diff --git a/src/dblib.cppo.ml b/src/dblib.cppo.ml index eb9b98a..d96a280 100644 --- a/src/dblib.cppo.ml +++ b/src/dblib.cppo.ml @@ -151,6 +151,7 @@ type col_type = | SYBMONEY4 (* 17 *) | SYBMONEY (* 18 *) | SYBMONEYN (* 19 *) | SYBREAL (* 20 *) | SYBBINARY (* 21 *) | SYBVARBINARY (* 22 *) + | SYBUNIQUE (* 23 *) let string_of_col_type = function | SYBCHAR -> "CHAR" @@ -168,6 +169,7 @@ let string_of_col_type = function | SYBBINARY -> "BINARY" | SYBVARBINARY -> "VARBINARY" | SYBNUMERIC -> "NUMERIC" | SYBDECIMAL -> "DECIMAL" + | SYBUNIQUE -> "UNIQUEIDENTIFIER" ;; external coltype : dbprocess -> int -> col_type = "ocaml_freetds_dbcoltype" diff --git a/src/dblib.mli b/src/dblib.mli index 7287e9a..8786a1a 100644 --- a/src/dblib.mli +++ b/src/dblib.mli @@ -145,6 +145,7 @@ type col_type = | SYBMONEY4 | SYBMONEY | SYBMONEYN | SYBREAL | SYBBINARY | SYBVARBINARY + | SYBUNIQUE val string_of_col_type : col_type -> string (** Returns a string description of the column type. *) diff --git a/src/dblib_stubs.c b/src/dblib_stubs.c index 1eb2a4b..52d6160 100644 --- a/src/dblib_stubs.c +++ b/src/dblib_stubs.c @@ -552,6 +552,7 @@ CAMLexport value ocaml_freetds_dbcoltype(value vdbproc, value vc) case SYBREAL: CAMLreturn(Val_int(20)); case SYBBINARY: CAMLreturn(Val_int(21)); case SYBVARBINARY: CAMLreturn(Val_int(22)); + case 36 /* SYBUNIQUE */: CAMLreturn(Val_int(23)); } if (ty == -1) /* The handler catches this exception. Raise a compatible one. */ @@ -713,6 +714,13 @@ CAMLexport value ocaml_freetds_get_data(value vdbproc, value vcol, COPY_STRING(vres, data, len); CONSTRUCTOR(0, vres); break; + // SYBUNIQUE is not consistently exported in FreeTDS headers due to "an oversight" + case 36 /* SYBUNIQUE */: + // Unique identifier should be 16 bytes + // When converting to a string, the result is 36 characters (32 hex characters + 4 dashes) + CONVERT_STRING(36); + CONSTRUCTOR(0, vres); + break; case SYBIMAGE: case SYBBINARY: case SYBVARBINARY: diff --git a/test/test_dblib.ml b/test/test_dblib.ml index 2842855..cf80980 100644 --- a/test/test_dblib.ml +++ b/test/test_dblib.ml @@ -106,13 +106,28 @@ let test_data params _ = CAST('a' AS CHAR(10)) AS c, \ CAST('abc' AS TEXT) AS txt, \ CAST(1 AS INT) AS i, \ - CAST(3.4 AS DOUBLE PRECISION) AS d"; + CAST(3.4 AS DOUBLE PRECISION) AS d, \ + CAST('b6702d1b-8082-4475-90c9-07e51aef9e7c' AS UNIQUEIDENTIFIER) AS u"; Dblib.results conn |> assert_bool "query has results"; + Dblib.numcols conn + |> assert_equal ~printer:string_of_int 6; + Dblib.coltype conn 1 + |> assert_equal ~printer:Dblib.string_of_col_type SYBCHAR; + Dblib.coltype conn 2 + |> assert_equal ~printer:Dblib.string_of_col_type SYBCHAR; + Dblib.coltype conn 3 + |> assert_equal ~printer:Dblib.string_of_col_type SYBTEXT; + Dblib.coltype conn 4 + |> assert_equal ~printer:Dblib.string_of_col_type SYBINT4; + Dblib.coltype conn 5 + |> assert_equal ~printer:Dblib.string_of_col_type SYBFLT8; + Dblib.coltype conn 6 + |> assert_equal ~printer:Dblib.string_of_col_type SYBUNIQUE; Dblib.nextrow conn |> assert_equal ~printer:string_of_row Dblib.([STRING "a"; STRING "a "; STRING "abc"; - INT 1; FLOAT 3.4]) + INT 1; FLOAT 3.4 ; STRING "B6702D1B-8082-4475-90C9-07E51AEF9E7C"]) ) let test_insert params _ =