aboutsummaryrefslogtreecommitdiffstats
path: root/lib/odbc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/odbc')
-rw-r--r--lib/odbc/c_src/odbcserver.c22
-rw-r--r--lib/odbc/c_src/odbcserver.h1
-rw-r--r--lib/odbc/doc/src/databases.xml4
-rw-r--r--lib/odbc/doc/src/odbc.xml2
-rw-r--r--lib/odbc/src/odbc.erl3
-rw-r--r--lib/odbc/src/odbc_internal.hrl1
-rw-r--r--lib/odbc/test/mysql.erl4
-rw-r--r--lib/odbc/test/odbc_data_type_SUITE.erl152
-rw-r--r--lib/odbc/test/oracle.erl4
-rw-r--r--lib/odbc/test/postgres.erl4
-rw-r--r--lib/odbc/test/sqlserver.erl4
11 files changed, 131 insertions, 70 deletions
diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c
index 3dd7da08b9..11e311d72d 100644
--- a/lib/odbc/c_src/odbcserver.c
+++ b/lib/odbc/c_src/odbcserver.c
@@ -90,7 +90,7 @@
Datatype - USER_INT | USER_SMALL_INT | {USER_DECIMAL, Precision, Scale} |
{USER_NMERIC, Precision, Scale} | {USER_CHAR, Max} | {USER_VARCHAR, Max} |
{USER_WVARCHAR, Max} | {USER_FLOAT, Precision} | USER_REAL | USER_DOUBLE |
- USER_TIMESTAMP
+ USER_TIMESTAMP | {USER_WLONGVARCHAR, Max}
Scale - integer
Precision - integer
Max - integer
@@ -1228,7 +1228,7 @@ static db_result_msg encode_column_name_list(SQLSMALLINT num_of_columns,
&nullable)))
DO_EXIT(EXIT_DESC);
- if(sql_type == SQL_LONGVARCHAR || sql_type == SQL_LONGVARBINARY)
+ if(sql_type == SQL_LONGVARCHAR || sql_type == SQL_LONGVARBINARY || sql_type == SQL_WLONGVARCHAR)
size = MAXCOLSIZE;
(columns(state)[i]).type.decimal_digits = dec_digits;
@@ -1537,6 +1537,11 @@ static void encode_data_type(SQLSMALLINT sql_type, SQLINTEGER size,
case SQL_LONGVARCHAR:
ei_x_encode_atom(&dynamic_buffer(state), "SQL_LONGVARCHAR");
break;
+ case SQL_WLONGVARCHAR:
+ ei_x_encode_tuple_header(&dynamic_buffer(state), 2);
+ ei_x_encode_atom(&dynamic_buffer(state), "sql_wlongvarchar");
+ ei_x_encode_long(&dynamic_buffer(state), size);
+ break;
case SQL_VARBINARY:
ei_x_encode_atom(&dynamic_buffer(state), "SQL_VARBINARY");
break;
@@ -2139,10 +2144,14 @@ static void init_param_column(param_array *params, byte *buffer, int *index,
break;
case USER_WCHAR:
case USER_WVARCHAR:
- if(user_type == USER_WCHAR) {
- params->type.sql = SQL_WCHAR;
- } else {
- params->type.sql = SQL_WVARCHAR;
+ case USER_WLONGVARCHAR:
+ switch (user_type) {
+ case USER_WCHAR:
+ params->type.sql = SQL_WCHAR; break;
+ case USER_WVARCHAR:
+ params->type.sql = SQL_WVARCHAR; break;
+ default:
+ params->type.sql = SQL_WLONGVARCHAR; break;
}
ei_decode_long(buffer, index, &length);
/* Max string length + string terminator */
@@ -2308,6 +2317,7 @@ static db_result_msg map_sql_2_c_column(db_column* column)
break;
case SQL_WCHAR:
case SQL_WVARCHAR:
+ case SQL_WLONGVARCHAR:
column -> type.len = (column -> type.col_size + 1)*sizeof(SQLWCHAR);
column -> type.c = SQL_C_WCHAR;
column -> type.strlen_or_indptr = SQL_NTS;
diff --git a/lib/odbc/c_src/odbcserver.h b/lib/odbc/c_src/odbcserver.h
index 3e2b22ab7d..314fbf32c6 100644
--- a/lib/odbc/c_src/odbcserver.h
+++ b/lib/odbc/c_src/odbcserver.h
@@ -115,6 +115,7 @@
#define USER_WCHAR 12
#define USER_WVARCHAR 13
#define USER_TIMESTAMP 14
+#define USER_WLONGVARCHAR 15
/*------------------------ TYPDEFS ----------------------------------*/
diff --git a/lib/odbc/doc/src/databases.xml b/lib/odbc/doc/src/databases.xml
index a6ba0e5245..09f5a5af5b 100644
--- a/lib/odbc/doc/src/databases.xml
+++ b/lib/odbc/doc/src/databases.xml
@@ -205,6 +205,10 @@ when p >= 16 </cell>
<cell align="left" valign="middle">String | Binary (configurable)</cell>
</row>
<row>
+ <cell align="left" valign="middle">SQL_WLONGVARCHAR(size) </cell>
+ <cell align="left" valign="middle">Unicode binary encoded as UTF16 little endian.</cell>
+ </row>
+ <row>
<cell align="left" valign="middle">SQL_BINARY</cell>
<cell align="left" valign="middle">String | Binary (configurable)</cell>
</row>
diff --git a/lib/odbc/doc/src/odbc.xml b/lib/odbc/doc/src/odbc.xml
index 70d8cfbe22..11ca97f743 100644
--- a/lib/odbc/doc/src/odbc.xml
+++ b/lib/odbc/doc/src/odbc.xml
@@ -102,7 +102,7 @@
{sql_decimal, precision(), scale()} |
{sql_numeric, precision(), scale()} |
{sql_char, size()} | {sql_wchar, size()} | {sql_varchar, size()} | {sql_wvarchar, size()}| {sql_float, precision()} |
- {sql_float, precision()} | sql_real | sql_double | sql_bit | atom()
+ {sql_wlongvarchar, size()} | {sql_float, precision()} | sql_real | sql_double | sql_bit | atom()
</code>
<code type="none">
precision() = integer() </code>
diff --git a/lib/odbc/src/odbc.erl b/lib/odbc/src/odbc.erl
index 2634450d4a..68497292db 100644
--- a/lib/odbc/src/odbc.erl
+++ b/lib/odbc/src/odbc.erl
@@ -925,6 +925,9 @@ fix_params({{sql_wchar, Max}, InOut, Values}) ->
fix_params({{sql_wvarchar, Max}, InOut, Values}) ->
NewValues = string_terminate(Values),
{?USER_WVARCHAR, Max, fix_inout(InOut), NewValues};
+fix_params({{sql_wlongvarchar, Max}, InOut, Values}) ->
+ NewValues = string_terminate(Values),
+ {?USER_WLONGVARCHAR, Max, fix_inout(InOut), NewValues};
fix_params({{sql_float, Precision}, InOut, Values}) ->
{?USER_FLOAT, Precision, fix_inout(InOut), Values};
fix_params({sql_real, InOut, Values}) ->
diff --git a/lib/odbc/src/odbc_internal.hrl b/lib/odbc/src/odbc_internal.hrl
index aa60120f9a..c0e7d9657b 100644
--- a/lib/odbc/src/odbc_internal.hrl
+++ b/lib/odbc/src/odbc_internal.hrl
@@ -72,6 +72,7 @@
-define(USER_WCHAR, 12).
-define(USER_WVARCHAR, 13).
-define(USER_TIMESTAMP, 14).
+-define(USER_WLONGVARCHAR, 15).
%% INPUT & OUTPUT TYPE
-define(IN, 0).
diff --git a/lib/odbc/test/mysql.erl b/lib/odbc/test/mysql.erl
index 76ffd3ecc9..49068c4356 100644
--- a/lib/odbc/test/mysql.erl
+++ b/lib/odbc/test/mysql.erl
@@ -98,10 +98,6 @@ create_text_table() ->
" (FIELD text)".
%-------------------------------------------------------------------------
-create_unicode_table() ->
- " (FIELD text)".
-
-%-------------------------------------------------------------------------
create_timestamp_table() ->
" (FIELD TIMESTAMP)".
diff --git a/lib/odbc/test/odbc_data_type_SUITE.erl b/lib/odbc/test/odbc_data_type_SUITE.erl
index 84c99e183b..099ae0aa7d 100644
--- a/lib/odbc/test/odbc_data_type_SUITE.erl
+++ b/lib/odbc/test/odbc_data_type_SUITE.erl
@@ -45,7 +45,7 @@ all() ->
case odbc_test_lib:odbc_check() of
ok ->
[{group, char},{group, fixed_char}, {group, binary_char},
- {group, fixed_binary_char},
+ {group, fixed_binary_char}, {group, unicode},
{group, int}, {group, floats},
{group, dec_and_num}, timestamp];
Other -> {skip, Other}
@@ -55,18 +55,18 @@ groups() ->
[{char, [],
[varchar_lower_limit,
varchar_upper_limit, varchar_no_padding,
- text_lower_limit, text_upper_limit, unicode]},
+ text_lower_limit, text_upper_limit]},
{fixed_char, [],
[char_fixed_lower_limit, char_fixed_upper_limit,
char_fixed_padding]},
{binary_char, [],
[binary_varchar_lower_limit,
binary_varchar_upper_limit, binary_varchar_no_padding,
- binary_text_lower_limit, binary_text_upper_limit,
- unicode]},
+ binary_text_lower_limit, binary_text_upper_limit]},
{fixed_binary_char, [], [binary_char_fixed_lower_limit,
binary_char_fixed_upper_limit,
binary_char_fixed_padding]},
+ {unicode, [], [utf8, nchar, nvarchar]},
{int, [],
[tiny_int_lower_limit, tiny_int_upper_limit,
small_int_lower_limit, small_int_upper_limit,
@@ -88,14 +88,24 @@ init_per_group(GroupName, Config) when GroupName == fixed_char;
Config
end;
+init_per_group(unicode, Config) ->
+ %% Uses parameterized queries
+ case {os:type(), erlang:system_info(wordsize)} of
+ {{unix, _}, 4} ->
+ Config;
+ {{unix, _}, _} ->
+ {skip, "Not supported by driver"};
+ _ ->
+ Config
+ end;
+
+
init_per_group(_GroupName, Config) ->
Config.
end_per_group(_GroupName, Config) ->
Config.
-
-
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
%% Config - [tuple()]
@@ -164,6 +174,16 @@ init_per_testcase(param_insert_tiny_int = Case, Config) ->
false ->
{skip, "Not supported by driver"}
end;
+
+init_per_testcase(Case, Config) when Case == nchar;
+ Case == nvarchar ->
+ case ?RDBMS of
+ sqlserver ->
+ common_init_per_testcase(Case, Config);
+ _ ->
+ {skip, "Not supported by driver"}
+ end;
+
init_per_testcase(Case, Config) ->
common_init_per_testcase(Case, Config).
@@ -173,7 +193,9 @@ common_init_per_testcase(Case, Config) ->
"binary" ++ _ ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
[{binary_strings, on}] ++ PlatformOptions);
- "unicode" ->
+ LCase when LCase == "utf8";
+ LCase == "nchar";
+ LCase == "nvarchar" ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
[{binary_strings, on}] ++ PlatformOptions);
_ ->
@@ -1435,17 +1457,16 @@ num_bignum(Config) when is_list(Config) ->
["FIELD"] = odbc_test_lib:to_upper(Fields1).
%%------------------------------------------------------------------------
-unicode(doc) ->
+utf8(doc) ->
["Test unicode support"];
-unicode(suit) ->
+utf8(suit) ->
[];
-unicode(Config) when is_list(Config) ->
+utf8(Config) when is_list(Config) ->
Ref = ?config(connection_ref, Config),
Table = ?config(tableName, Config),
- {updated, _} = % Value == 0 || -1 driver dependent!
- odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
- ?RDBMS:create_unicode_table()),
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ "(FIELD text)"),
+
Latin1Data = ["���������",
"testasdf",
"Row 3",
@@ -1458,41 +1479,7 @@ unicode(Config) when is_list(Config) ->
"Row 10",
"Row 11",
"Row 12"],
-
- case ?RDBMS of
- sqlserver ->
- w_char_support_win(Ref, Table, Latin1Data);
- postgres ->
- direct_utf8(Ref, Table, Latin1Data);
- mysql ->
- direct_utf8(Ref, Table, Latin1Data);
- oracle ->
- {skip, "not currently supported"}
- end.
-
-w_char_support_win(Ref, Table, Latin1Data) ->
- UnicodeIn = lists:map(fun(S) ->
- unicode:characters_to_binary(S,latin1,{utf16,little})
- end,
- Latin1Data),
-
- test_server:format("UnicodeIn (utf 16): ~p ~n",[UnicodeIn]),
-
- {updated, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ "(FIELD) values(?)",
- [{{sql_wvarchar,50},UnicodeIn}]),
-
- {selected,_,UnicodeOut} = odbc:sql_query(Ref,"SELECT * FROM " ++ Table),
-
- test_server:format("UnicodeOut: ~p~n", [UnicodeOut]),
- Result = lists:map(fun({Unicode}) ->
- unicode:characters_to_list(Unicode,{utf16,little})
- end,
- UnicodeOut),
- Latin1Data = Result.
-
-
-direct_utf8(Ref, Table, Latin1Data) ->
UnicodeIn = lists:map(fun(String) ->
unicode:characters_to_binary(String,latin1,utf8)
end,
@@ -1513,6 +1500,37 @@ direct_utf8(Ref, Table, Latin1Data) ->
test_server:format("Result: ~p ~n", [Result]),
Latin1Data = Result.
+%%------------------------------------------------------------------------
+
+nchar(doc) ->
+ ["Test unicode nchar support in sqlserver"];
+nchar(suit) ->
+ [];
+nchar(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD nchar(50))"),
+
+ w_char_support(Ref, Table, sql_wvarchar, 50).
+
+%%------------------------------------------------------------------------
+
+nvarchar(doc) ->
+ ["Test 'unicode' nvarchar support"];
+nvarchar(suit) ->
+ [];
+nvarchar(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD nvarchar(50))"),
+
+ w_char_support(Ref, Table, sql_wlongvarchar, 50).
%%------------------------------------------------------------------------
timestamp(doc) ->
@@ -1541,3 +1559,43 @@ timestamp(Config) when is_list(Config) ->
TimeStamps = lists:map(fun(Value) -> {Value} end, Data),
{selected,_, TimeStamps} = odbc:sql_query(Ref, "SELECT * FROM " ++ Table).
+%%------------------------------------------------------------------------
+
+w_char_support(Ref, Table, CharType, Size) ->
+ Latin1Data = ["���������",
+ "testasdf",
+ "Row 3",
+ "Row 4",
+ "Row 5",
+ "Row 6",
+ "Row 7",
+ "Row 8",
+ "Row 9",
+ "Row 10",
+ "Row 11",
+ "Row 12"],
+
+ UnicodeIn = lists:map(fun(S) ->
+ unicode:characters_to_binary(S,latin1,{utf16,little})
+ end,
+ Latin1Data),
+
+ test_server:format("UnicodeIn (utf 16): ~p ~n",[UnicodeIn]),
+
+ {updated, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ "(FIELD) values(?)",
+ [{{CharType, Size},UnicodeIn}]),
+
+ {selected,_,UnicodeOut} = odbc:sql_query(Ref,"SELECT * FROM " ++ Table),
+
+ test_server:format("UnicodeOut: ~p~n", [UnicodeOut]),
+
+ PadResult = lists:map(fun({Unicode}) ->
+ unicode:characters_to_list(Unicode,{utf16,little})
+ end,
+ UnicodeOut),
+
+ test_server:format("Result: ~p~n", [PadResult]),
+
+ Result = lists:map(fun(Str) -> string:strip(Str) end, PadResult),
+
+ Latin1Data = Result.
diff --git a/lib/odbc/test/oracle.erl b/lib/odbc/test/oracle.erl
index 786280701d..d74863d8c1 100644
--- a/lib/odbc/test/oracle.erl
+++ b/lib/odbc/test/oracle.erl
@@ -108,10 +108,6 @@ create_text_table() ->
" (FIELD long)". %Oracle long is variable length char data
%-------------------------------------------------------------------------
-create_unicode_table() ->
- " (FIELD nvarchar(50))".
-
-%-------------------------------------------------------------------------
create_timestamp_table() ->
" (FIELD DATETIME)".
diff --git a/lib/odbc/test/postgres.erl b/lib/odbc/test/postgres.erl
index 9c7eed271f..26a2913d46 100644
--- a/lib/odbc/test/postgres.erl
+++ b/lib/odbc/test/postgres.erl
@@ -135,10 +135,6 @@ create_text_table() ->
" (FIELD text)".
%-------------------------------------------------------------------------
-create_unicode_table() ->
- " (FIELD text)".
-
-%-------------------------------------------------------------------------
create_timestamp_table() ->
" (FIELD TIMESTAMP)".
diff --git a/lib/odbc/test/sqlserver.erl b/lib/odbc/test/sqlserver.erl
index 13930cd5ae..59252d4276 100644
--- a/lib/odbc/test/sqlserver.erl
+++ b/lib/odbc/test/sqlserver.erl
@@ -123,10 +123,6 @@ create_text_table() ->
" (FIELD text)".
%-------------------------------------------------------------------------
-create_unicode_table() ->
- " (FIELD nvarchar(50))".
-
-%-------------------------------------------------------------------------
create_timestamp_table() ->
" (FIELD DATETIME)".