4
* Copyright Ericsson AB 1999-2009. All Rights Reserved.
4
* Copyright Ericsson AB 1999-2011. All Rights Reserved.
6
6
* The contents of this file are subject to the Erlang Public License,
7
7
* Version 1.1, (the "License"); you may not use this file except in
8
8
* compliance with the License. You should have received a copy of the
9
9
* Erlang Public License along with this software. If not, it can be
10
10
* retrieved online at http://www.erlang.org/.
12
12
* Software distributed under the License is distributed on an "AS IS"
13
13
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
* the License for the specific language governing rights and limitations
15
15
* under the License.
434
437
int erl_auto_commit_mode, erl_trace_driver,
435
use_srollable_cursors, tuple_row_state;
438
use_srollable_cursors, tuple_row_state, binary_strings;
437
440
erl_auto_commit_mode = args[0];
438
441
erl_trace_driver = args[1];
439
442
use_srollable_cursors = args[2];
440
443
tuple_row_state = args[3];
441
connStrIn = args + 4 * sizeof(byte);
444
binary_strings = args[4];
445
connStrIn = args + 5 * sizeof(byte);
443
447
if(tuple_row_state == ON) {
444
tuple_row(state) = TRUE;
446
tuple_row(state) = FALSE;
448
tuple_row(state) = TRUE;
450
tuple_row(state) = FALSE;
453
if(binary_strings == ON) {
454
binary_strings(state) = TRUE;
456
binary_strings(state) = FALSE;
449
459
if(use_srollable_cursors == ON) {
450
use_srollable_cursors(state) = TRUE;
460
use_srollable_cursors(state) = TRUE;
452
use_srollable_cursors(state) = FALSE;
462
use_srollable_cursors(state) = FALSE;
455
465
init_driver(erl_auto_commit_mode, erl_trace_driver, state);
457
467
connlen = (SQLSMALLINT)strlen((const char*)connStrIn);
784
795
num_param_values, state);
786
797
if(params != NULL) {
787
if(!sql_success(SQLExecDirect(statement_handle(state),
789
diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state));
790
msg = encode_error_message(diagnos.error_msg);
799
result = SQLExecDirect(statement_handle(state), sql, SQL_NTS);
800
if (!sql_success(result) || result == SQL_NO_DATA) {
801
diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state));
803
/* SQL_NO_DATA and SQLSTATE 00000 indicate success for
804
updates/deletes that affect no rows */
805
if(!sql_success(result) &&
806
!(result == SQL_NO_DATA && !strcmp((char *)diagnos.sqlState, INFO))) {
807
msg = encode_error_message(diagnos.error_msg);
792
809
for (i = 0; i < param_status.params_processed; i++) {
793
810
switch (param_status.param_status_array[i]) {
1094
1112
void* values = retrive_param_values(&column);
1095
1113
switch(column.type.c) {
1114
case SQL_C_TYPE_TIMESTAMP:
1115
ts = (TIMESTAMP_STRUCT*) values;
1116
ei_x_encode_tuple_header(&dynamic_buffer(state), 2);
1117
ei_x_encode_tuple_header(&dynamic_buffer(state), 3);
1118
ei_x_encode_long(&dynamic_buffer(state), (long)(ts->year));
1119
ei_x_encode_long(&dynamic_buffer(state), (long)(ts->month));
1120
ei_x_encode_long(&dynamic_buffer(state), (long)(ts->day));
1121
ei_x_encode_tuple_header(&dynamic_buffer(state), 3);
1122
ei_x_encode_long(&dynamic_buffer(state), (long)(ts->hour));
1123
ei_x_encode_long(&dynamic_buffer(state), (long)(ts->minute));
1124
ei_x_encode_long(&dynamic_buffer(state), (long)(ts->second));
1096
1126
case SQL_C_CHAR:
1097
ei_x_encode_string(&dynamic_buffer(state), ((char*)values)+j*column.type.len);
1127
if binary_strings(state) {
1128
ei_x_encode_binary(&dynamic_buffer(state),
1129
((char*)values)+j*column.type.len,
1130
(column.type.strlen_or_indptr_array[j]));
1133
ei_x_encode_string(&dynamic_buffer(state),
1134
((char*)values)+j*column.type.len);
1138
ei_x_encode_binary(&dynamic_buffer(state),
1139
((char*)values)+j*column.type.len,
1140
(column.type.strlen_or_indptr_array[j]));
1099
1142
case SQL_C_SLONG:
1100
1143
ei_x_encode_long(&dynamic_buffer(state), ((long*)values)[j]);
1351
1394
static void encode_column_dyn(db_column column, int column_nr,
1352
1395
db_state *state)
1397
TIMESTAMP_STRUCT* ts;
1354
1398
if (column.type.len == 0 ||
1355
1399
column.type.strlen_or_indptr == SQL_NULL_DATA) {
1356
1400
ei_x_encode_atom(&dynamic_buffer(state), "null");
1358
1402
switch(column.type.c) {
1403
case SQL_C_TYPE_TIMESTAMP:
1404
ts = (TIMESTAMP_STRUCT*)column.buffer;
1405
ei_x_encode_tuple_header(&dynamic_buffer(state), 2);
1406
ei_x_encode_tuple_header(&dynamic_buffer(state), 3);
1407
ei_x_encode_ulong(&dynamic_buffer(state), ts->year);
1408
ei_x_encode_ulong(&dynamic_buffer(state), ts->month);
1409
ei_x_encode_ulong(&dynamic_buffer(state), ts->day);
1410
ei_x_encode_tuple_header(&dynamic_buffer(state), 3);
1411
ei_x_encode_ulong(&dynamic_buffer(state), ts->hour);
1412
ei_x_encode_ulong(&dynamic_buffer(state), ts->minute);
1413
ei_x_encode_ulong(&dynamic_buffer(state), ts->second);
1359
1415
case SQL_C_CHAR:
1360
ei_x_encode_string(&dynamic_buffer(state), column.buffer);
1416
if binary_strings(state) {
1417
ei_x_encode_binary(&dynamic_buffer(state),
1418
column.buffer,column.type.strlen_or_indptr);
1420
ei_x_encode_string(&dynamic_buffer(state), column.buffer);
1424
ei_x_encode_binary(&dynamic_buffer(state),
1425
column.buffer,column.type.strlen_or_indptr);
1362
1427
case SQL_C_SLONG:
1363
1428
ei_x_encode_long(&dynamic_buffer(state),
1371
1436
ei_x_encode_atom(&dynamic_buffer(state),
1372
1437
column.buffer[0]?"true":"false");
1375
1440
column = retrive_binary_data(column, column_nr, state);
1376
ei_x_encode_string(&dynamic_buffer(state), (void *)column.buffer);
1441
if binary_strings(state) {
1442
ei_x_encode_binary(&dynamic_buffer(state),
1443
column.buffer,column.type.strlen_or_indptr);
1445
ei_x_encode_string(&dynamic_buffer(state), (void *)column.buffer);
1379
1449
ei_x_encode_atom(&dynamic_buffer(state), "error");
1396
1466
ei_x_encode_atom(&dynamic_buffer(state), "sql_varchar");
1397
1467
ei_x_encode_long(&dynamic_buffer(state), size);
1470
ei_x_encode_tuple_header(&dynamic_buffer(state), 2);
1471
ei_x_encode_atom(&dynamic_buffer(state), "sql_wchar");
1472
ei_x_encode_long(&dynamic_buffer(state), size);
1475
ei_x_encode_tuple_header(&dynamic_buffer(state), 2);
1476
ei_x_encode_atom(&dynamic_buffer(state), "sql_wvarchar");
1477
ei_x_encode_long(&dynamic_buffer(state), size);
1399
1479
case SQL_NUMERIC:
1400
1480
ei_x_encode_tuple_header(&dynamic_buffer(state), 3);
1401
1481
ei_x_encode_atom(&dynamic_buffer(state), "sql_numeric");
1487
static Boolean decode_params(byte *buffer, int *index, param_array **params,
1567
static Boolean decode_params(db_state *state, byte *buffer, int *index, param_array **params,
1490
1570
int erl_type, size;
1491
1571
long bin_size, l64;
1492
1573
param_array* param;
1574
TIMESTAMP_STRUCT* ts;
1494
1576
ei_get_type(buffer, index, &erl_type, &size);
1495
1577
param = &(*params)[i];
1497
1579
switch (param->type.c) {
1498
1580
case SQL_C_CHAR:
1499
if(erl_type != ERL_STRING_EXT) {
1503
ei_decode_string(buffer, index, &(param->values.string[param->offset]));
1504
param->offset += param->type.len;
1505
param->type.strlen_or_indptr_array[j] = SQL_NTS;
1581
if (binary_strings(state)) {
1582
ei_decode_binary(buffer, index,
1583
&(param->values.string[param->offset]), &bin_size);
1584
param->offset += param->type.len;
1585
param->type.strlen_or_indptr_array[j] = SQL_NTS;
1587
if(erl_type != ERL_STRING_EXT) {
1590
ei_decode_string(buffer, index, &(param->values.string[param->offset]));
1591
param->offset += param->type.len;
1592
param->type.strlen_or_indptr_array[j] = SQL_NTS;
1596
ei_decode_binary(buffer, index, &(param->values.string[param->offset]), &bin_size);
1597
param->offset += param->type.len;
1598
param->type.strlen_or_indptr_array[j] = SQL_NTS;
1600
case SQL_C_TYPE_TIMESTAMP:
1601
ts = (TIMESTAMP_STRUCT*) param->values.string;
1602
ei_decode_tuple_header(buffer, index, &size);
1603
ei_decode_long(buffer, index, &val);
1604
ts[j].year = (SQLUSMALLINT)val;
1605
ei_decode_long(buffer, index, &val);
1606
ts[j].month = (SQLUSMALLINT)val;
1607
ei_decode_long(buffer, index, &val);
1608
ts[j].day = (SQLUSMALLINT)val;
1609
ei_decode_long(buffer, index, &val);
1610
ts[j].hour = (SQLUSMALLINT)val;
1611
ei_decode_long(buffer, index, &val);
1612
ts[j].minute = (SQLUSMALLINT)val;
1613
ei_decode_long(buffer, index, &val);
1614
ts[j].second = (SQLUSMALLINT)val;
1615
ts[j].fraction = (SQLINTEGER)0;
1508
1617
case SQL_C_SLONG:
1509
if(!((erl_type == ERL_SMALL_INTEGER_EXT) ||
1510
(erl_type == ERL_INTEGER_EXT) ||
1511
(erl_type == ERL_SMALL_BIG_EXT) ||
1512
(erl_type == ERL_LARGE_BIG_EXT))) {
1516
if(ei_decode_long(buffer, index, &l64)) {
1520
/* For 64-bit platforms we downcast 8-byte long
1521
* to 4-byte SQLINTEGER, checking for overflow */
1523
if(l64>INT_MAX || l64<INT_MIN) {
1618
if(!((erl_type == ERL_SMALL_INTEGER_EXT) ||
1619
(erl_type == ERL_INTEGER_EXT) ||
1620
(erl_type == ERL_SMALL_BIG_EXT) ||
1621
(erl_type == ERL_LARGE_BIG_EXT))) {
1625
if(ei_decode_long(buffer, index, &l64)) {
1629
/* For 64-bit platforms we downcast 8-byte long
1630
* to 4-byte SQLINTEGER, checking for overflow */
1632
if(l64>INT_MAX || l64<INT_MIN) {
1527
1636
param->values.integer[j]=(SQLINTEGER)l64;
1530
1639
case SQL_C_DOUBLE:
1531
if((erl_type != ERL_FLOAT_EXT)) {
1534
ei_decode_double(buffer, index, &(param->values.floating[j]));
1640
if((erl_type != ERL_FLOAT_EXT)) {
1643
ei_decode_double(buffer, index, &(param->values.floating[j]));
1537
1646
case SQL_C_BIT:
1538
1647
if((erl_type != ERL_ATOM_EXT)) {
1541
1650
ei_decode_boolean(buffer, index, &(param->values.bool[j]));
1620
1729
/* ------------- Socket communication functions --------------------------*/
1626
#if defined WIN32 || defined USE_IPV4
1627
/* Currently only an old windows compiler is supported so we do not have ipv6
1629
1732
static SOCKET connect_to_erlang(const char *port)
1632
struct sockaddr_in sin;
1634
sock = socket(AF_INET, SOCK_STREAM, 0);
1636
memset(&sin, 0, sizeof(sin));
1637
sin.sin_port = htons ((unsigned short)atoi(port));
1638
sin.sin_family = AF_INET;
1639
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
1641
if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
1643
DO_EXIT(EXIT_SOCKET_CONNECT);
1647
1733
#elif defined(UNIX)
1648
1734
static int connect_to_erlang(const char *port)
1652
struct addrinfo hints;
1653
struct addrinfo *erlang_ai, *first;
1655
memset(&hints, 0, sizeof(hints));
1656
hints.ai_family = PF_UNSPEC; /* PF_INET or PF_INET6 */
1657
hints.ai_socktype = SOCK_STREAM;
1658
hints.ai_protocol = IPPROTO_TCP;
1660
if (getaddrinfo("localhost", port, &hints, &first) != 0) {
1661
DO_EXIT(EXIT_FAILURE);
1664
for (erlang_ai = first; erlang_ai; erlang_ai = erlang_ai->ai_next) {
1742
struct sockaddr_in sin;
1744
#if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_ADDR) && defined(AF_INET6)
1745
struct sockaddr_in6 sin6;
1747
sock = socket(AF_INET6, SOCK_STREAM, 0);
1749
memset(&sin6, 0, sizeof(sin6));
1750
sin6.sin6_port = htons ((unsigned short)atoi(port));
1751
sin6.sin6_family = AF_INET6;
1752
sin6.sin6_addr = in6addr_loopback;
1754
if (connect(sock, (struct sockaddr*)&sin6, sizeof(sin6)) == 0) {
1759
sock = socket(AF_INET, SOCK_STREAM, 0);
1761
memset(&sin, 0, sizeof(sin));
1762
sin.sin_port = htons ((unsigned short)atoi(port));
1763
sin.sin_family = AF_INET;
1764
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1666
sock = socket(erlang_ai->ai_family, erlang_ai->ai_socktype,
1667
erlang_ai->ai_protocol);
1670
if (connect(sock, (struct sockaddr*)erlang_ai->ai_addr,
1671
erlang_ai->ai_addrlen) < 0) {
1766
if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
1768
DO_EXIT(EXIT_SOCKET_CONNECT);
1679
freeaddrinfo(first);
1683
DO_EXIT(EXIT_SOCKET_CONNECT);
1691
1774
static void close_socket(SOCKET socket)
1950
2033
environment_handle(state),
1951
2034
&connection_handle(state))))
1952
2035
DO_EXIT(EXIT_ALLOC);
2036
/* By default Erlang handles all timeouts */
1953
2037
if(!sql_success(SQLSetConnectAttr(connection_handle(state),
1954
2038
SQL_ATTR_CONNECTION_TIMEOUT,
1955
2039
(SQLPOINTER)TIME_OUT, 0)))
1956
DO_EXIT(EXIT_CONNECTION);
2040
DO_EXIT(EXIT_CONNECTION);
1957
2041
if(!sql_success(SQLSetConnectAttr(connection_handle(state),
1958
2042
SQL_ATTR_AUTOCOMMIT,
1959
2043
(SQLPOINTER)auto_commit_mode, 0)))
1960
DO_EXIT(EXIT_CONNECTION);
2044
DO_EXIT(EXIT_CONNECTION);
1961
2045
if(!sql_success(SQLSetConnectAttr(connection_handle(state),
1962
2046
SQL_ATTR_TRACE,
1963
2047
(SQLPOINTER)trace_driver, 0)))
1964
DO_EXIT(EXIT_CONNECTION);
2048
DO_EXIT(EXIT_CONNECTION);
1967
2051
static void init_param_column(param_array *params, byte *buffer, int *index,
2045
2129
sizeof(byte)* params->type.len);
2134
if(user_type == USER_WCHAR) {
2135
params->type.sql = SQL_WCHAR;
2137
params->type.sql = SQL_WVARCHAR;
2139
ei_decode_long(buffer, index, &length);
2140
/* Max string length + string terminator */
2141
params->type.len = (length+1)*sizeof(SQLWCHAR);
2142
params->type.c = SQL_C_WCHAR;
2143
params->type.col_size = (SQLUINTEGER)length;
2144
params->type.strlen_or_indptr_array =
2145
(SQLLEN*)safe_malloc(num_param_values * sizeof(SQLINTEGER));
2146
params->values.string =
2147
(byte *)safe_malloc(num_param_values * sizeof(byte) * params->type.len);
2150
case USER_TIMESTAMP:
2151
params->type.sql = SQL_TYPE_TIMESTAMP;
2152
params->type.len = sizeof(TIMESTAMP_STRUCT);
2153
params->type.c = SQL_C_TYPE_TIMESTAMP;
2154
params->type.col_size = (SQLUINTEGER)COL_SQL_TIMESTAMP;
2155
params->values.string =
2156
(byte *)safe_malloc(num_param_values * params->type.len);
2048
2158
case USER_FLOAT:
2049
2159
params->type.sql = SQL_FLOAT;
2050
2160
params->type.c = SQL_C_DOUBLE;
2464
2587
/* Foreach diagnostic record in the current set of diagnostic records
2465
2588
the error message is obtained */
2466
2589
for(record_nr = 1; ;record_nr++) {
2467
if(SQLGetDiagRec(handleType, handle, record_nr, current_sql_state,
2590
result = SQLGetDiagRec(handleType, handle, record_nr, current_sql_state,
2468
2591
&nativeError, current_errmsg_pos,
2469
(SQLSMALLINT)errmsg_buffer_size, &errmsg_size)
2592
(SQLSMALLINT)errmsg_buffer_size, &errmsg_size);
2593
if(result != SQL_SUCCESS && result != SQL_NO_DATA) {