ibm_db 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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")