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 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.0) and Driver (0.10.0) (2008/11/06)
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
- 2) The IBM_DB driver can also be built separately (from source) and used in direct API calls.
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.9.5 (mswin32)
47
- 2. ibm_db 0.9.5 (ruby)
48
- 3. ibm_db 0.9.4 (mswin32)
49
- 4. ibm_db 0.9.4 (ruby)
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 IBM_DB_DIR=/opt/ibm/db2/V9.1
79
- $ export IBM_DB_LIB=/opt/ibm/db2/V9.1/lib32
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.9.5 (mswin32)
83
- 2. ibm_db 0.9.5 (ruby)
84
- 3. ibm_db 0.9.4 (ruby)
85
- 4. ibm_db 0.9.4 (mswin32)
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
- $ export IBM_DB_DIR=/opt/ibm/db2/V9.1
148
- $ export IBM_DB_LIB=/opt/ibm/db2/V9.1/lib32
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.yaml
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=test_001.rb
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
- IBM_DB_DIR = (ENV['IBM_DB_DIR'] or
15
- (Dir['/opt/*/db2/*'].sort_by {|f| File.basename(f)}).last )
16
- dir_config('IBM_DB',IBM_DB_DIR)
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', ENV['IBM_DB_LIB']))
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
- Install IBM DB2 Univeral Database
30
+ Follow the steps below and retry
28
31
 
29
- or
32
+ Step 1: - Install IBM DB2 Universal Database Server/Client
30
33
 
31
- If using rake, please set the environment variables
32
- IBM_DB_DIR=/path/to/db2 (eg. /opt/IBM/db2/V9.1)
33
- IBM_DB_LIB=/path/to/db2/lib (eg. /opt/IBM/db2/V9.1/lib32)
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
- or
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.10.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 != SQL_SUCCESS ) {
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
- case key
131
- when :app_user # Set connection's user info
132
- conn_options[IBM_DB::SQL_ATTR_INFO_USERID] = value
133
- when :account # Set connection's account info
134
- conn_options[IBM_DB::SQL_ATTR_INFO_ACCTSTR] = value
135
- when :application # Set connection's application info
136
- conn_options[IBM_DB::SQL_ATTR_INFO_APPLNAME] = value
137
- when :workstation # Set connection's workstation info
138
- conn_options[IBM_DB::SQL_ATTR_INFO_WRKSTNNAME] = value
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: 'ibm_db' // IBM_DB Adapter name
359
- # username: 'db2user' // data server (database) user
360
- # password: 'secret' // data server (database) password
361
- # database: 'ARUNIT' // remote database name (or catalog entry alias)
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: 'rails123' // name space qualifier
364
- # account: 'tester' // OS account (client workstation)
365
- # app_user: 'test11' // authenticated application user
366
- # application: 'rtests' // application name
367
- # workstation: 'plato' // client workstation name
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: 'socrates' // fully qualified hostname or IP address
370
- # port: '50000' // data server TCP/IP port number
371
- # security: 'SSL' // optional parameter enabling SSL encryption -
372
- # // - Available only from CLI version V95fp2 and above
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 = connection
389
- @conn_options = conn_options
390
- @database = config[:database]
391
- @username = config[:username]
392
- @password = config[: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 = config[:host]
395
- @port = config[:port] || 50000 # default port
411
+ @host = config[:host]
412
+ @port = config[:port] || 50000 # default port
396
413
  end
397
- @schema = config[:schema]
398
- @security = config[:security] || nil
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 = conn_options[:app_user] if conn_options.has_key?(:app_user)
402
- @account = conn_options[:account] if conn_options.has_key?(:account)
403
- @application = conn_options[:application] if conn_options.has_key?(:application)
404
- @workstation = conn_options[:workstation] if conn_options.has_key?(: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
@@ -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?(:SQLServerAdapter, :SybaseAdapter)
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")