ibm_db 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +6 -0
- data/README +17 -17
- data/ext/extconf.rb +18 -15
- data/ext/ibm_db.c +91 -3
- data/ext/ruby_ibm_db.h +17 -0
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +65 -39
- data/test/cases/adapter_test.rb +6 -0
- data/test/cases/associations/eager_test.rb +54 -5
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +71 -4
- data/test/cases/associations/has_many_through_associations_test.rb +50 -3
- data/test/cases/base_test.rb +106 -34
- data/test/cases/calculations_test.rb +5 -0
- data/test/cases/finder_test.rb +162 -11
- data/test/cases/fixtures_test.rb +32 -3
- data/test/cases/migration_test.rb +60 -22
- data/test/cases/validations_test.rb +44 -33
- data/test/schema/schema.rb +13 -2
- metadata +2 -2
data/CHANGES
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
Change Log
|
2
2
|
==============
|
3
|
+
2008/12/18 (IBM_DB adapter 1.0.1, driver 1.0.1) :
|
4
|
+
- Support for datatype decfloat
|
5
|
+
- Changes in installation process. Now user should set IBM_DB_INCLUDE env variable instead of IBM_DB_DIR
|
6
|
+
- Support for specifying the Authentication type to be used during connection in adapter
|
7
|
+
- Corrected the ignorance of a connection, when the connection is successful with a warning
|
8
|
+
- ActiveRecord-2.2.2 test suite changes for IBM_DB
|
3
9
|
2008/11/06 (IBM_DB adapter 1.0.0, driver 0.10.0):
|
4
10
|
- Support for short-hand migration syntax for datatype char and double in create_table
|
5
11
|
- Support for short-hand migration syntax for datatypes xml, char and double in change_table
|
data/README
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
=====================================================================
|
2
|
-
README for the IBM_DB Adapter (1.0.
|
2
|
+
README for the IBM_DB Adapter (1.0.1) and Driver (1.0.1) (2008/12/18)
|
3
3
|
For ActiveRecord Version >= 1.15.5 (and Rails >= 1.2.5)
|
4
4
|
=====================================================================
|
5
5
|
|
@@ -30,7 +30,7 @@ Ruby environment, including Rails, to interact with IBM data servers.
|
|
30
30
|
|
31
31
|
Note : - 1) If using activerecord version below 2.0 then it requires that the ibm_db adapter be registered with the list of connection adapters by manually adding ibm_db at line 77 (approx) in the file activerecord.rb (GEM_HOME\activerecord-<version>\lib\).
|
32
32
|
|
33
|
-
|
33
|
+
2) The IBM_DB driver can also be built separately (from source) and used in direct API calls.
|
34
34
|
|
35
35
|
1. Windows platforms:
|
36
36
|
=====================
|
@@ -43,10 +43,10 @@ Note : - 1) If using activerecord version below 2.0 then it requires that the ib
|
|
43
43
|
D:\>gem install ibm_db
|
44
44
|
Bulk updating gem source index for: http://gems.rubyforge.org
|
45
45
|
Select which gem to install for your platform (i386-mswin32)
|
46
|
-
1. ibm_db 0.
|
47
|
-
2. ibm_db 0.
|
48
|
-
3. ibm_db 0.
|
49
|
-
4. ibm_db 0.
|
46
|
+
1. ibm_db 1.0.0 (mswin32)
|
47
|
+
2. ibm_db 1.0.0 (ruby)
|
48
|
+
3. ibm_db 0.10.0 (mswin32)
|
49
|
+
4. ibm_db 0.10.0 (ruby)
|
50
50
|
|
51
51
|
Running gem install ibm_db you are presented with two choices for each release
|
52
52
|
(mswin32 or ruby)choose mswin32. This will install the IBM_DB gem containing
|
@@ -75,14 +75,14 @@ Note : - 1) If using activerecord version below 2.0 then it requires that the ib
|
|
75
75
|
Note: DB2 environment is required while using an arbitrary user account
|
76
76
|
(other than the DB2 install user account)
|
77
77
|
$ . /home/db2inst1/sqllib/db2profile
|
78
|
-
$ export
|
79
|
-
$ export IBM_DB_LIB
|
78
|
+
$ export IBM_DB_INCLUDE=DB2HOME/include (eg. /home/db2inst1/sqllib/include or /opt/ibm/db2/v9.5/include)
|
79
|
+
$ export IBM_DB_LIB=DB2HOME/lib (eg. /home/db2inst1/sqllib/lib or /opt/ibm/db2/V9.5/lib32)
|
80
80
|
$ gem install ibm_db
|
81
81
|
Select which gem to install for your platform (i686-linux)
|
82
|
-
1. ibm_db 0.
|
83
|
-
2. ibm_db 0.
|
84
|
-
3. ibm_db 0.
|
85
|
-
4. ibm_db 0.
|
82
|
+
1. ibm_db 1.0.0 (mswin32)
|
83
|
+
2. ibm_db 1.0.0 (ruby)
|
84
|
+
3. ibm_db 0.10.0 (ruby)
|
85
|
+
4. ibm_db 0.10.0 (mswin32)
|
86
86
|
...
|
87
87
|
Running gem install ibm_db you are presented with two choices for each release
|
88
88
|
(mswin32 or ruby) choose ruby. This will build the native extension (ibm_db driver) and installs the ibm_db gem.
|
@@ -94,7 +94,7 @@ Note : - 1) If using activerecord version below 2.0 then it requires that the ib
|
|
94
94
|
Installing RDoc documentation for ibm_db-0.6.5...
|
95
95
|
|
96
96
|
TEST (simple gem install verification)
|
97
|
-
Note: The manual step after install if using activerecord version below 2.0 is:
|
97
|
+
Note: The manual step after install, if using activerecord version below 2.0 is:
|
98
98
|
add ibm_db into GEM_HOME\1.8\gems\activerecord-1.15.3\lib\active_record.rb (Line 77)
|
99
99
|
$ irb
|
100
100
|
irb(main):001:0> gem 'ibm_db'
|
@@ -144,8 +144,8 @@ here only for reference, and also involves running the unit tests.
|
|
144
144
|
port: 50000
|
145
145
|
|
146
146
|
- To compile and link with DB2 client libraries:
|
147
|
-
|
148
|
-
|
147
|
+
$ export IBM_DB_INCLUDE=DB2HOME/include (eg. /home/db2inst1/sqllib/include or /opt/ibm/db2/v9.5/include)
|
148
|
+
$ export IBM_DB_LIB=DB2HOME/lib (eg. /home/db2inst1/sqllib/lib or /opt/ibm/db2/V9.5/lib32)
|
149
149
|
|
150
150
|
Windows platforms:
|
151
151
|
- Install Visual C++ 2005, Platform SDK (latest), .Net SDK (latest)
|
@@ -153,7 +153,7 @@ here only for reference, and also involves running the unit tests.
|
|
153
153
|
CALL "C:\Program Files\Microsoft Platform SDK for Windows Server 2005\SetEnv.Cmd"
|
154
154
|
CALL "C:\Program Files\Microsoft Visual C++ Toolkit 2005\vcvars32.bat"
|
155
155
|
SET LIB=%LIB%;C:\Program Files\Microsoft Visual Studio .NET 2005\Vc8\lib
|
156
|
-
- To configure database connection parameters edit config.
|
156
|
+
- To configure database connection parameters edit config.yml
|
157
157
|
|
158
158
|
Build and Execution:
|
159
159
|
rake
|
@@ -162,7 +162,7 @@ here only for reference, and also involves running the unit tests.
|
|
162
162
|
rake onlytests
|
163
163
|
|
164
164
|
Execution of a single test inside the tests directory can be done by the following:
|
165
|
-
export SINGLE_RUBY_TEST=
|
165
|
+
export SINGLE_RUBY_TEST=test_001_CtlgConn.rb
|
166
166
|
rake
|
167
167
|
|
168
168
|
|
data/ext/extconf.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# +----------------------------------------------------------------------+
|
4
4
|
# | Licensed Materials - Property of IBM |
|
5
5
|
# | |
|
6
|
-
# | (C) Copyright IBM Corporation 2006, 2007
|
6
|
+
# | (C) Copyright IBM Corporation 2006, 2007,2008 |
|
7
7
|
# +----------------------------------------------------------------------+
|
8
8
|
|
9
9
|
require 'mkmf'
|
@@ -11,32 +11,35 @@ WIN = RUBY_PLATFORM =~ /mswin/
|
|
11
11
|
|
12
12
|
# use ENV['DB2DIR'] or latest db2 you can find
|
13
13
|
# (we need to revisit default when db2 10.x comes out)
|
14
|
-
|
15
|
-
(Dir['/opt/*/db2
|
16
|
-
|
14
|
+
IBM_DB_INCLUDE = (ENV['IBM_DB_INCLUDE'] or
|
15
|
+
(Dir['/opt/*/db2/*/include'].sort_by {|f| File.basename(f)}).last )
|
16
|
+
IBM_DB_LIB = (ENV['IBM_DB_LIB'] or
|
17
|
+
(Dir['/opt/*/db2/*/lib32'].sort_by {|f| File.basename(f)}).last )
|
18
|
+
|
19
|
+
dir_config('IBM_DB',IBM_DB_INCLUDE,IBM_DB_LIB)
|
17
20
|
|
18
21
|
def crash(str)
|
19
22
|
printf(" extconf failure: %s\n", str)
|
20
23
|
exit 1
|
21
24
|
end
|
22
25
|
|
23
|
-
unless (have_library(WIN ? 'db2cli' : 'db2','SQLConnect') or find_library(WIN ? 'db2cli' : 'db2','SQLConnect',
|
26
|
+
unless (have_library(WIN ? 'db2cli' : 'db2','SQLConnect') or find_library(WIN ? 'db2cli' : 'db2','SQLConnect', IBM_DB_LIB))
|
24
27
|
crash(<<EOL)
|
25
28
|
Unable to locate DB2 libraries.
|
26
29
|
|
27
|
-
|
30
|
+
Follow the steps below and retry
|
28
31
|
|
29
|
-
|
32
|
+
Step 1: - Install IBM DB2 Universal Database Server/Client
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
step 2: - Set the environment variables IBM_DB_INCLUDE and IBM_DB_LIB as below
|
35
|
+
|
36
|
+
(assuming bash shell)
|
37
|
+
|
38
|
+
export IBM_DB_INCLUDE=DB2HOME/include (eg. /home/db2inst1/sqllib/include or /opt/ibm/db2/v9.5/include)
|
39
|
+
export IBM_DB_LIB=DB2HOME/lib (eg. /home/db2inst1/sqllib/lib or /opt/ibm/db2/V9.5/lib32)
|
34
40
|
|
35
|
-
|
36
|
-
|
37
|
-
Try passing one of the following options to extconf.rb:
|
38
|
-
--with-IBM_DB-dir=/path/to/db2 (eg. /opt/IBM/db2/V9.1)
|
39
|
-
--with-IBM_DB-lib=/path/to/db2/lib (eg. /opt/IBM/db2/V9.1/lib32)
|
41
|
+
step 3: - Retry gem install
|
42
|
+
|
40
43
|
EOL
|
41
44
|
end
|
42
45
|
|
data/ext/ibm_db.c
CHANGED
@@ -2,15 +2,17 @@
|
|
2
2
|
+----------------------------------------------------------------------+
|
3
3
|
| Licensed Materials - Property of IBM |
|
4
4
|
| |
|
5
|
-
| (C) Copyright IBM Corporation 2006, 2007
|
5
|
+
| (C) Copyright IBM Corporation 2006, 2007,2008 |
|
6
6
|
+----------------------------------------------------------------------+
|
7
7
|
| Authors: Sushant Koduru, Lynh Nguyen, Kanchana Padmanabhan, |
|
8
8
|
| Dan Scott, Helmut Tessarek, Sam Ruby, Kellen Bombardier, |
|
9
9
|
| Tony Cairns, Manas Dadarkar, Swetha Patel, Salvador Ledezma |
|
10
|
+
| Mario Ds Briggs, Praveen Devarao, Ambrish Bhargava, |
|
11
|
+
| Tarun Pasrija |
|
10
12
|
+----------------------------------------------------------------------+
|
11
13
|
*/
|
12
14
|
|
13
|
-
#define MODULE_RELEASE "0.
|
15
|
+
#define MODULE_RELEASE "1.0.1"
|
14
16
|
|
15
17
|
#ifdef HAVE_CONFIG_H
|
16
18
|
#include "config.h"
|
@@ -29,6 +31,7 @@ static void _ruby_ibm_db_check_sql_errors( SQLHANDLE handle, SQLSMALLINT hType,
|
|
29
31
|
static void _ruby_ibm_db_assign_options( void* handle, int type, long opt_key, VALUE data );
|
30
32
|
static void _ruby_ibm_db_clear_conn_err_cache();
|
31
33
|
static void _ruby_ibm_db_clear_stmt_err_cache();
|
34
|
+
static int _ruby_ibm_db_set_decfloat_rounding_mode_client(SQLHANDLE hdbc);
|
32
35
|
static char * _ruby_ibm_db_instance_name;
|
33
36
|
static int is_systemi, is_informix; /* 1 == TRUE; 0 == FALSE; */
|
34
37
|
|
@@ -399,6 +402,7 @@ static void _ruby_ibm_db_free_result_struct(stmt_handle* handle)
|
|
399
402
|
case SQL_DECIMAL:
|
400
403
|
case SQL_NUMERIC:
|
401
404
|
case SQL_XML:
|
405
|
+
case SQL_DECFLOAT:
|
402
406
|
if ( handle->row_data[i].data.str_val != NULL ) {
|
403
407
|
ruby_xfree(handle->row_data[i].data.str_val);
|
404
408
|
handle->row_data[i].data.str_val = NULL;
|
@@ -967,6 +971,7 @@ static int _ruby_ibm_db_bind_column_helper(stmt_handle *stmt_res)
|
|
967
971
|
case SQL_TYPE_TIME:
|
968
972
|
case SQL_TYPE_TIMESTAMP:
|
969
973
|
case SQL_BIGINT:
|
974
|
+
case SQL_DECFLOAT:
|
970
975
|
in_length = stmt_res->column_info[i].size+1;
|
971
976
|
row_data->str_val = (SQLCHAR *)ALLOC_N(char, in_length);
|
972
977
|
rc = SQLBindCol((SQLHSTMT)stmt_res->hstmt, (SQLUSMALLINT)(i+1),
|
@@ -1202,13 +1207,25 @@ static VALUE _ruby_ibm_db_connect_helper( int argc, VALUE *argv, int isPersisten
|
|
1202
1207
|
(SQLCHAR *)password, (SQLSMALLINT)password_len );
|
1203
1208
|
}
|
1204
1209
|
|
1205
|
-
if ( rc
|
1210
|
+
if ( rc == SQL_ERROR ) {
|
1206
1211
|
_ruby_ibm_db_check_sql_errors(conn_res->hdbc, SQL_HANDLE_DBC, rc, 1, NULL, -1, 1);
|
1207
1212
|
SQLFreeHandle( SQL_HANDLE_DBC, conn_res->hdbc );
|
1208
1213
|
SQLFreeHandle(SQL_HANDLE_ENV, conn_res->henv);
|
1209
1214
|
break;
|
1210
1215
|
}
|
1211
1216
|
|
1217
|
+
#ifdef CLI_DBC_SERVER_TYPE_DB2LUW
|
1218
|
+
#ifdef SQL_ATTR_DECFLOAT_ROUNDING_MODE
|
1219
|
+
|
1220
|
+
/**
|
1221
|
+
* Code for setting SQL_ATTR_DECFLOAT_ROUNDING_MODE
|
1222
|
+
* for implementation of Decfloat Datatype
|
1223
|
+
* */
|
1224
|
+
_ruby_ibm_db_set_decfloat_rounding_mode_client(conn_res->hdbc);
|
1225
|
+
|
1226
|
+
#endif
|
1227
|
+
#endif
|
1228
|
+
|
1212
1229
|
/* Get the server name */
|
1213
1230
|
memset(server, 0, sizeof(server));
|
1214
1231
|
rc = SQLGetInfo(conn_res->hdbc, SQL_DBMS_NAME, (SQLPOINTER)server, 2048, NULL);
|
@@ -1278,6 +1295,74 @@ static VALUE _ruby_ibm_db_connect_helper( int argc, VALUE *argv, int isPersisten
|
|
1278
1295
|
conn_res);
|
1279
1296
|
}
|
1280
1297
|
}
|
1298
|
+
|
1299
|
+
#ifdef CLI_DBC_SERVER_TYPE_DB2LUW
|
1300
|
+
#ifdef SQL_ATTR_DECFLOAT_ROUNDING_MODE
|
1301
|
+
/**
|
1302
|
+
* Function for implementation of DECFLOAT Datatype
|
1303
|
+
*
|
1304
|
+
* Description :
|
1305
|
+
* This function retrieves the value of special register decflt_rounding
|
1306
|
+
* from the database server which signifies the current rounding mode set
|
1307
|
+
* on the server. For using decfloat, the rounding mode has to be in sync
|
1308
|
+
* on the client as well as server. Thus we set here on the client, the
|
1309
|
+
* same rounding mode as the server.
|
1310
|
+
* @return: success or failure
|
1311
|
+
* */
|
1312
|
+
static int _ruby_ibm_db_set_decfloat_rounding_mode_client(SQLHANDLE hdbc)
|
1313
|
+
{
|
1314
|
+
SQLCHAR decflt_rounding[20];
|
1315
|
+
SQLHANDLE hstmt;
|
1316
|
+
int rc = 0;
|
1317
|
+
int rounding_mode;
|
1318
|
+
SQLINTEGER decfloat;
|
1319
|
+
|
1320
|
+
|
1321
|
+
SQLCHAR *stmt = (SQLCHAR *)"values current decfloat rounding mode";
|
1322
|
+
|
1323
|
+
/* Allocate a Statement Handle */
|
1324
|
+
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
1325
|
+
if (rc == SQL_ERROR) {
|
1326
|
+
_ruby_ibm_db_check_sql_errors(hdbc, SQL_HANDLE_DBC, rc, 1,
|
1327
|
+
NULL, -1, 1);
|
1328
|
+
return rc;
|
1329
|
+
}
|
1330
|
+
rc = SQLExecDirect((SQLHSTMT)hstmt, stmt, SQL_NTS);
|
1331
|
+
if ( rc == SQL_ERROR ) {
|
1332
|
+
_ruby_ibm_db_check_sql_errors((SQLHSTMT)hstmt,
|
1333
|
+
SQL_HANDLE_STMT, rc, 1, NULL,
|
1334
|
+
-1, 1);
|
1335
|
+
return rc;
|
1336
|
+
}
|
1337
|
+
|
1338
|
+
rc = SQLBindCol((SQLHSTMT)hstmt, 1, SQL_C_DEFAULT, decflt_rounding, 20, NULL);
|
1339
|
+
if ( rc == SQL_ERROR ) {
|
1340
|
+
_ruby_ibm_db_check_sql_errors((SQLHSTMT)hstmt,
|
1341
|
+
SQL_HANDLE_STMT, rc, 1, NULL,
|
1342
|
+
-1, 1);
|
1343
|
+
return rc;
|
1344
|
+
}
|
1345
|
+
rc = SQLFetch(hstmt);
|
1346
|
+
rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
1347
|
+
/* Now setting up the same rounding mode on the client*/
|
1348
|
+
if(strcmp(decflt_rounding,"ROUND_HALF_EVEN")== 0) rounding_mode = ROUND_HALF_EVEN;
|
1349
|
+
if(strcmp(decflt_rounding,"ROUND_HALF_UP")== 0) rounding_mode = ROUND_HALF_UP;
|
1350
|
+
if(strcmp(decflt_rounding,"ROUND_DOWN")== 0) rounding_mode = ROUND_DOWN;
|
1351
|
+
if(strcmp(decflt_rounding,"ROUND_CEILING")== 0) rounding_mode = ROUND_CEILING;
|
1352
|
+
if(strcmp(decflt_rounding,"ROUND_FLOOR")== 0) rounding_mode = ROUND_FLOOR;
|
1353
|
+
|
1354
|
+
#ifndef PASE
|
1355
|
+
rc = SQLSetConnectAttr(hdbc,SQL_ATTR_DECFLOAT_ROUNDING_MODE,(SQLPOINTER)rounding_mode ,SQL_NTS);
|
1356
|
+
#else
|
1357
|
+
rc = SQLSetConnectAttr(hdbc,SQL_ATTR_DECFLOAT_ROUNDING_MODE,(SQLPOINTER)&rounding_mode ,SQL_NTS);
|
1358
|
+
#endif
|
1359
|
+
|
1360
|
+
|
1361
|
+
return rc;
|
1362
|
+
}
|
1363
|
+
#endif
|
1364
|
+
#endif
|
1365
|
+
|
1281
1366
|
/* */
|
1282
1367
|
|
1283
1368
|
/* static void _ruby_ibm_db_clear_conn_err_cache ()
|
@@ -4458,6 +4543,7 @@ VALUE ibm_db_field_type(int argc, VALUE *argv, VALUE self)
|
|
4458
4543
|
case SQL_DOUBLE:
|
4459
4544
|
case SQL_DECIMAL:
|
4460
4545
|
case SQL_NUMERIC:
|
4546
|
+
case SQL_DECFLOAT:
|
4461
4547
|
str_val = "real";
|
4462
4548
|
break;
|
4463
4549
|
case SQL_CLOB:
|
@@ -4814,6 +4900,7 @@ VALUE ibm_db_result(int argc, VALUE *argv, VALUE self)
|
|
4814
4900
|
case SQL_BIGINT:
|
4815
4901
|
case SQL_DECIMAL:
|
4816
4902
|
case SQL_NUMERIC:
|
4903
|
+
case SQL_DECFLOAT:
|
4817
4904
|
if (column_type == SQL_DECIMAL || column_type == SQL_NUMERIC)
|
4818
4905
|
in_length = stmt_res->column_info[col_num].size + stmt_res->column_info[col_num].scale + 2 + 1;
|
4819
4906
|
else
|
@@ -5109,6 +5196,7 @@ static VALUE _ruby_ibm_db_bind_fetch_helper(int argc, VALUE *argv, int op)
|
|
5109
5196
|
case SQL_BIGINT:
|
5110
5197
|
case SQL_DECIMAL:
|
5111
5198
|
case SQL_NUMERIC:
|
5199
|
+
case SQL_DECFLOAT:
|
5112
5200
|
|
5113
5201
|
if ( op & FETCH_ASSOC ) {
|
5114
5202
|
rb_hash_aset(return_value, rb_str_new2((char *)stmt_res->column_info[i].name), rb_str_new2((char *)row_data->str_val));
|
data/ext/ruby_ibm_db.h
CHANGED
@@ -21,6 +21,11 @@
|
|
21
21
|
#define SQL_XML -370
|
22
22
|
#endif
|
23
23
|
|
24
|
+
/* Needed for Backward compatibility */
|
25
|
+
#ifndef SQL_DECFLOAT
|
26
|
+
#define SQL_DECFLOAT -360
|
27
|
+
#endif
|
28
|
+
|
24
29
|
/* SQL_ATTR_USE_TRUSTED_CONTEXT,
|
25
30
|
* SQL_ATTR_TRUSTED_CONTEXT_USERID and
|
26
31
|
* SQL_ATTR_TRUSTED_CONTEXT_PASSWORD
|
@@ -95,6 +100,18 @@
|
|
95
100
|
#define APPLNAME_LEN 32
|
96
101
|
#define WRKSTNNAME_LEN 18
|
97
102
|
|
103
|
+
/*
|
104
|
+
* Enum for Decfloat Rounding Modes
|
105
|
+
* */
|
106
|
+
enum
|
107
|
+
{
|
108
|
+
ROUND_HALF_EVEN = 0,
|
109
|
+
ROUND_HALF_UP,
|
110
|
+
ROUND_DOWN,
|
111
|
+
ROUND_CEILING,
|
112
|
+
ROUND_FLOOR
|
113
|
+
}ROUNDING_MODE;
|
114
|
+
|
98
115
|
void Init_ibm_db();
|
99
116
|
|
100
117
|
VALUE ibm_db_connect(int argc, VALUE *argv, VALUE self);
|
@@ -127,15 +127,17 @@ requires credentials: username and password"
|
|
127
127
|
# Retrieve database objects fields in lowercase
|
128
128
|
conn_options = {IBM_DB::ATTR_CASE => IBM_DB::CASE_LOWER}
|
129
129
|
config.each do |key, value|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
130
|
+
if !value.nil?
|
131
|
+
case key
|
132
|
+
when :app_user # Set connection's user info
|
133
|
+
conn_options[IBM_DB::SQL_ATTR_INFO_USERID] = value
|
134
|
+
when :account # Set connection's account info
|
135
|
+
conn_options[IBM_DB::SQL_ATTR_INFO_ACCTSTR] = value
|
136
|
+
when :application # Set connection's application info
|
137
|
+
conn_options[IBM_DB::SQL_ATTR_INFO_APPLNAME] = value
|
138
|
+
when :workstation # Set connection's workstation info
|
139
|
+
conn_options[IBM_DB::SQL_ATTR_INFO_WRKSTNNAME] = value
|
140
|
+
end
|
139
141
|
end
|
140
142
|
end
|
141
143
|
|
@@ -147,7 +149,7 @@ requires credentials: username and password"
|
|
147
149
|
host = config[:host]
|
148
150
|
# A net address connection requires a port. If no port has been specified, 50000 is used by default
|
149
151
|
port = config[:port] || 50000
|
150
|
-
# Connects to the database using the database, host, port, username and password specified
|
152
|
+
# Connects to the database using the database, host, port, authentication type, username and password specified
|
151
153
|
# Starting with DB2 9.1FP5 secure connections using SSL are supported.
|
152
154
|
# On the client side using CLI this is supported from CLI version V95FP2 and onwards.
|
153
155
|
# This feature is set by specifying SECURITY=SSL in the connection string.
|
@@ -160,6 +162,7 @@ requires credentials: username and password"
|
|
160
162
|
UID=#{username};\
|
161
163
|
PWD=#{password};"
|
162
164
|
conn_string << "SECURITY=#{config[:security]};" if config.has_key?(:security)
|
165
|
+
conn_string << "AUTHENTICATION=#{config[:authentication]};" if config.has_key?(:authentication)
|
163
166
|
connection = IBM_DB.connect conn_string, '', '', conn_options
|
164
167
|
else
|
165
168
|
# No host implies a local catalog-based connection: +database+ represents catalog alias
|
@@ -206,10 +209,10 @@ requires credentials: username and password"
|
|
206
209
|
:boolean
|
207
210
|
when /int|serial/i
|
208
211
|
:integer
|
212
|
+
when /decimal|numeric|decfloat/i
|
213
|
+
:decimal
|
209
214
|
when /float|double|real/i
|
210
215
|
:float
|
211
|
-
when /decimal|numeric/i
|
212
|
-
:decimal
|
213
216
|
when /timestamp|datetime/i
|
214
217
|
:timestamp
|
215
218
|
when /time/i
|
@@ -269,6 +272,12 @@ requires credentials: username and password"
|
|
269
272
|
return self
|
270
273
|
end
|
271
274
|
|
275
|
+
#Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type decfloat
|
276
|
+
def decfloat(*args)
|
277
|
+
ibm_parse_column_attributes_args('decfloat',*args)
|
278
|
+
return self
|
279
|
+
end
|
280
|
+
|
272
281
|
#Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type char [character]
|
273
282
|
def char(*args)
|
274
283
|
ibm_parse_column_attributes_args('char',*args)
|
@@ -302,6 +311,12 @@ requires credentials: username and password"
|
|
302
311
|
ibm_parse_column_attributes_args('double',*args)
|
303
312
|
return self
|
304
313
|
end
|
314
|
+
|
315
|
+
#Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type decfloat
|
316
|
+
def decfloat(*args)
|
317
|
+
ibm_parse_column_attributes_args('decfloat',*args)
|
318
|
+
return self
|
319
|
+
end
|
305
320
|
|
306
321
|
#Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type char [character]
|
307
322
|
def char(*args)
|
@@ -355,21 +370,23 @@ requires credentials: username and password"
|
|
355
370
|
# for IBM data servers (ibm_db.so).
|
356
371
|
# +config+ the hash passed as an initializer argument content:
|
357
372
|
# == mandatory parameters
|
358
|
-
# adapter:
|
359
|
-
# username:
|
360
|
-
# password:
|
361
|
-
# database:
|
373
|
+
# adapter: 'ibm_db' // IBM_DB Adapter name
|
374
|
+
# username: 'db2user' // data server (database) user
|
375
|
+
# password: 'secret' // data server (database) password
|
376
|
+
# database: 'ARUNIT' // remote database name (or catalog entry alias)
|
362
377
|
# == optional (highly recommended for data server auditing and monitoring purposes)
|
363
|
-
# schema:
|
364
|
-
# account:
|
365
|
-
# app_user:
|
366
|
-
# application:
|
367
|
-
# workstation:
|
378
|
+
# schema: 'rails123' // name space qualifier
|
379
|
+
# account: 'tester' // OS account (client workstation)
|
380
|
+
# app_user: 'test11' // authenticated application user
|
381
|
+
# application: 'rtests' // application name
|
382
|
+
# workstation: 'plato' // client workstation name
|
368
383
|
# == remote TCP/IP connection (required when no local database catalog entry available)
|
369
|
-
# host:
|
370
|
-
# port:
|
371
|
-
# security:
|
372
|
-
#
|
384
|
+
# host: 'socrates' // fully qualified hostname or IP address
|
385
|
+
# port: '50000' // data server TCP/IP port number
|
386
|
+
# security: 'SSL' // optional parameter enabling SSL encryption -
|
387
|
+
# // - Available only from CLI version V95fp2 and above
|
388
|
+
# authentication: 'SERVER' // AUTHENTICATION type which the client uses -
|
389
|
+
# // - to connect to the database server. By default value is SERVER
|
373
390
|
#
|
374
391
|
# When schema is not specified, the username value is used instead.
|
375
392
|
#
|
@@ -385,23 +402,24 @@ requires credentials: username and password"
|
|
385
402
|
|
386
403
|
def initialize(connection, logger, config, conn_options)
|
387
404
|
# Caching database connection configuration (+connect+ or +reconnect+ support)
|
388
|
-
@connection
|
389
|
-
@conn_options
|
390
|
-
@database
|
391
|
-
@username
|
392
|
-
@password
|
405
|
+
@connection = connection
|
406
|
+
@conn_options = conn_options
|
407
|
+
@database = config[:database]
|
408
|
+
@username = config[:username]
|
409
|
+
@password = config[:password]
|
393
410
|
if config.has_key?(:host)
|
394
|
-
@host
|
395
|
-
@port
|
411
|
+
@host = config[:host]
|
412
|
+
@port = config[:port] || 50000 # default port
|
396
413
|
end
|
397
|
-
@schema
|
398
|
-
@security
|
414
|
+
@schema = config[:schema]
|
415
|
+
@security = config[:security] || nil
|
416
|
+
@authentication = config[:authentication] || nil
|
399
417
|
|
400
418
|
# Caching database connection options (auditing and billing support)
|
401
|
-
@app_user
|
402
|
-
@account
|
403
|
-
@application
|
404
|
-
@workstation
|
419
|
+
@app_user = conn_options[:app_user] if conn_options.has_key?(:app_user)
|
420
|
+
@account = conn_options[:account] if conn_options.has_key?(:account)
|
421
|
+
@application = conn_options[:application] if conn_options.has_key?(:application)
|
422
|
+
@workstation = conn_options[:workstation] if conn_options.has_key?(:workstation)
|
405
423
|
|
406
424
|
# Calls the parent class +ConnectionAdapters+' initializer
|
407
425
|
# which sets @connection, @logger, @runtime and @last_verification
|
@@ -525,6 +543,7 @@ requires credentials: username and password"
|
|
525
543
|
UID=#{@username};\
|
526
544
|
PWD=#{@password};"
|
527
545
|
@conn_string << "SECURITY=#{@security};" if @security
|
546
|
+
@conn_string << "AUTHENTICATION=#{@authentication};" if @authentication
|
528
547
|
# Connects and assigns the resulting IBM_DB.Connection to the +@connection+ instance variable
|
529
548
|
@connection = IBM_DB.connect(@conn_string, '', '', @conn_options)
|
530
549
|
else
|
@@ -915,13 +934,20 @@ requires credentials: username and password"
|
|
915
934
|
:rowid => { :name => "rowid" }, # rowid is a supported datatype on z/OS and i/5
|
916
935
|
:serial => { :name => "serial" }, # rowid is a supported datatype on Informix Dynamic Server
|
917
936
|
:char => { :name => "char" },
|
918
|
-
:double => { :name => @servertype.get_double_mapping }
|
937
|
+
:double => { :name => @servertype.get_double_mapping },
|
938
|
+
:decfloat => { :name => "decfloat"}
|
919
939
|
}
|
920
940
|
end
|
921
941
|
|
922
942
|
# IBM data servers do not support limits on certain data types (unlike MySQL)
|
923
943
|
# Limit is supported for the {float, decimal, numeric, varchar, clob, blob} data types.
|
924
944
|
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
|
945
|
+
if type.to_sym == :decfloat
|
946
|
+
sql_segment = native_database_types[type.to_sym][:name].to_s
|
947
|
+
sql_segment << "(#{precision})" if !precision.nil?
|
948
|
+
return sql_segment
|
949
|
+
end
|
950
|
+
|
925
951
|
return super if limit.nil?
|
926
952
|
|
927
953
|
# strip off limits on data types not supporting them
|
data/test/cases/adapter_test.rb
CHANGED
@@ -109,6 +109,12 @@ class AdapterTest < ActiveRecord::TestCase
|
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
112
|
+
if current_adapter?(:PostgreSQLAdapter)
|
113
|
+
def test_encoding
|
114
|
+
assert_not_nil @connection.encoding
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
112
118
|
def test_table_alias
|
113
119
|
def @connection.test_table_alias_length() 10; end
|
114
120
|
class << @connection
|
@@ -18,7 +18,7 @@ require 'models/developer'
|
|
18
18
|
require 'models/project'
|
19
19
|
|
20
20
|
class EagerAssociationTest < ActiveRecord::TestCase
|
21
|
-
fixtures :posts, :comments, :authors, :categories, :categories_posts,
|
21
|
+
fixtures :posts, :comments, :authors, :author_addresses, :categories, :categories_posts,
|
22
22
|
:companies, :accounts, :tags, :taggings, :people, :readers,
|
23
23
|
:owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books,
|
24
24
|
:developers, :projects, :developers_projects
|
@@ -111,6 +111,46 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
+
def test_finding_with_includes_on_has_many_association_with_same_include_includes_only_once
|
115
|
+
author_id = authors(:david).id
|
116
|
+
author = assert_queries(3) { Author.find(author_id, :include => {:posts_with_comments => :comments}) } # find the author, then find the posts, then find the comments
|
117
|
+
author.posts_with_comments.each do |post_with_comments|
|
118
|
+
assert_equal post_with_comments.comments.length, post_with_comments.comments.count
|
119
|
+
assert_equal nil, post_with_comments.comments.uniq!
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_finding_with_includes_on_has_one_assocation_with_same_include_includes_only_once
|
124
|
+
author = authors(:david)
|
125
|
+
post = author.post_about_thinking_with_last_comment
|
126
|
+
last_comment = post.last_comment
|
127
|
+
author = assert_queries(3) { Author.find(author.id, :include => {:post_about_thinking_with_last_comment => :last_comment})} # find the author, then find the posts, then find the comments
|
128
|
+
assert_no_queries do
|
129
|
+
assert_equal post, author.post_about_thinking_with_last_comment
|
130
|
+
assert_equal last_comment, author.post_about_thinking_with_last_comment.last_comment
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_finding_with_includes_on_belongs_to_association_with_same_include_includes_only_once
|
135
|
+
post = posts(:welcome)
|
136
|
+
author = post.author
|
137
|
+
author_address = author.author_address
|
138
|
+
post = assert_queries(3) { Post.find(post.id, :include => {:author_with_address => :author_address}) } # find the post, then find the author, then find the address
|
139
|
+
assert_no_queries do
|
140
|
+
assert_equal author, post.author_with_address
|
141
|
+
assert_equal author_address, post.author_with_address.author_address
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_finding_with_includes_on_null_belongs_to_association_with_same_include_includes_only_once
|
146
|
+
post = posts(:welcome)
|
147
|
+
post.update_attributes!(:author => nil)
|
148
|
+
post = assert_queries(2) { Post.find(post.id, :include => {:author_with_address => :author_address}) } # find the post, then find the author which is null so no query for the address
|
149
|
+
assert_no_queries do
|
150
|
+
assert_equal nil, post.author_with_address
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
114
154
|
def test_loading_from_an_association
|
115
155
|
posts = authors(:david).posts.find(:all, :include => :comments, :order => "posts.id")
|
116
156
|
assert_equal 2, posts.first.comments.size
|
@@ -269,14 +309,23 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
|
269
309
|
end
|
270
310
|
|
271
311
|
def test_eager_with_has_many_through
|
272
|
-
posts_with_comments = people(:michael).posts.find(:all, :include => :comments)
|
273
|
-
posts_with_author = people(:michael).posts.find(:all, :include => :author )
|
274
|
-
posts_with_comments_and_author = people(:michael).posts.find(:all, :include => [ :comments, :author ])
|
312
|
+
posts_with_comments = people(:michael).posts.find(:all, :include => :comments, :order => 'posts.id')
|
313
|
+
posts_with_author = people(:michael).posts.find(:all, :include => :author, :order => 'posts.id')
|
314
|
+
posts_with_comments_and_author = people(:michael).posts.find(:all, :include => [ :comments, :author ], :order => 'posts.id')
|
275
315
|
assert_equal 2, posts_with_comments.inject(0) { |sum, post| sum += post.comments.size }
|
276
316
|
assert_equal authors(:david), assert_no_queries { posts_with_author.first.author }
|
277
317
|
assert_equal authors(:david), assert_no_queries { posts_with_comments_and_author.first.author }
|
278
318
|
end
|
279
319
|
|
320
|
+
def test_eager_with_has_many_through_a_belongs_to_association
|
321
|
+
author = authors(:mary)
|
322
|
+
post = Post.create!(:author => author, :title => "TITLE", :body => "BODY")
|
323
|
+
author.author_favorites.create(:favorite_author_id => 1)
|
324
|
+
author.author_favorites.create(:favorite_author_id => 2)
|
325
|
+
posts_with_author_favorites = author.posts.find(:all, :include => :author_favorites)
|
326
|
+
assert_no_queries { posts_with_author_favorites.first.author_favorites.first.author_id }
|
327
|
+
end
|
328
|
+
|
280
329
|
def test_eager_with_has_many_through_an_sti_join_model
|
281
330
|
author = Author.find(:first, :include => :special_post_comments, :order => 'authors.id')
|
282
331
|
assert_equal [comments(:does_it_hurt)], assert_no_queries { author.special_post_comments }
|
@@ -622,7 +671,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
|
622
671
|
end
|
623
672
|
|
624
673
|
def test_count_with_include
|
625
|
-
if current_adapter?(:
|
674
|
+
if current_adapter?(:SybaseAdapter)
|
626
675
|
assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "len(comments.body) > 15")
|
627
676
|
elsif current_adapter?(:OpenBaseAdapter)
|
628
677
|
assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(FETCHBLOB(comments.body)) > 15")
|