ibm_db 0.4.0 → 0.4.6
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 +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
|