ibm_db 0.4.0 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +19 -9
- data/README +29 -20
- data/ext/extconf.rb +55 -50
- data/ext/ibm_db.c +6267 -6259
- data/ext/ruby_ibm_db.h +164 -164
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +167 -142
- data/lib/active_record/vendor/db2-i5-zOS.yaml +68 -68
- data/lib/linux32/ibm_db.so +0 -0
- data/test/adapter_test.rb +128 -0
- data/test/base_test.rb +1579 -0
- data/test/{activerecord → connections}/native_ibm_db/connection.rb +6 -7
- data/test/fixtures/db_definitions/i5/ibm_db.drop.sql +32 -0
- data/test/fixtures/db_definitions/i5/ibm_db.sql +232 -0
- data/test/fixtures/db_definitions/i5/ibm_db2.drop.sql +2 -0
- data/test/fixtures/db_definitions/i5/ibm_db2.sql +5 -0
- data/test/fixtures/db_definitions/luw/ibm_db.drop.sql +31 -0
- data/test/fixtures/db_definitions/luw/ibm_db.sql +226 -0
- data/test/fixtures/db_definitions/luw/ibm_db2.drop.sql +2 -0
- data/test/fixtures/db_definitions/luw/ibm_db2.sql +5 -0
- data/test/fixtures/db_definitions/zOS/ibm_db.drop.sql +32 -0
- data/test/fixtures/db_definitions/zOS/ibm_db.sql +284 -0
- data/test/fixtures/db_definitions/zOS/ibm_db2.drop.sql +2 -0
- data/test/fixtures/db_definitions/zOS/ibm_db2.sql +7 -0
- data/test/locking_test.rb +190 -0
- data/test/migration_test.rb +779 -0
- metadata +39 -17
data/ext/ruby_ibm_db.h
CHANGED
@@ -1,164 +1,164 @@
|
|
1
|
-
/*
|
2
|
-
+----------------------------------------------------------------------+
|
3
|
-
| Licensed Materials - Property of IBM |
|
4
|
-
| |
|
5
|
-
| (C) Copyright IBM Corporation 2007.
|
6
|
-
+----------------------------------------------------------------------+
|
7
|
-
| Authors: Sushant Koduru, Lynh Nguyen, Kanchana Padmanabhan, |
|
8
|
-
| Dan Scott, Helmut Tessarek, Kellen Bombardier, Sam Ruby |
|
9
|
-
+----------------------------------------------------------------------+
|
10
|
-
*/
|
11
|
-
|
12
|
-
#ifndef RUBY_IBM_DB_H
|
13
|
-
#define RUBY_IBM_DB_H
|
14
|
-
|
15
|
-
#include <stdio.h>
|
16
|
-
#include <string.h>
|
17
|
-
#include <stdlib.h>
|
18
|
-
#include <sqlcli1.h>
|
19
|
-
|
20
|
-
#ifndef SQL_XML
|
21
|
-
#define SQL_XML -370
|
22
|
-
#endif
|
23
|
-
|
24
|
-
#ifndef SQL_ATTR_REPLACE_QUOTED_LITERALS
|
25
|
-
#define SQL_ATTR_REPLACE_QUOTED_LITERALS 116
|
26
|
-
#endif
|
27
|
-
|
28
|
-
#ifdef _WIN32
|
29
|
-
#define RUBY_IBM_DB_API __declspec(dllexport)
|
30
|
-
#else
|
31
|
-
#define RUBY_IBM_DB_API
|
32
|
-
#endif
|
33
|
-
|
34
|
-
/* strlen(" SQLCODE=") added in */
|
35
|
-
#define DB2_MAX_ERR_MSG_LEN (SQL_MAX_MESSAGE_LENGTH + SQL_SQLSTATE_SIZE + 10)
|
36
|
-
|
37
|
-
/* Used in _ruby_parse_options */
|
38
|
-
#define DB2_ERRMSG 1
|
39
|
-
#define DB2_ERR 2
|
40
|
-
|
41
|
-
/* DB2 instance environment variable */
|
42
|
-
#define DB2_VAR_INSTANCE "DB2INSTANCE="
|
43
|
-
|
44
|
-
/******** Makes code compatible with the options used by the user */
|
45
|
-
#define BINARY 1
|
46
|
-
#define CONVERT 2
|
47
|
-
#define PASSTHRU 3
|
48
|
-
#define PARAM_FILE 11
|
49
|
-
|
50
|
-
#ifdef PASE
|
51
|
-
#define SQL_IS_INTEGER 0
|
52
|
-
#define SQL_BEST_ROWID 0
|
53
|
-
#define SQLLEN long
|
54
|
-
#define SQLFLOAT double
|
55
|
-
#endif
|
56
|
-
|
57
|
-
/*fetch*/
|
58
|
-
#define FETCH_INDEX 0x01
|
59
|
-
#define FETCH_ASSOC 0x02
|
60
|
-
#define FETCH_BOTH 0x03
|
61
|
-
|
62
|
-
/* Change column case */
|
63
|
-
#define ATTR_CASE 3271982
|
64
|
-
#define CASE_NATURAL 0
|
65
|
-
#define CASE_LOWER 1
|
66
|
-
#define CASE_UPPER 2
|
67
|
-
|
68
|
-
/* maximum sizes */
|
69
|
-
#define USERID_LEN 16
|
70
|
-
#define ACCTSTR_LEN 200
|
71
|
-
#define APPLNAME_LEN 32
|
72
|
-
#define WRKSTNNAME_LEN 18
|
73
|
-
|
74
|
-
void Init_ibm_db();
|
75
|
-
|
76
|
-
VALUE ibm_db_connect(int argc, VALUE *argv, VALUE self);
|
77
|
-
VALUE ibm_db_commit(int argc, VALUE *argv, VALUE self);
|
78
|
-
VALUE ibm_db_pconnect(int argc, VALUE *argv, VALUE self);
|
79
|
-
VALUE ibm_db_autocommit(int argc, VALUE *argv, VALUE self);
|
80
|
-
VALUE ibm_db_bind_param(int argc, VALUE *argv, VALUE self);
|
81
|
-
VALUE ibm_db_close(int argc, VALUE *argv, VALUE self);
|
82
|
-
VALUE ibm_db_columnprivileges(int argc, VALUE *argv, VALUE self);
|
83
|
-
VALUE ibm_db_column_privileges(int argc, VALUE *argv, VALUE self);
|
84
|
-
VALUE ibm_db_columns(int argc, VALUE *argv, VALUE self);
|
85
|
-
VALUE ibm_db_foreignkeys(int argc, VALUE *argv, VALUE self);
|
86
|
-
VALUE ibm_db_foreign_keys(int argc, VALUE *argv, VALUE self);
|
87
|
-
VALUE ibm_db_primarykeys(int argc, VALUE *argv, VALUE self);
|
88
|
-
VALUE ibm_db_primary_keys(int argc, VALUE *argv, VALUE self);
|
89
|
-
VALUE ibm_db_procedure_columns(int argc, VALUE *argv, VALUE self);
|
90
|
-
VALUE ibm_db_procedures(int argc, VALUE *argv, VALUE self);
|
91
|
-
VALUE ibm_db_specialcolumns(int argc, VALUE *argv, VALUE self);
|
92
|
-
VALUE ibm_db_special_columns(int argc, VALUE *argv, VALUE self);
|
93
|
-
VALUE ibm_db_statistics(int argc, VALUE *argv, VALUE self);
|
94
|
-
VALUE ibm_db_tableprivileges(int argc, VALUE *argv, VALUE self);
|
95
|
-
VALUE ibm_db_table_privileges(int argc, VALUE *argv, VALUE self);
|
96
|
-
VALUE ibm_db_tables(int argc, VALUE *argv, VALUE self);
|
97
|
-
VALUE ibm_db_commit(int argc, VALUE *argv, VALUE self);
|
98
|
-
VALUE ibm_db_exec(int argc, VALUE *argv, VALUE self);
|
99
|
-
VALUE ibm_db_prepare(int argc, VALUE *argv, VALUE self);
|
100
|
-
VALUE ibm_db_execute(int argc, VALUE *argv, VALUE self);
|
101
|
-
VALUE ibm_db_conn_errormsg(int argc, VALUE *argv, VALUE self);
|
102
|
-
VALUE ibm_db_stmt_errormsg(int argc, VALUE *argv, VALUE self);
|
103
|
-
VALUE ibm_db_conn_error(int argc, VALUE *argv, VALUE self);
|
104
|
-
VALUE ibm_db_stmt_error(int argc, VALUE *argv, VALUE self);
|
105
|
-
VALUE ibm_db_next_result(int argc, VALUE *argv, VALUE self);
|
106
|
-
VALUE ibm_db_num_fields(int argc, VALUE *argv, VALUE self);
|
107
|
-
VALUE ibm_db_num_rows(int argc, VALUE *argv, VALUE self);
|
108
|
-
VALUE ibm_db_field_name(int argc, VALUE *argv, VALUE self);
|
109
|
-
VALUE ibm_db_field_display_size(int argc, VALUE *argv, VALUE self);
|
110
|
-
VALUE ibm_db_field_num(int argc, VALUE *argv, VALUE self);
|
111
|
-
VALUE ibm_db_field_precision(int argc, VALUE *argv, VALUE self);
|
112
|
-
VALUE ibm_db_field_scale(int argc, VALUE *argv, VALUE self);
|
113
|
-
VALUE ibm_db_field_type(int argc, VALUE *argv, VALUE self);
|
114
|
-
VALUE ibm_db_field_width(int argc, VALUE *argv, VALUE self);
|
115
|
-
VALUE ibm_db_cursor_type(int argc, VALUE *argv, VALUE self);
|
116
|
-
VALUE ibm_db_rollback(int argc, VALUE *argv, VALUE self);
|
117
|
-
VALUE ibm_db_free_stmt(int argc, VALUE *argv, VALUE self);
|
118
|
-
VALUE ibm_db_result(int argc, VALUE *argv, VALUE self);
|
119
|
-
VALUE ibm_db_fetch_row(int argc, VALUE *argv, VALUE self);
|
120
|
-
VALUE ibm_db_fetch_assoc(int argc, VALUE *argv, VALUE self);
|
121
|
-
VALUE ibm_db_fetch_array(int argc, VALUE *argv, VALUE self);
|
122
|
-
VALUE ibm_db_fetch_both(int argc, VALUE *argv, VALUE self);
|
123
|
-
VALUE ibm_db_result_all(int argc, VALUE *argv, VALUE self);
|
124
|
-
VALUE ibm_db_free_result(int argc, VALUE *argv, VALUE self);
|
125
|
-
VALUE ibm_db_set_option(int argc, VALUE *argv, VALUE self);
|
126
|
-
VALUE ibm_db_setoption(int argc, VALUE *argv, VALUE self);
|
127
|
-
VALUE ibm_db_get_option(int argc, VALUE *argv, VALUE self);
|
128
|
-
VALUE ibm_db_getoption(int argc, VALUE *argv, VALUE self);
|
129
|
-
VALUE ibm_db_fetch_object(int argc, VALUE *argv, VALUE self);
|
130
|
-
VALUE ibm_db_server_info(int argc, VALUE *argv, VALUE self);
|
131
|
-
VALUE ibm_db_client_info(int argc, VALUE *argv, VALUE self);
|
132
|
-
VALUE ibm_db_active(int argc, VALUE *argv, VALUE self);
|
133
|
-
|
134
|
-
/*
|
135
|
-
Declare any global variables you may need between the BEGIN
|
136
|
-
and END macros here:
|
137
|
-
*/
|
138
|
-
struct _ibm_db_globals {
|
139
|
-
int bin_mode;
|
140
|
-
char __ruby_conn_err_msg[DB2_MAX_ERR_MSG_LEN];
|
141
|
-
char __ruby_conn_err_state[SQL_SQLSTATE_SIZE + 1];
|
142
|
-
char __ruby_stmt_err_msg[DB2_MAX_ERR_MSG_LEN];
|
143
|
-
char __ruby_stmt_err_state[SQL_SQLSTATE_SIZE + 1];
|
144
|
-
#ifdef PASE /* i5/OS ease of use turn off commit */
|
145
|
-
long i5_allow_commit;
|
146
|
-
#endif /* PASE */
|
147
|
-
};
|
148
|
-
|
149
|
-
/*
|
150
|
-
TODO: make this threadsafe
|
151
|
-
*/
|
152
|
-
|
153
|
-
#define IBM_DB_G(v) (ibm_db_globals->v)
|
154
|
-
|
155
|
-
#endif /* RUBY_IBM_DB_H */
|
156
|
-
|
157
|
-
|
158
|
-
/*
|
159
|
-
* Local variables:
|
160
|
-
* tab-width: 4
|
161
|
-
* c-basic-offset: 4
|
162
|
-
* indent-tabs-mode: t
|
163
|
-
* End:
|
164
|
-
*/
|
1
|
+
/*
|
2
|
+
+----------------------------------------------------------------------+
|
3
|
+
| Licensed Materials - Property of IBM |
|
4
|
+
| |
|
5
|
+
| (C) Copyright IBM Corporation 2006, 2007. |
|
6
|
+
+----------------------------------------------------------------------+
|
7
|
+
| Authors: Sushant Koduru, Lynh Nguyen, Kanchana Padmanabhan, |
|
8
|
+
| Dan Scott, Helmut Tessarek, Kellen Bombardier, Sam Ruby |
|
9
|
+
+----------------------------------------------------------------------+
|
10
|
+
*/
|
11
|
+
|
12
|
+
#ifndef RUBY_IBM_DB_H
|
13
|
+
#define RUBY_IBM_DB_H
|
14
|
+
|
15
|
+
#include <stdio.h>
|
16
|
+
#include <string.h>
|
17
|
+
#include <stdlib.h>
|
18
|
+
#include <sqlcli1.h>
|
19
|
+
|
20
|
+
#ifndef SQL_XML
|
21
|
+
#define SQL_XML -370
|
22
|
+
#endif
|
23
|
+
|
24
|
+
#ifndef SQL_ATTR_REPLACE_QUOTED_LITERALS
|
25
|
+
#define SQL_ATTR_REPLACE_QUOTED_LITERALS 116
|
26
|
+
#endif
|
27
|
+
|
28
|
+
#ifdef _WIN32
|
29
|
+
#define RUBY_IBM_DB_API __declspec(dllexport)
|
30
|
+
#else
|
31
|
+
#define RUBY_IBM_DB_API
|
32
|
+
#endif
|
33
|
+
|
34
|
+
/* strlen(" SQLCODE=") added in */
|
35
|
+
#define DB2_MAX_ERR_MSG_LEN (SQL_MAX_MESSAGE_LENGTH + SQL_SQLSTATE_SIZE + 10)
|
36
|
+
|
37
|
+
/* Used in _ruby_parse_options */
|
38
|
+
#define DB2_ERRMSG 1
|
39
|
+
#define DB2_ERR 2
|
40
|
+
|
41
|
+
/* DB2 instance environment variable */
|
42
|
+
#define DB2_VAR_INSTANCE "DB2INSTANCE="
|
43
|
+
|
44
|
+
/******** Makes code compatible with the options used by the user */
|
45
|
+
#define BINARY 1
|
46
|
+
#define CONVERT 2
|
47
|
+
#define PASSTHRU 3
|
48
|
+
#define PARAM_FILE 11
|
49
|
+
|
50
|
+
#ifdef PASE
|
51
|
+
#define SQL_IS_INTEGER 0
|
52
|
+
#define SQL_BEST_ROWID 0
|
53
|
+
#define SQLLEN long
|
54
|
+
#define SQLFLOAT double
|
55
|
+
#endif
|
56
|
+
|
57
|
+
/*fetch*/
|
58
|
+
#define FETCH_INDEX 0x01
|
59
|
+
#define FETCH_ASSOC 0x02
|
60
|
+
#define FETCH_BOTH 0x03
|
61
|
+
|
62
|
+
/* Change column case */
|
63
|
+
#define ATTR_CASE 3271982
|
64
|
+
#define CASE_NATURAL 0
|
65
|
+
#define CASE_LOWER 1
|
66
|
+
#define CASE_UPPER 2
|
67
|
+
|
68
|
+
/* maximum sizes */
|
69
|
+
#define USERID_LEN 16
|
70
|
+
#define ACCTSTR_LEN 200
|
71
|
+
#define APPLNAME_LEN 32
|
72
|
+
#define WRKSTNNAME_LEN 18
|
73
|
+
|
74
|
+
void Init_ibm_db();
|
75
|
+
|
76
|
+
VALUE ibm_db_connect(int argc, VALUE *argv, VALUE self);
|
77
|
+
VALUE ibm_db_commit(int argc, VALUE *argv, VALUE self);
|
78
|
+
VALUE ibm_db_pconnect(int argc, VALUE *argv, VALUE self);
|
79
|
+
VALUE ibm_db_autocommit(int argc, VALUE *argv, VALUE self);
|
80
|
+
VALUE ibm_db_bind_param(int argc, VALUE *argv, VALUE self);
|
81
|
+
VALUE ibm_db_close(int argc, VALUE *argv, VALUE self);
|
82
|
+
VALUE ibm_db_columnprivileges(int argc, VALUE *argv, VALUE self);
|
83
|
+
VALUE ibm_db_column_privileges(int argc, VALUE *argv, VALUE self);
|
84
|
+
VALUE ibm_db_columns(int argc, VALUE *argv, VALUE self);
|
85
|
+
VALUE ibm_db_foreignkeys(int argc, VALUE *argv, VALUE self);
|
86
|
+
VALUE ibm_db_foreign_keys(int argc, VALUE *argv, VALUE self);
|
87
|
+
VALUE ibm_db_primarykeys(int argc, VALUE *argv, VALUE self);
|
88
|
+
VALUE ibm_db_primary_keys(int argc, VALUE *argv, VALUE self);
|
89
|
+
VALUE ibm_db_procedure_columns(int argc, VALUE *argv, VALUE self);
|
90
|
+
VALUE ibm_db_procedures(int argc, VALUE *argv, VALUE self);
|
91
|
+
VALUE ibm_db_specialcolumns(int argc, VALUE *argv, VALUE self);
|
92
|
+
VALUE ibm_db_special_columns(int argc, VALUE *argv, VALUE self);
|
93
|
+
VALUE ibm_db_statistics(int argc, VALUE *argv, VALUE self);
|
94
|
+
VALUE ibm_db_tableprivileges(int argc, VALUE *argv, VALUE self);
|
95
|
+
VALUE ibm_db_table_privileges(int argc, VALUE *argv, VALUE self);
|
96
|
+
VALUE ibm_db_tables(int argc, VALUE *argv, VALUE self);
|
97
|
+
VALUE ibm_db_commit(int argc, VALUE *argv, VALUE self);
|
98
|
+
VALUE ibm_db_exec(int argc, VALUE *argv, VALUE self);
|
99
|
+
VALUE ibm_db_prepare(int argc, VALUE *argv, VALUE self);
|
100
|
+
VALUE ibm_db_execute(int argc, VALUE *argv, VALUE self);
|
101
|
+
VALUE ibm_db_conn_errormsg(int argc, VALUE *argv, VALUE self);
|
102
|
+
VALUE ibm_db_stmt_errormsg(int argc, VALUE *argv, VALUE self);
|
103
|
+
VALUE ibm_db_conn_error(int argc, VALUE *argv, VALUE self);
|
104
|
+
VALUE ibm_db_stmt_error(int argc, VALUE *argv, VALUE self);
|
105
|
+
VALUE ibm_db_next_result(int argc, VALUE *argv, VALUE self);
|
106
|
+
VALUE ibm_db_num_fields(int argc, VALUE *argv, VALUE self);
|
107
|
+
VALUE ibm_db_num_rows(int argc, VALUE *argv, VALUE self);
|
108
|
+
VALUE ibm_db_field_name(int argc, VALUE *argv, VALUE self);
|
109
|
+
VALUE ibm_db_field_display_size(int argc, VALUE *argv, VALUE self);
|
110
|
+
VALUE ibm_db_field_num(int argc, VALUE *argv, VALUE self);
|
111
|
+
VALUE ibm_db_field_precision(int argc, VALUE *argv, VALUE self);
|
112
|
+
VALUE ibm_db_field_scale(int argc, VALUE *argv, VALUE self);
|
113
|
+
VALUE ibm_db_field_type(int argc, VALUE *argv, VALUE self);
|
114
|
+
VALUE ibm_db_field_width(int argc, VALUE *argv, VALUE self);
|
115
|
+
VALUE ibm_db_cursor_type(int argc, VALUE *argv, VALUE self);
|
116
|
+
VALUE ibm_db_rollback(int argc, VALUE *argv, VALUE self);
|
117
|
+
VALUE ibm_db_free_stmt(int argc, VALUE *argv, VALUE self);
|
118
|
+
VALUE ibm_db_result(int argc, VALUE *argv, VALUE self);
|
119
|
+
VALUE ibm_db_fetch_row(int argc, VALUE *argv, VALUE self);
|
120
|
+
VALUE ibm_db_fetch_assoc(int argc, VALUE *argv, VALUE self);
|
121
|
+
VALUE ibm_db_fetch_array(int argc, VALUE *argv, VALUE self);
|
122
|
+
VALUE ibm_db_fetch_both(int argc, VALUE *argv, VALUE self);
|
123
|
+
VALUE ibm_db_result_all(int argc, VALUE *argv, VALUE self);
|
124
|
+
VALUE ibm_db_free_result(int argc, VALUE *argv, VALUE self);
|
125
|
+
VALUE ibm_db_set_option(int argc, VALUE *argv, VALUE self);
|
126
|
+
VALUE ibm_db_setoption(int argc, VALUE *argv, VALUE self);
|
127
|
+
VALUE ibm_db_get_option(int argc, VALUE *argv, VALUE self);
|
128
|
+
VALUE ibm_db_getoption(int argc, VALUE *argv, VALUE self);
|
129
|
+
VALUE ibm_db_fetch_object(int argc, VALUE *argv, VALUE self);
|
130
|
+
VALUE ibm_db_server_info(int argc, VALUE *argv, VALUE self);
|
131
|
+
VALUE ibm_db_client_info(int argc, VALUE *argv, VALUE self);
|
132
|
+
VALUE ibm_db_active(int argc, VALUE *argv, VALUE self);
|
133
|
+
|
134
|
+
/*
|
135
|
+
Declare any global variables you may need between the BEGIN
|
136
|
+
and END macros here:
|
137
|
+
*/
|
138
|
+
struct _ibm_db_globals {
|
139
|
+
int bin_mode;
|
140
|
+
char __ruby_conn_err_msg[DB2_MAX_ERR_MSG_LEN];
|
141
|
+
char __ruby_conn_err_state[SQL_SQLSTATE_SIZE + 1];
|
142
|
+
char __ruby_stmt_err_msg[DB2_MAX_ERR_MSG_LEN];
|
143
|
+
char __ruby_stmt_err_state[SQL_SQLSTATE_SIZE + 1];
|
144
|
+
#ifdef PASE /* i5/OS ease of use turn off commit */
|
145
|
+
long i5_allow_commit;
|
146
|
+
#endif /* PASE */
|
147
|
+
};
|
148
|
+
|
149
|
+
/*
|
150
|
+
TODO: make this threadsafe
|
151
|
+
*/
|
152
|
+
|
153
|
+
#define IBM_DB_G(v) (ibm_db_globals->v)
|
154
|
+
|
155
|
+
#endif /* RUBY_IBM_DB_H */
|
156
|
+
|
157
|
+
|
158
|
+
/*
|
159
|
+
* Local variables:
|
160
|
+
* tab-width: 4
|
161
|
+
* c-basic-offset: 4
|
162
|
+
* indent-tabs-mode: t
|
163
|
+
* End:
|
164
|
+
*/
|
@@ -42,7 +42,7 @@ module ActiveRecord
|
|
42
42
|
end
|
43
43
|
|
44
44
|
update_query << ") = "
|
45
|
-
#
|
45
|
+
# IBM_DB accepts 'SET (column) = NULL' but not (NULL),
|
46
46
|
# therefore the sql needs to be changed for a single NULL field.
|
47
47
|
if params.size==1 && params[0] == 'NULL'
|
48
48
|
update_query << "NULL"
|
@@ -72,7 +72,7 @@ module ActiveRecord
|
|
72
72
|
begin
|
73
73
|
require 'ibm_db' unless defined? IBM_DB
|
74
74
|
rescue LoadError
|
75
|
-
raise LoadError, "Failed to load
|
75
|
+
raise LoadError, "Failed to load IBM_DB Ruby driver."
|
76
76
|
end
|
77
77
|
|
78
78
|
# Converts all +config+ keys to symbols
|
@@ -104,7 +104,7 @@ module ActiveRecord
|
|
104
104
|
# Retrieve database objects fields in lowercase
|
105
105
|
conn_options = {IBM_DB::ATTR_CASE => IBM_DB::CASE_LOWER}
|
106
106
|
# Set connection's user info
|
107
|
-
conn_options[:
|
107
|
+
conn_options[:app_user] = config[:app_user].to_s if config.has_key?(:app_user)
|
108
108
|
# Set connection's account info
|
109
109
|
conn_options[:account] = config[:account].to_s if config.has_key?(:account)
|
110
110
|
# Set connection's application info
|
@@ -136,7 +136,7 @@ module ActiveRecord
|
|
136
136
|
ConnectionAdapters::IBM_DBAdapter.new(connection, logger, config, conn_options)
|
137
137
|
else
|
138
138
|
# If the connection failed, it raises a Runtime error
|
139
|
-
raise "Failed to connect to the #{database} due to: #{IBM_DB::conn_errormsg}"
|
139
|
+
raise "Failed to connect to the [#{database}] due to: #{IBM_DB::conn_errormsg}"
|
140
140
|
end
|
141
141
|
end # method self.ibm_db_connection
|
142
142
|
end # class Base
|
@@ -159,7 +159,7 @@ module ActiveRecord
|
|
159
159
|
end
|
160
160
|
|
161
161
|
private
|
162
|
-
# Mapping IBM
|
162
|
+
# Mapping IBM data servers SQL datatypes to Ruby data types
|
163
163
|
def simplified_type(field_type)
|
164
164
|
case field_type
|
165
165
|
# if +field_type+ contains 'for bit data' handle it as a binary
|
@@ -189,40 +189,37 @@ module ActiveRecord
|
|
189
189
|
:string
|
190
190
|
when /boolean/i
|
191
191
|
:boolean
|
192
|
+
when /rowid/i # rowid is a supported datatype on z/OS and i/5
|
193
|
+
:rowid
|
192
194
|
end
|
193
|
-
|
194
195
|
end # method simplified_type
|
195
196
|
end #class IBM_DBColumn
|
196
197
|
|
197
198
|
|
198
|
-
# The IBM_DB Adapter requires the native Ruby
|
199
|
-
#
|
200
|
-
#
|
201
|
-
#
|
202
|
-
#
|
203
|
-
#
|
204
|
-
#
|
205
|
-
#
|
206
|
-
#
|
207
|
-
# schema:
|
208
|
-
#
|
209
|
-
#
|
210
|
-
#
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
#
|
219
|
-
# 'SAMPLE' is the database alias as it appears in the local IBM DB catalog
|
220
|
-
# Once you pick the type of connection you want to use, you need to fill-in all the fields above, as shown in the example.
|
221
|
-
# The current version allows you to set only one schema. If you don't specify a schema, the username is used as a schema.
|
199
|
+
# The IBM_DB Adapter requires the native Ruby driver (ibm_db)
|
200
|
+
# for IBM data servers (ibm_db.so).
|
201
|
+
# +config+ the hash passed as an initializer argument content:
|
202
|
+
# == mandatory parameters
|
203
|
+
# adapter: 'ibm_db' // IBM_DB Adapter name
|
204
|
+
# username: 'db2user' // data server (database) user
|
205
|
+
# password: 'secret' // data server (database) password
|
206
|
+
# database: 'ARUNIT' // remote database name (or catalog entry alias)
|
207
|
+
# == optional (highly recommended for data server auditing and monitoring purposes)
|
208
|
+
# schema: 'rails123' // name space qualifier
|
209
|
+
# account: 'tester' // OS account (client workstation)
|
210
|
+
# app_user: 'test11' // authenticated application user
|
211
|
+
# application: 'rtests' // application name
|
212
|
+
# workstation: 'plato' // client workstation name
|
213
|
+
# == remote TCP/IP connection (required when no local database catalog entry available)
|
214
|
+
# host: 'socrates' // fully qualified hostname or IP address
|
215
|
+
# port: '50000' // data server TCP/IP port number
|
216
|
+
#
|
217
|
+
# When schema is not specified, the username value is used instead.
|
218
|
+
#
|
222
219
|
class IBM_DBAdapter < AbstractAdapter
|
223
220
|
attr_reader :connection
|
224
221
|
attr_accessor :sql
|
225
|
-
attr_reader :schema, :
|
222
|
+
attr_reader :schema, :app_user, :account, :application, :workstation
|
226
223
|
|
227
224
|
# Name of the adapter
|
228
225
|
def adapter_name
|
@@ -231,6 +228,8 @@ module ActiveRecord
|
|
231
228
|
|
232
229
|
def initialize(connection, logger, config, conn_options)
|
233
230
|
# Caching database connection configuration (+connect+ or +reconnect+ support)
|
231
|
+
@connection = connection
|
232
|
+
@conn_options = conn_options
|
234
233
|
@database = config[:database]
|
235
234
|
@username = config[:username]
|
236
235
|
@password = config[:password]
|
@@ -241,14 +240,14 @@ module ActiveRecord
|
|
241
240
|
@schema = config[:schema]
|
242
241
|
|
243
242
|
# Caching database connection options (auditing and billing support)
|
244
|
-
@
|
243
|
+
@app_user = conn_options[:app_user] if conn_options.has_key?(:app_user)
|
245
244
|
@account = conn_options[:account] if conn_options.has_key?(:account)
|
246
245
|
@application = conn_options[:application] if conn_options.has_key?(:application)
|
247
246
|
@workstation = conn_options[:workstation] if conn_options.has_key?(:workstation)
|
248
247
|
|
249
248
|
# Calls the parent class +ConnectionAdapters+' initializer
|
250
249
|
# which sets @connection, @logger, @runtime and @last_verification
|
251
|
-
super(connection, logger)
|
250
|
+
super(@connection, logger)
|
252
251
|
|
253
252
|
if @connection
|
254
253
|
server_info = IBM_DB::server_info( @connection )
|
@@ -274,27 +273,29 @@ module ActiveRecord
|
|
274
273
|
@servertype = IBM_DB2_I5.new(@connection, self)
|
275
274
|
end
|
276
275
|
end
|
277
|
-
|
278
276
|
# Executes the +set schema+ statement using the schema identifier provided
|
279
|
-
|
277
|
+
@servertype.set_schema(@schema) if @schema && @schema != @username
|
280
278
|
end
|
281
279
|
|
280
|
+
# Optional connection attribute: database name space qualifier
|
282
281
|
def schema=(name)
|
283
282
|
unless name == @schema
|
284
283
|
@schema = name
|
285
|
-
|
284
|
+
@servertype.set_schema(@schema)
|
286
285
|
end
|
287
286
|
end
|
288
287
|
|
289
|
-
|
290
|
-
|
288
|
+
# Optional connection attribute: authenticated application user
|
289
|
+
def app_user=(name)
|
290
|
+
unless name == @app_user
|
291
291
|
option = {IBM_DB::SQL_ATTR_INFO_USERID => "#{name}"}
|
292
292
|
if IBM_DB::set_option( @connection, option, 1 )
|
293
|
-
@
|
293
|
+
@app_user = IBM_DB::get_option( @connection, IBM_DB::SQL_ATTR_INFO_USERID )
|
294
294
|
end
|
295
295
|
end
|
296
296
|
end
|
297
297
|
|
298
|
+
# Optional connection attribute: OS account (client workstation)
|
298
299
|
def account=(name)
|
299
300
|
unless name == @account
|
300
301
|
option = {IBM_DB::SQL_ATTR_INFO_ACCTSTR => "#{name}"}
|
@@ -304,6 +305,7 @@ module ActiveRecord
|
|
304
305
|
end
|
305
306
|
end
|
306
307
|
|
308
|
+
# Optional connection attribute: application name
|
307
309
|
def application=(name)
|
308
310
|
unless name == @application
|
309
311
|
option = {IBM_DB::SQL_ATTR_INFO_APPLNAME => "#{name}"}
|
@@ -313,6 +315,7 @@ module ActiveRecord
|
|
313
315
|
end
|
314
316
|
end
|
315
317
|
|
318
|
+
# Optional connection attribute: client workstation name
|
316
319
|
def workstation=(name)
|
317
320
|
unless name == @workstation
|
318
321
|
option = {IBM_DB::SQL_ATTR_INFO_WRKSTNNAME => "#{name}"}
|
@@ -322,9 +325,9 @@ module ActiveRecord
|
|
322
325
|
end
|
323
326
|
end
|
324
327
|
|
325
|
-
# This adapter supports migrations
|
326
|
-
#
|
327
|
-
#
|
328
|
+
# This adapter supports migrations.
|
329
|
+
# Current limitations: +remove_column+ is not currently supported
|
330
|
+
# while DB2 for zOS does not support +rename_column+
|
328
331
|
def supports_migrations?
|
329
332
|
true
|
330
333
|
end
|
@@ -341,6 +344,8 @@ module ActiveRecord
|
|
341
344
|
# Tests the connection status
|
342
345
|
def active?
|
343
346
|
IBM_DB::active @connection
|
347
|
+
rescue
|
348
|
+
false
|
344
349
|
end
|
345
350
|
|
346
351
|
# Private method used by +reconnect!+.
|
@@ -358,7 +363,7 @@ module ActiveRecord
|
|
358
363
|
end
|
359
364
|
# Sets the schema if different from default (username)
|
360
365
|
if @schema && @schema != @username
|
361
|
-
|
366
|
+
@servertype.set_schema(@schema)
|
362
367
|
end
|
363
368
|
end
|
364
369
|
private :connect
|
@@ -388,45 +393,28 @@ module ActiveRecord
|
|
388
393
|
@servertype.create_index_after_table(name, self)
|
389
394
|
end
|
390
395
|
|
391
|
-
# DB2 throws an error SQL0214N An expression in the ORDER BY
|
392
|
-
# clause in the following position, or starting with "UPPER..."
|
393
|
-
# in the "ORDER BY" clause is not valid. Reason code = "2".
|
394
|
-
# SQLSTATE=42822
|
395
|
-
# If the order_by columns do not match the select columns, we change
|
396
|
-
# the select columns.
|
397
|
-
def distinct(columns, order_by)
|
398
|
-
if !order_by.nil? && !order_by.empty?
|
399
|
-
order_by_columns = order_by.upcase.split(',').collect! { |e| (e.split).first }
|
400
|
-
distinct_sql = (columns.upcase.split(',') + order_by_columns).uniq
|
401
|
-
distinct_sql.collect! {|e| e + ", " }
|
402
|
-
return "DISTINCT #{distinct_sql.to_s.strip.chop}"
|
403
|
-
else
|
404
|
-
return "DISTINCT #{columns}"
|
405
|
-
end
|
406
|
-
end
|
407
|
-
|
408
396
|
# Returns an array of hashes with the column names as keys and
|
409
397
|
# column values as values. +sql+ is the select query, and +name+ is an optional description for logging
|
410
398
|
def select_all(sql, name = nil)
|
411
|
-
# Replaces {"= NULL" with "IS NULL"} OR {"IN (NULL)" with "IS NULL"}
|
412
|
-
sql.gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, "IS NULL" )
|
413
|
-
|
399
|
+
# Replaces {"= NULL" with " IS NULL"} OR {"IN (NULL)" with " IS NULL"}
|
400
|
+
sql.gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" )
|
401
|
+
|
414
402
|
results = []
|
415
403
|
# Invokes the method +execute+ in order to log and execute the sql instructions
|
416
404
|
# and get a IBM_DB::Statement from which is possible to fetch the results
|
417
405
|
if stmt = execute(sql, name)
|
418
406
|
begin
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
407
|
+
# Fetches all the results available. IBM_DB::fetch_assoc(stmt) returns
|
408
|
+
# an hash for each single record.
|
409
|
+
# The loop stops when there aren't any more valid records to fetch
|
410
|
+
while single_hash = IBM_DB::fetch_assoc(stmt)
|
423
411
|
# Add the record to the +results+ array
|
424
412
|
results << single_hash
|
425
|
-
|
413
|
+
end
|
426
414
|
ensure
|
427
|
-
|
428
|
-
|
429
|
-
|
415
|
+
# Ensures to free the resources associated with the statement
|
416
|
+
IBM_DB::free_result stmt
|
417
|
+
end
|
430
418
|
end
|
431
419
|
# The array of record hashes is returned
|
432
420
|
results
|
@@ -450,30 +438,41 @@ module ActiveRecord
|
|
450
438
|
return id_value || @servertype.last_generated_id
|
451
439
|
# Ensures to free the resources associated with the statement
|
452
440
|
ensure
|
453
|
-
|
441
|
+
IBM_DB::free_result(stmt)
|
454
442
|
end
|
455
443
|
end
|
456
444
|
end
|
457
445
|
|
458
|
-
# Executes and logs
|
446
|
+
# Executes and logs +sql+ commands and
|
459
447
|
# returns a +IBM_DB::Statement+ object.
|
460
448
|
def execute(sql, name = nil)
|
449
|
+
sql.gsub!( /(\s*xml DEFAULT NULL)/i, " xml NOT NULL" )
|
461
450
|
# Logs and execute the sql instructions.
|
462
451
|
# The +log+ method is defined in the parent class +AbstractAdapter+
|
463
452
|
log(sql, name) do
|
464
|
-
|
465
|
-
stmt
|
466
|
-
|
467
|
-
|
453
|
+
begin
|
454
|
+
if stmt = IBM_DB::exec(@connection, sql)
|
455
|
+
stmt # Return the statement object
|
456
|
+
else
|
457
|
+
raise IBM_DB::stmt_errormsg
|
458
|
+
end
|
459
|
+
rescue StandardError
|
460
|
+
error_msg = IBM_DB::conn_errormsg ? IBM_DB::conn_errormsg : IBM_DB::stmt_errormsg
|
461
|
+
if error_msg && !error_msg.empty?
|
462
|
+
raise "Failed to execute statement due to error: #{error_msg}"
|
463
|
+
else
|
464
|
+
raise
|
465
|
+
end
|
468
466
|
end
|
469
467
|
end
|
470
468
|
end
|
471
469
|
|
470
|
+
# Executes an "UPDATE" SQL statement
|
472
471
|
def update(sql, name = nil)
|
473
472
|
# Make sure the WHERE clause handles NULL's correctly
|
474
473
|
sqlarray = sql.split(/\s*WHERE\s*/)
|
475
474
|
if !sqlarray[1].nil?
|
476
|
-
sqlarray[1].gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, "IS NULL" )
|
475
|
+
sqlarray[1].gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" )
|
477
476
|
sql = sqlarray[0] + " WHERE " + sqlarray[1]
|
478
477
|
end
|
479
478
|
|
@@ -501,7 +500,7 @@ module ActiveRecord
|
|
501
500
|
IBM_DB::autocommit(@connection, IBM_DB::SQL_AUTOCOMMIT_OFF)
|
502
501
|
end
|
503
502
|
|
504
|
-
# Commits the transaction
|
503
|
+
# Commits the transaction and turns on auto-committing
|
505
504
|
def commit_db_transaction
|
506
505
|
# Commits the transaction
|
507
506
|
IBM_DB::commit @connection rescue nil
|
@@ -509,7 +508,7 @@ module ActiveRecord
|
|
509
508
|
IBM_DB::autocommit @connection, IBM_DB::SQL_AUTOCOMMIT_ON
|
510
509
|
end
|
511
510
|
|
512
|
-
# Rolls back the transaction
|
511
|
+
# Rolls back the transaction and turns on auto-committing. Must be
|
513
512
|
# done if the transaction block raises an exception or returns false
|
514
513
|
def rollback_db_transaction
|
515
514
|
# ROLLBACK the transaction
|
@@ -522,9 +521,9 @@ module ActiveRecord
|
|
522
521
|
# Modifies a sql statement in order to implement a LIMIT and an OFFSET.
|
523
522
|
# A LIMIT defines the number of rows that should be fetched, while
|
524
523
|
# an OFFSET defines from what row the records must be fetched.
|
525
|
-
# IBM
|
524
|
+
# IBM data servers implement a LIMIT in SQL statements through:
|
526
525
|
# FETCH FIRST n ROWS ONLY, where n is the number of rows required.
|
527
|
-
# The implementation of OFFSET is more elaborate, and
|
526
|
+
# The implementation of OFFSET is more elaborate, and requires the usage of
|
528
527
|
# subqueries and the ROW_NUMBER() command in order to add row numbering
|
529
528
|
# as an additional column to a copy of the existing table.
|
530
529
|
# ==== Examples
|
@@ -557,15 +556,15 @@ module ActiveRecord
|
|
557
556
|
# sql query given an offset and a limit
|
558
557
|
def query_offset_limit(sql, offset, limit)
|
559
558
|
# Defines what will be the last record
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
559
|
+
last_record = offset + limit
|
560
|
+
# Transforms the SELECT query in order to retrieve/fetch only
|
561
|
+
# a number of records after the specified offset.
|
562
|
+
# 'select' or 'SELECT' is replaced with the partial query below that adds the sys_row_num column
|
563
|
+
# to select with the condition of this column being between offset+1 and the offset+limit
|
564
|
+
sql.gsub!(/SELECT/i,"SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM (SELECT")
|
565
|
+
# The final part of the query is appended to include a WHERE...BETWEEN...AND condition,
|
566
|
+
# and retrieve only a LIMIT number of records starting from the OFFSET+1
|
567
|
+
sql << ") AS I) AS O WHERE sys_row_num BETWEEN #{offset+1} AND #{last_record}"
|
569
568
|
end
|
570
569
|
private :query_offset_limit
|
571
570
|
|
@@ -583,7 +582,7 @@ module ActiveRecord
|
|
583
582
|
def quote(value, column = nil)
|
584
583
|
case value
|
585
584
|
# If it's a numeric value and the column type is not a string, it shouldn't be quoted
|
586
|
-
# (
|
585
|
+
# (IBM_DB doesn't accept quotes on numeric types)
|
587
586
|
when Numeric
|
588
587
|
# If the column type is text or string, return the quote value
|
589
588
|
if column && column.type == :text || column && column.type == :string
|
@@ -594,30 +593,30 @@ module ActiveRecord
|
|
594
593
|
value.to_s
|
595
594
|
end
|
596
595
|
when String, ActiveSupport::Multibyte::Chars
|
597
|
-
|
598
|
-
|
599
|
-
unless caller[0] =~ /add_column_options/i
|
600
|
-
# Invokes a convertion from string to binary
|
601
|
-
"BLOB('?')"
|
602
|
-
else
|
603
|
-
# Quoting required for the default value of a column
|
604
|
-
"BLOB('#{value}')"
|
605
|
-
end
|
606
|
-
elsif column && column.type == :text
|
596
|
+
if column && column.type == :binary
|
597
|
+
# If quoting is required for the insert/update of a BLOB
|
607
598
|
unless caller[0] =~ /add_column_options/i
|
608
|
-
|
599
|
+
# Invokes a convertion from string to binary
|
600
|
+
"BLOB('?')"
|
609
601
|
else
|
610
|
-
|
602
|
+
# Quoting required for the default value of a column
|
603
|
+
"BLOB('#{value}')"
|
611
604
|
end
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
605
|
+
elsif column && column.type == :text
|
606
|
+
unless caller[0] =~ /add_column_options/i
|
607
|
+
"'@@@IBMTEXT@@@'"
|
608
|
+
else
|
609
|
+
"#{value}"
|
610
|
+
end
|
611
|
+
elsif column && column.type == :xml
|
612
|
+
unless caller[0] =~ /add_column_options/i
|
613
|
+
"'<ibm>@@@IBMXML@@@</ibm>'"
|
614
|
+
else
|
615
|
+
"#{value}"
|
616
|
+
end
|
617
|
+
else
|
618
|
+
"'#{quote_string(value)}'"
|
619
|
+
end
|
621
620
|
when TrueClass then quoted_true # return '1' for true
|
622
621
|
when FalseClass then quoted_false # return '0' for false
|
623
622
|
when NilClass
|
@@ -669,12 +668,13 @@ module ActiveRecord
|
|
669
668
|
:date => { :name => "date" },
|
670
669
|
:binary => { :name => "blob" },
|
671
670
|
|
672
|
-
# IBM
|
671
|
+
# IBM data servers don't have a native boolean type.
|
673
672
|
# A boolean can be represented by a smallint,
|
674
673
|
# adopting the convention that False is 0 and True is 1
|
675
674
|
:boolean => { :name => "smallint"},
|
676
675
|
:xml => { :name => "xml"},
|
677
|
-
:decimal => { :name => "decimal" }
|
676
|
+
:decimal => { :name => "decimal" },
|
677
|
+
:rowid => { :name => "rowid" } # rowid is a supported datatype on z/OS and i/5
|
678
678
|
}
|
679
679
|
end
|
680
680
|
|
@@ -682,16 +682,16 @@ module ActiveRecord
|
|
682
682
|
# unlike MySQL. It does support limits on float and decimal/numeric
|
683
683
|
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
|
684
684
|
if type == :integer && (!limit.nil? && limit > 0)
|
685
|
-
|
685
|
+
return 'integer'
|
686
686
|
elsif type == :double && (!limit.nil? && limit > 0)
|
687
|
-
|
687
|
+
return 'double'
|
688
688
|
else
|
689
|
-
|
689
|
+
return super
|
690
690
|
end
|
691
691
|
end
|
692
692
|
|
693
693
|
# Returns the maximum length a table alias identifier can be.
|
694
|
-
# IBM
|
694
|
+
# IBM data servers (cross-platform) table limit is 128 characters
|
695
695
|
def table_alias_length
|
696
696
|
128
|
697
697
|
end
|
@@ -759,8 +759,8 @@ module ActiveRecord
|
|
759
759
|
# Statement required to access all the columns information
|
760
760
|
if stmt = IBM_DB::columns(@connection, nil, @schema.upcase, table_name.upcase)
|
761
761
|
begin
|
762
|
-
|
763
|
-
|
762
|
+
# Fetches all the columns and assigns them to col.
|
763
|
+
# +col+ is an hash with keys/value pairs for a column
|
764
764
|
while col = IBM_DB::fetch_assoc(stmt)
|
765
765
|
column_name = col["column_name"].downcase
|
766
766
|
# Assigns the column default value.
|
@@ -779,7 +779,7 @@ module ActiveRecord
|
|
779
779
|
# it appends the (column_length) string on the supported data types
|
780
780
|
unless column_length.nil? || column_length == '' || column_type.sub!(/ \(\) for bit data/i,"(#{column_length}) FOR BIT DATA") || !column_type =~ /char|lob|graphic/i
|
781
781
|
if column_type =~ /decimal/i
|
782
|
-
|
782
|
+
column_type << "(#{column_length},#{column_scale})"
|
783
783
|
else
|
784
784
|
column_type << "(#{column_length})"
|
785
785
|
end
|
@@ -793,8 +793,13 @@ module ActiveRecord
|
|
793
793
|
columns << IBM_DBColumn.new(column_name, column_default_value, column_type, column_nullable)
|
794
794
|
end
|
795
795
|
end
|
796
|
-
rescue
|
797
|
-
|
796
|
+
rescue StandardError
|
797
|
+
error_msg = IBM_DB::conn_errormsg ? IBM_DB::conn_errormsg : IBM_DB::stmt_errormsg
|
798
|
+
if error_msg && !error_msg.empty?
|
799
|
+
raise "Failed to retrieve column metadata due to driver error: #{error_msg}"
|
800
|
+
else
|
801
|
+
raise
|
802
|
+
end
|
798
803
|
end
|
799
804
|
end
|
800
805
|
# Returns the columns array
|
@@ -804,7 +809,7 @@ module ActiveRecord
|
|
804
809
|
# Renames a table.
|
805
810
|
# ==== Example
|
806
811
|
# rename_table('octopuses', 'octopi')
|
807
|
-
# Overriden to satisfy IBM
|
812
|
+
# Overriden to satisfy IBM data servers syntax
|
808
813
|
def rename_table(name, new_name)
|
809
814
|
# SQL rename table statement
|
810
815
|
rename_table_sql = "RENAME TABLE #{name} TO #{new_name}"
|
@@ -818,14 +823,14 @@ module ActiveRecord
|
|
818
823
|
# ===== Example
|
819
824
|
# rename_column(:suppliers, :description, :name)
|
820
825
|
def rename_column(table_name, column_name, new_column_name)
|
821
|
-
|
826
|
+
@servertype.rename_column(table_name, column_name, new_column_name)
|
822
827
|
end
|
823
828
|
|
824
829
|
# Removes the column from the table definition.
|
825
830
|
# ===== Examples
|
826
831
|
# remove_column(:suppliers, :qualification)
|
827
832
|
def remove_column(table_name, column_name)
|
828
|
-
|
833
|
+
@servertype.remove_column(table_name, column_name)
|
829
834
|
end
|
830
835
|
|
831
836
|
# Changes the column's definition according to the new options.
|
@@ -834,18 +839,18 @@ module ActiveRecord
|
|
834
839
|
# change_column(:suppliers, :name, :string, :limit => 80)
|
835
840
|
# change_column(:accounts, :description, :text)
|
836
841
|
def change_column(table_name, column_name, type, options = {})
|
837
|
-
|
842
|
+
@servertype.change_column(table_name, column_name, type, options)
|
838
843
|
end
|
839
844
|
|
840
|
-
# Sets a new default value for a column.
|
841
|
-
# value to +NULL+,
|
842
|
-
#
|
845
|
+
# Sets a new default value for a column. This does not set the default
|
846
|
+
# value to +NULL+, instead, it needs DatabaseStatements#execute which
|
847
|
+
# can execute the appropriate SQL statement for setting the value.
|
843
848
|
# ==== Examples
|
844
849
|
# change_column_default(:suppliers, :qualification, 'new')
|
845
850
|
# change_column_default(:accounts, :authorized, 1)
|
846
|
-
# Method overriden to satisfy IBM
|
851
|
+
# Method overriden to satisfy IBM data servers syntax.
|
847
852
|
def change_column_default(table_name, column_name, default)
|
848
|
-
|
853
|
+
# SQL statement which alters column's default value
|
849
854
|
change_column_sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET WITH DEFAULT #{quote(default)}"
|
850
855
|
stmt = execute(change_column_sql)
|
851
856
|
# Ensures to free the resources associated with the statement
|
@@ -902,20 +907,20 @@ module ActiveRecord
|
|
902
907
|
# You can remove an index on multiple columns by specifying the first column.
|
903
908
|
# add_index :accounts, [:username, :password]
|
904
909
|
# remove_index :accounts, :username
|
905
|
-
# Overriden to use the IBM
|
910
|
+
# Overriden to use the IBM data servers SQL syntax.
|
906
911
|
def remove_index(table_name, options = {})
|
907
912
|
execute("DROP INDEX #{index_name(table_name, options)}")
|
908
913
|
end
|
909
914
|
|
910
915
|
# Builds an index name from a table_name and column. If an index name has been passed,
|
911
|
-
# the method returns it. Overrides the default method to respect the IBM
|
916
|
+
# the method returns it. Overrides the default method to respect the IBM data servers (cross-platform)
|
912
917
|
# limit on indexes (max of 18 characters)
|
913
918
|
def index_name(table_name, options)
|
914
919
|
if Hash === options and options[:name]
|
915
920
|
# legacy support
|
916
|
-
|
917
|
-
|
918
|
-
|
921
|
+
# If a name has been specified, this is returned
|
922
|
+
options[:name]
|
923
|
+
else
|
919
924
|
# We reverse the table name to reduce the chance of hitting duplicate
|
920
925
|
# index name errors. For e.g. indexes on table names like accounts,
|
921
926
|
# accounts_favorites
|
@@ -960,11 +965,15 @@ module ActiveRecord
|
|
960
965
|
reorg_table(table_name)
|
961
966
|
end
|
962
967
|
|
968
|
+
def set_schema(schema)
|
969
|
+
@caller.execute("SET SCHEMA #{schema}")
|
970
|
+
end
|
971
|
+
|
963
972
|
end # class IBM_DataServer
|
964
973
|
|
965
974
|
class IBM_DB2 < IBM_DataServer
|
966
975
|
def rename_column(table_name, column_name, new_column_name)
|
967
|
-
raise NotImplementedError, "rename_column is not implemented yet in the
|
976
|
+
raise NotImplementedError, "rename_column is not implemented yet in the IBM_DB Adapter"
|
968
977
|
end
|
969
978
|
|
970
979
|
def primary_key
|
@@ -985,10 +994,19 @@ module ActiveRecord
|
|
985
994
|
end
|
986
995
|
|
987
996
|
def change_column(table_name, column_name, type, options)
|
988
|
-
|
997
|
+
data_type = @caller.type_to_sql(type, options[:limit], options[:precision], options[:scale])
|
998
|
+
begin
|
999
|
+
@caller.execute "ALTER TABLE #{table_name} ALTER #{column_name} SET DATA TYPE #{data_type}"
|
1000
|
+
rescue StandardError => exec_err
|
1001
|
+
if exec_err.message.include?('SQLCODE=-190')
|
1002
|
+
raise StatementInvalid, "Please consult documentation for compatible data types while changing column datatype. The column datatype change to [#{data_type}] is not supported by this data server: #{exec_err}"
|
1003
|
+
else
|
1004
|
+
raise
|
1005
|
+
end
|
1006
|
+
end
|
989
1007
|
reorg_table(table_name)
|
990
1008
|
if !options[:default].nil?
|
991
|
-
|
1009
|
+
@caller.change_column_default(table_name, column_name, options[:default])
|
992
1010
|
end
|
993
1011
|
end
|
994
1012
|
end # class IBM_DB2
|
@@ -1035,6 +1053,13 @@ module ActiveRecord
|
|
1035
1053
|
def remove_column(table_name, column_name)
|
1036
1054
|
raise NotImplementedError, "remove_column is not supported for DB2/zOS server"
|
1037
1055
|
end
|
1056
|
+
|
1057
|
+
# Setting the SQLID on z/OS will also update the CURRENT SCHEMA
|
1058
|
+
# special register, but not vice versa
|
1059
|
+
def set_schema(schema)
|
1060
|
+
@caller.execute("SET CURRENT SQLID ='#{schema}'")
|
1061
|
+
end
|
1062
|
+
|
1038
1063
|
end # class IBM_DB2_ZOS
|
1039
1064
|
|
1040
1065
|
class IBM_DB2_ZOS_8 < IBM_DB2_ZOS
|
@@ -1050,4 +1075,4 @@ module ActiveRecord
|
|
1050
1075
|
end # class IBM_DB2_I5
|
1051
1076
|
|
1052
1077
|
end # module ConnectionAdapters
|
1053
|
-
end # module ActiveRecord
|
1078
|
+
end # module ActiveRecord
|