diff --git a/build.zig b/build.zig index dd9c875..450f0c4 100644 --- a/build.zig +++ b/build.zig @@ -1,6 +1,6 @@ const std = @import("std"); -const builtin = std.builtin; -const CompileStep = std.build.CompileStep; +const builtin = @import("builtin"); +const CompileStep = std.Build.CompileStep; const test_files = .{ "src/ParameterBucket.zig", @@ -9,7 +9,7 @@ const test_files = .{ const Example = struct { name: []const u8, - source_file: std.Build.FileSource, + source_file: std.Build.LazyPath, description: []const u8, }; @@ -36,7 +36,7 @@ const examples = [_]Example{ }, }; -pub fn build(b: *std.build.Builder) !void { +pub fn build(b: *std.Build) !void { const optimize = b.standardOptimizeOption(.{}); const target = b.standardTargetOptions(.{}); @@ -45,50 +45,88 @@ pub fn build(b: *std.build.Builder) !void { .optimize = optimize, }); - var zdb_module = b.createModule(.{ - .source_file = .{ .path = "src/zdb.zig" }, - .dependencies = &.{ - .{ .name = "odbc", .module = zig_odbc_dep.module("zig-odbc") }, + const zdb_module = b.createModule(.{ + .root_source_file = .{ .path = "src/zdb.zig" }, + .imports = &.{ + .{ .name = "zig-odbc", .module = zig_odbc_dep.module("zig-odbc") }, }, }); + _ = zdb_module; + // _ = zdb_module; + // const zdb_module = b.addModule("zdb", .{ + // .root_source_file = .{ .path = "src/zdb.zig" }, + // .imports = &.{ + // .{ .name = "zig-odbc", .module = zig_odbc_dep.module("zig-odbc") }, + // }, + // }); + // _ = zdb_module; - var lib = b.addStaticLibrary(.{ + const lib = b.addSharedLibrary(.{ .name = "zdb", .optimize = optimize, .target = target, }); + // try b.modules.put(b.dupe("libzdb"), zdb_module); - const odbc_lib = zig_odbc_dep.artifact("odbc"); - lib.linkLibrary(odbc_lib); + const zig_odbc_lib = zig_odbc_dep.artifact("zigodbc"); + // lib.root_module.addImport("zig-odbc", zig_odbc_dep.module("zig-odbc")); + // lib.root_module.addImport("zdb", zdb_module); + lib.linkLibrary(zig_odbc_lib); - inline for (examples) |example| { - const example_exe = b.addExecutable(.{ - .name = example.name, - .root_source_file = example.source_file, + b.installArtifact(lib); + + // inline for (examples) |example| { + // const example_exe = b.addExecutable(.{ + // .name = example.name, + // .root_source_file = example.source_file, + // .optimize = optimize, + // .target = target, + // }); + // + // // example_exe.addModule("zdb", zdb_module); + // // example_exe.linkLibrary(odbc_lib); + // example_exe.linkLibrary(lib); + // + // const install_step = b.addInstallArtifact(example_exe, .{}); + // + // const run_cmd = b.addRunArtifact(example_exe); + // run_cmd.step.dependOn(&install_step.step); + // const run_step = b.step(example.name, example.description); + // run_step.dependOn(&run_cmd.step); + // } + + const test_step = b.step("test", "Run library tests"); + + var tests: [test_files.len]*std.Build.Step.Run = undefined; + inline for (test_files, 0..) |filename, index| { + const current_tests = b.addTest(.{ + .root_source_file = .{ .path = filename }, .optimize = optimize, .target = target, }); - example_exe.addModule("zdb", zdb_module); - example_exe.linkLibrary(odbc_lib); + current_tests.root_module.addImport("zig-odbc", zig_odbc_dep.module("zig-odbc")); - const install_step = b.addInstallArtifact(example_exe, .{}); + setupOdbcDependencies(current_tests); - const run_cmd = b.addRunArtifact(example_exe); - run_cmd.step.dependOn(&install_step.step); - const run_step = b.step(example.name, example.description); - run_step.dependOn(&run_cmd.step); + const run_current_unit_tests = b.addRunArtifact(current_tests); + tests[index] = run_current_unit_tests; + // tests.linkLibrary(odbc_lib); + // tests.linkLibrary(lib); + // test_step.dependOn(&tests.step); + } + for (tests) |t| { + test_step.dependOn(&t.step); } +} - const test_step = b.step("test", "Run library tests"); - inline for (test_files) |filename| { - const tests = b.addTest(.{ - .root_source_file = .{ .path = filename }, - .optimize = optimize, - .target = target, - }); +pub fn setupOdbcDependencies(step: *std.Build.Step.Compile) void { + step.linkLibC(); - tests.linkLibrary(odbc_lib); - test_step.dependOn(&tests.step); + const odbc_library_name = if (builtin.os.tag == .windows) "odbc32" else "odbc"; + if (builtin.os.tag == .macos) { + step.addIncludePath(.{ .path = "/usr/local/include" }); + step.addIncludePath(.{ .path = "/usr/local/lib" }); } + step.linkSystemLibrary(odbc_library_name); } diff --git a/build.zig.zon b/build.zig.zon index 9d6b628..53b8d56 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,11 +1,23 @@ .{ .name = "zdb", - .version = "0.2.0", + .version = "0.3.0", + + // This is currently advisory only; Zig does not yet do anything + // with this value. + .minimum_zig_version = "0.12.0", .dependencies = .{ .zig_odbc = .{ - .url = "https://github.com/mjoerussell/zig-odbc/archive/main.tar.gz", - .hash = "12201a961f7b538543444f6ca418b0ea5482c18119b4e39cf6a8abfd90471e0497b3", + .url = "https://github.com/rupurt/zig-odbc/archive/zig-0.12.0-support.tar.gz", + .hash = "122098955e514a8ac3b087ef43df206ed7a0d3c9481f6d5f918f8c8543f76b834aa4", }, }, + + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + "LICENSE", + "README.md", + }, } diff --git a/examples/01_basic_connect.zig b/examples/01_basic_connect.zig index 46aaa74..13006a4 100644 --- a/examples/01_basic_connect.zig +++ b/examples/01_basic_connect.zig @@ -8,7 +8,7 @@ pub fn main() anyerror!void { // The first step to using zdb is creating your data source. In this example we'll use the default postgres // settings and connect without using a DSN. - var connection_info = Connection.ConnectionConfig{ + const connection_info = Connection.ConnectionConfig{ .driver = "PostgreSQL Unicode(x64)", .database = "postgres", .server = "localhost", @@ -31,7 +31,7 @@ pub fn main() anyerror!void { // We'll run a simple operation on this DB to start - simply querying all the database names assocaiated with this // connection. Since we connected to a specific DB above, this should only return "postgres" - var catalogs = try cursor.catalogs(allocator); + const catalogs = try cursor.catalogs(allocator); defer allocator.free(catalogs); std.debug.print("Got {} catalogs\n", .{catalogs.len}); diff --git a/examples/02_connect_and_create_db.zig b/examples/02_connect_and_create_db.zig index 7c4335b..92a15c7 100644 --- a/examples/02_connect_and_create_db.zig +++ b/examples/02_connect_and_create_db.zig @@ -8,7 +8,7 @@ pub fn main() anyerror!void { // In this example we'll create a new database and reconnect to it. // The beginning is the same as basic_connect - var basic_connect_config = Connection.ConnectionConfig{ + const basic_connect_config = Connection.ConnectionConfig{ .driver = "PostgreSQL Unicode(x64)", .database = "postgres", .server = "localhost", diff --git a/examples/04_row_binding.zig b/examples/04_row_binding.zig index 8237391..e0bd928 100644 --- a/examples/04_row_binding.zig +++ b/examples/04_row_binding.zig @@ -9,7 +9,7 @@ pub fn main() anyerror!void { // This example is the same as create_and_query_table, except we're going to see how to use RowIterator to fetch results instead of // ItemIterator. - var basic_connect_config = Connection.ConnectionConfig{ + const basic_connect_config = Connection.ConnectionConfig{ .driver = "PostgreSQL Unicode(x64)", .database = "postgres", .server = "localhost", @@ -111,7 +111,7 @@ pub fn main() anyerror!void { // custom format strings based on the SQLType of the column, which can be checked on the Row struct. There are default // format strings defined for all SQLTypes already, so in most cases you don't have to specify anything and the data should // print in a predictable way - var stdout_writer = std.io.getStdOut().writer(); + const stdout_writer = std.io.getStdOut().writer(); try row.printColumn("age", .{}, stdout_writer); std.debug.print("\n", .{}); diff --git a/src/Connection.zig b/src/Connection.zig index 8355deb..f6a31bf 100644 --- a/src/Connection.zig +++ b/src/Connection.zig @@ -1,7 +1,7 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const odbc = @import("odbc"); +const odbc = @import("zig-odbc"); const Cursor = @import("Cursor.zig"); @@ -68,7 +68,7 @@ pub fn connect(conn: *Connection, server_name: []const u8, username: []const u8, /// Connect to a database using a ConnectionConfig. The config will be converted to a connection string, and then /// it will attempt to connect using connectExtended. pub fn connectWithConfig(conn: *Connection, allocator: Allocator, connection_config: ConnectionConfig) !void { - var connection_string = try connection_config.getConnectionString(allocator); + const connection_string = try connection_config.getConnectionString(allocator); defer allocator.free(connection_string); try conn.connection.connectExtended(connection_string, .NoPrompt); @@ -116,5 +116,5 @@ test "ConnectionInfo" { const connection_string = try connection_info.getConnectionString(allocator); defer allocator.free(connection_string); - try std.testing.expectEqualStrings("DRIVER=A Driver;DSN=Some DSN Value;UID=User;PWD=Password", connection_string); + try std.testing.expectEqualStrings("DRIVER={A Driver};DSN=Some DSN Value;UID=User;PWD=Password;", connection_string); } diff --git a/src/Cursor.zig b/src/Cursor.zig index 28bab05..8d62e13 100644 --- a/src/Cursor.zig +++ b/src/Cursor.zig @@ -1,7 +1,7 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const odbc = @import("odbc"); +const odbc = @import("zig-odbc"); const Statement = odbc.Statement; const Connection = odbc.Connection; @@ -205,8 +205,8 @@ pub fn columns(cursor: *Cursor, allocator: Allocator, catalog_name: ?[]const u8, errdefer column_result.deinit(); while (true) { - var result = column_iter.next() catch continue; - var column = result orelse break; + const result = column_iter.next() catch continue; + const column = result orelse break; try column_result.append(column); } @@ -224,8 +224,8 @@ pub fn tables(cursor: *Cursor, allocator: Allocator, catalog_name: ?[]const u8, errdefer table_result.deinit(); while (true) { - var result = table_iter.next() catch continue; - var table = result orelse break; + const result = table_iter.next() catch continue; + const table = result orelse break; try table_result.append(table); } @@ -243,8 +243,8 @@ pub fn tablePrivileges(cursor: *Cursor, allocator: Allocator, catalog_name: ?[]c errdefer priv_result.deinit(); while (true) { - var result = priv_iter.next() catch continue; - var privilege = result orelse break; + const result = priv_iter.next() catch continue; + const privilege = result orelse break; try priv_result.append(privilege); } @@ -261,7 +261,7 @@ pub fn catalogs(cursor: *Cursor, allocator: Allocator) ![][]const u8 { defer iter.deinit(allocator); while (true) { - var result = iter.next() catch continue; + const result = iter.next() catch continue; var row = result orelse break; const catalog_name = row.get([]const u8, "TABLE_CAT") catch continue; diff --git a/src/ParameterBucket.zig b/src/ParameterBucket.zig index 82d18eb..ac10bc3 100644 --- a/src/ParameterBucket.zig +++ b/src/ParameterBucket.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const odbc = @import("odbc"); +const odbc = @import("zig-odbc"); const EraseComptime = @import("util.zig").EraseComptime; @@ -45,7 +45,7 @@ data: []u8, indicators: []c_longlong, pub fn init(allocator: Allocator, num_params: usize) !ParameterBucket { - var indicators = try allocator.alloc(c_longlong, num_params); + const indicators = try allocator.alloc(c_longlong, num_params); errdefer allocator.free(indicators); for (indicators) |*i| i.* = 0; @@ -81,10 +81,11 @@ pub fn set(bucket: *ParameterBucket, allocator: Allocator, param_data: anytype, const data_indicator = @as(usize, @intCast(bucket.indicators[param_index])); - const data_buffer: []const u8 = if (comptime std.meta.trait.isZigString(ParamType)) - param_data - else - &std.mem.toBytes(@as(ParamType, param_data)); + // const data_buffer: []const u8 = if (comptime std.meta.trait.isZigString(ParamType)) + // param_data + // else + // &std.mem.toBytes(@as(ParamType, param_data)); + const data_buffer: []const u8 = &std.mem.toBytes(@as(ParamType, param_data)); bucket.indicators[param_index] = @as(c_longlong, @intCast(data_buffer.len)); @@ -105,7 +106,7 @@ pub fn set(bucket: *ParameterBucket, allocator: Allocator, param_data: anytype, if (data_buffer.len < data_indicator) { // If the new len is smaller than the old one, then just move the remaining params // forward - std.mem.copy(u8, copy_dest, copy_src); + std.mem.copyForwards(u8, copy_dest, copy_src); } else { // If the new len is bigger than the old one, then resize the buffer and then move the // remaining params backwards @@ -116,7 +117,7 @@ pub fn set(bucket: *ParameterBucket, allocator: Allocator, param_data: anytype, } } - std.mem.copy(u8, bucket.data[data_index..], data_buffer); + std.mem.copyForwards(u8, bucket.data[data_index..], data_buffer); return Param{ .data = @as(*anyopaque, @ptrCast(&bucket.data[data_index])), @@ -150,7 +151,7 @@ test "add parameter to ParameterBucket" { var bucket = try ParameterBucket.init(allocator, 5); defer bucket.deinit(allocator); - var param_value: u32 = 10; + const param_value: u32 = 10; const param = try bucket.set(allocator, param_value, 0); @@ -164,7 +165,7 @@ test "add string parameter to ParameterBucket" { var bucket = try ParameterBucket.init(allocator, 5); defer bucket.deinit(allocator); - var param_value = "some string value"; + const param_value = "some string value"; const param = try bucket.set(allocator, param_value, 0); diff --git a/src/ResultSet.zig b/src/ResultSet.zig index 990c775..a35f26b 100644 --- a/src/ResultSet.zig +++ b/src/ResultSet.zig @@ -1,7 +1,7 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const odbc = @import("odbc"); +const odbc = @import("zig-odbc"); const RowStatus = odbc.Types.StatementAttributeValue.RowStatus; const Statement = odbc.Statement; const CType = odbc.Types.CType; @@ -107,7 +107,7 @@ fn toTarget(comptime Target: type, allocator: Allocator, row: FetchResult(Target else @as(usize, @intCast(len_or_indicator)); - var data_slice = try allocator.alloc(info.child, slice_length); + const data_slice = try allocator.alloc(info.child, slice_length); std.mem.copy(info.child, data_slice, row_data[0..slice_length]); break :blk data_slice; }, @@ -467,13 +467,13 @@ const RowIterator = struct { pub fn init(allocator: Allocator, statement: odbc.Statement, row_count: usize) !RowIterator { const num_columns = try statement.numResultColumns(); - var columns = try allocator.alloc(Column, num_columns); + const columns = try allocator.alloc(Column, num_columns); errdefer { for (columns) |*c| c.deinit(allocator); allocator.free(columns); } - var row_status = try allocator.alloc(RowStatus, row_count); + const row_status = try allocator.alloc(RowStatus, row_count); errdefer allocator.free(row_status); try statement.setAttribute(.{ .RowBindType = odbc.sys.SQL_BIND_BY_COLUMN }); diff --git a/src/catalog.zig b/src/catalog.zig index 41a92ea..c9aedc6 100644 --- a/src/catalog.zig +++ b/src/catalog.zig @@ -1,7 +1,7 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const odbc = @import("odbc"); +const odbc = @import("zig-odbc"); /// Used for fetching column metadata from a database. Supports formatted printing by default. pub const Column = struct { diff --git a/src/zdb.zig b/src/zdb.zig index f32cf1f..3c4f3c7 100644 --- a/src/zdb.zig +++ b/src/zdb.zig @@ -4,4 +4,4 @@ pub const ResultSet = @import("ResultSet.zig"); pub const Cursor = @import("Cursor.zig"); pub const util = @import("util.zig"); -pub const odbc = @import("odbc"); +pub const odbc = @import("zig-odbc");