sequel_core 1.0
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/CHANGELOG +1003 -0
- data/COPYING +18 -0
- data/README +81 -0
- data/Rakefile +176 -0
- data/bin/sequel +41 -0
- data/lib/sequel_core.rb +59 -0
- data/lib/sequel_core/adapters/adapter_skeleton.rb +68 -0
- data/lib/sequel_core/adapters/ado.rb +100 -0
- data/lib/sequel_core/adapters/db2.rb +158 -0
- data/lib/sequel_core/adapters/dbi.rb +126 -0
- data/lib/sequel_core/adapters/informix.rb +87 -0
- data/lib/sequel_core/adapters/jdbc.rb +108 -0
- data/lib/sequel_core/adapters/mysql.rb +269 -0
- data/lib/sequel_core/adapters/odbc.rb +145 -0
- data/lib/sequel_core/adapters/odbc_mssql.rb +93 -0
- data/lib/sequel_core/adapters/openbase.rb +90 -0
- data/lib/sequel_core/adapters/oracle.rb +99 -0
- data/lib/sequel_core/adapters/postgres.rb +519 -0
- data/lib/sequel_core/adapters/sqlite.rb +192 -0
- data/lib/sequel_core/array_keys.rb +296 -0
- data/lib/sequel_core/connection_pool.rb +152 -0
- data/lib/sequel_core/core_ext.rb +59 -0
- data/lib/sequel_core/core_sql.rb +191 -0
- data/lib/sequel_core/database.rb +433 -0
- data/lib/sequel_core/dataset.rb +409 -0
- data/lib/sequel_core/dataset/convenience.rb +321 -0
- data/lib/sequel_core/dataset/sequelizer.rb +354 -0
- data/lib/sequel_core/dataset/sql.rb +586 -0
- data/lib/sequel_core/exceptions.rb +45 -0
- data/lib/sequel_core/migration.rb +191 -0
- data/lib/sequel_core/model.rb +8 -0
- data/lib/sequel_core/pretty_table.rb +73 -0
- data/lib/sequel_core/schema.rb +8 -0
- data/lib/sequel_core/schema/schema_generator.rb +131 -0
- data/lib/sequel_core/schema/schema_sql.rb +131 -0
- data/lib/sequel_core/worker.rb +58 -0
- data/spec/adapters/informix_spec.rb +139 -0
- data/spec/adapters/mysql_spec.rb +330 -0
- data/spec/adapters/oracle_spec.rb +130 -0
- data/spec/adapters/postgres_spec.rb +189 -0
- data/spec/adapters/sqlite_spec.rb +345 -0
- data/spec/array_keys_spec.rb +679 -0
- data/spec/connection_pool_spec.rb +356 -0
- data/spec/core_ext_spec.rb +67 -0
- data/spec/core_sql_spec.rb +301 -0
- data/spec/database_spec.rb +812 -0
- data/spec/dataset_spec.rb +2381 -0
- data/spec/migration_spec.rb +261 -0
- data/spec/pretty_table_spec.rb +66 -0
- data/spec/rcov.opts +4 -0
- data/spec/schema_generator_spec.rb +86 -0
- data/spec/schema_spec.rb +230 -0
- data/spec/sequelizer_spec.rb +448 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/worker_spec.rb +96 -0
- metadata +162 -0
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'java'
|
2
|
+
|
3
|
+
module Sequel
|
4
|
+
module JDBC
|
5
|
+
module JavaLang; include_package 'java.lang'; end
|
6
|
+
module JavaSQL; include_package 'java.sql'; end
|
7
|
+
|
8
|
+
def self.load_driver(driver)
|
9
|
+
JavaLang::Class.forName(driver)
|
10
|
+
# "com.mysql.jdbc.Driver"
|
11
|
+
end
|
12
|
+
|
13
|
+
class Database < Sequel::Database
|
14
|
+
set_adapter_scheme :jdbc
|
15
|
+
|
16
|
+
def connect
|
17
|
+
unless conn_string = @opts[:uri] || @opts[:url] || @opts[:database]
|
18
|
+
raise Error, "No connection string specified"
|
19
|
+
end
|
20
|
+
unless conn_string =~ /^jdbc:/
|
21
|
+
conn_string = "jdbc:#{conn_string}"
|
22
|
+
end
|
23
|
+
JavaSQL::DriverManager.getConnection(
|
24
|
+
conn_string,
|
25
|
+
@opts[:user],
|
26
|
+
@opts[:password]
|
27
|
+
)
|
28
|
+
# "jdbc:mysql://127.0.0.1:3306/ruby?user=root"
|
29
|
+
# "mysql://127.0.0.1:3306/ruby?user=root"
|
30
|
+
end
|
31
|
+
|
32
|
+
def disconnect
|
33
|
+
@pool.disconnect {|c| c.close}
|
34
|
+
end
|
35
|
+
|
36
|
+
def dataset(opts = nil)
|
37
|
+
JDBC::Dataset.new(self, opts)
|
38
|
+
end
|
39
|
+
|
40
|
+
def execute_and_forget(sql)
|
41
|
+
@logger.info(sql) if @logger
|
42
|
+
@pool.hold do |conn|
|
43
|
+
stmt = conn.createStatement
|
44
|
+
begin
|
45
|
+
stmt.executeQuery(sql)
|
46
|
+
ensure
|
47
|
+
stmt.close
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def execute(sql)
|
53
|
+
@logger.info(sql) if @logger
|
54
|
+
@pool.hold do |conn|
|
55
|
+
stmt = conn.createStatement
|
56
|
+
begin
|
57
|
+
yield stmt.executeQuery(sql)
|
58
|
+
ensure
|
59
|
+
stmt.close
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Dataset < Sequel::Dataset
|
66
|
+
def literal(v)
|
67
|
+
case v
|
68
|
+
when Time
|
69
|
+
literal(v.iso8601)
|
70
|
+
else
|
71
|
+
super
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def fetch_rows(sql, &block)
|
76
|
+
@db.synchronize do
|
77
|
+
@db.execute(sql) do |result|
|
78
|
+
# get column names
|
79
|
+
meta = result.getMetaData
|
80
|
+
column_count = meta.getColumnCount
|
81
|
+
@columns = []
|
82
|
+
column_count.times {|i| @columns << meta.getColumnName(i).to_sym}
|
83
|
+
|
84
|
+
# get rows
|
85
|
+
while result.next
|
86
|
+
row = {}
|
87
|
+
@columns.each_with_index {|v, i| row[v] = result.getObject(i)}
|
88
|
+
yield row
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
self
|
93
|
+
end
|
94
|
+
|
95
|
+
def insert(*values)
|
96
|
+
@db.execute_and_forget insert_sql(*values)
|
97
|
+
end
|
98
|
+
|
99
|
+
def update(*args, &block)
|
100
|
+
@db.execute_and_forget update_sql(*args, &block)
|
101
|
+
end
|
102
|
+
|
103
|
+
def delete(opts = nil)
|
104
|
+
@db.execute_and_forget delete_sql(opts)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
require 'mysql'
|
2
|
+
|
3
|
+
# Monkey patch Mysql::Result to yield hashes with symbol keys
|
4
|
+
class Mysql::Result
|
5
|
+
MYSQL_TYPES = {
|
6
|
+
0 => :to_d, # MYSQL_TYPE_DECIMAL
|
7
|
+
1 => :to_i, # MYSQL_TYPE_TINY
|
8
|
+
2 => :to_i, # MYSQL_TYPE_SHORT
|
9
|
+
3 => :to_i, # MYSQL_TYPE_LONG
|
10
|
+
4 => :to_f, # MYSQL_TYPE_FLOAT
|
11
|
+
5 => :to_f, # MYSQL_TYPE_DOUBLE
|
12
|
+
# 6 => ??, # MYSQL_TYPE_NULL
|
13
|
+
7 => :to_time, # MYSQL_TYPE_TIMESTAMP
|
14
|
+
8 => :to_i, # MYSQL_TYPE_LONGLONG
|
15
|
+
9 => :to_i, # MYSQL_TYPE_INT24
|
16
|
+
10 => :to_time, # MYSQL_TYPE_DATE
|
17
|
+
11 => :to_time, # MYSQL_TYPE_TIME
|
18
|
+
12 => :to_time, # MYSQL_TYPE_DATETIME
|
19
|
+
13 => :to_i, # MYSQL_TYPE_YEAR
|
20
|
+
14 => :to_time, # MYSQL_TYPE_NEWDATE
|
21
|
+
# 15 => :to_s # MYSQL_TYPE_VARCHAR
|
22
|
+
# 16 => :to_s, # MYSQL_TYPE_BIT
|
23
|
+
246 => :to_d, # MYSQL_TYPE_NEWDECIMAL
|
24
|
+
247 => :to_i, # MYSQL_TYPE_ENUM
|
25
|
+
248 => :to_i # MYSQL_TYPE_SET
|
26
|
+
# 249 => :to_s, # MYSQL_TYPE_TINY_BLOB
|
27
|
+
# 250 => :to_s, # MYSQL_TYPE_MEDIUM_BLOB
|
28
|
+
# 251 => :to_s, # MYSQL_TYPE_LONG_BLOB
|
29
|
+
# 252 => :to_s, # MYSQL_TYPE_BLOB
|
30
|
+
# 253 => :to_s, # MYSQL_TYPE_VAR_STRING
|
31
|
+
# 254 => :to_s, # MYSQL_TYPE_STRING
|
32
|
+
# 255 => :to_s # MYSQL_TYPE_GEOMETRY
|
33
|
+
}
|
34
|
+
|
35
|
+
def convert_type(v, type)
|
36
|
+
v ? ((t = MYSQL_TYPES[type]) ? v.send(t) : v) : nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def columns(with_table = nil)
|
40
|
+
unless @columns
|
41
|
+
@column_types = []
|
42
|
+
@columns = fetch_fields.map do |f|
|
43
|
+
@column_types << f.type
|
44
|
+
(with_table ? (f.table + "." + f.name) : f.name).to_sym
|
45
|
+
end
|
46
|
+
end
|
47
|
+
@columns
|
48
|
+
end
|
49
|
+
|
50
|
+
def each_array(with_table = nil)
|
51
|
+
c = columns
|
52
|
+
while row = fetch_row
|
53
|
+
c.each_with_index do |f, i|
|
54
|
+
if (t = MYSQL_TYPES[@column_types[i]]) && (v = row[i])
|
55
|
+
row[i] = v.send(t)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
row.keys = c
|
59
|
+
yield row
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def each_hash(with_table = nil)
|
64
|
+
c = columns
|
65
|
+
while row = fetch_row
|
66
|
+
h = {}
|
67
|
+
c.each_with_index {|f, i| h[f] = convert_type(row[i], @column_types[i])}
|
68
|
+
yield h
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
module Sequel
|
74
|
+
module MySQL
|
75
|
+
class Database < Sequel::Database
|
76
|
+
set_adapter_scheme :mysql
|
77
|
+
|
78
|
+
def serial_primary_key_options
|
79
|
+
{:primary_key => true, :type => :integer, :auto_increment => true}
|
80
|
+
end
|
81
|
+
|
82
|
+
AUTO_INCREMENT = 'AUTO_INCREMENT'.freeze
|
83
|
+
|
84
|
+
def auto_increment_sql
|
85
|
+
AUTO_INCREMENT
|
86
|
+
end
|
87
|
+
|
88
|
+
def connect
|
89
|
+
conn = Mysql.real_connect(@opts[:host], @opts[:user], @opts[:password],
|
90
|
+
@opts[:database], @opts[:port], nil, Mysql::CLIENT_MULTI_RESULTS)
|
91
|
+
conn.query_with_result = false
|
92
|
+
if encoding = @opts[:encoding] || @opts[:charset]
|
93
|
+
conn.query("set character_set_connection = '#{encoding}'")
|
94
|
+
conn.query("set character_set_client = '#{encoding}'")
|
95
|
+
conn.query("set character_set_results = '#{encoding}'")
|
96
|
+
end
|
97
|
+
conn.reconnect = true
|
98
|
+
conn
|
99
|
+
end
|
100
|
+
|
101
|
+
def disconnect
|
102
|
+
@pool.disconnect {|c| c.close}
|
103
|
+
end
|
104
|
+
|
105
|
+
def tables
|
106
|
+
@pool.hold do |conn|
|
107
|
+
conn.list_tables.map {|t| t.to_sym}
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def dataset(opts = nil)
|
112
|
+
MySQL::Dataset.new(self, opts)
|
113
|
+
end
|
114
|
+
|
115
|
+
def execute(sql)
|
116
|
+
@logger.info(sql) if @logger
|
117
|
+
@pool.hold do |conn|
|
118
|
+
conn.query(sql)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def execute_select(sql)
|
123
|
+
@logger.info(sql) if @logger
|
124
|
+
@pool.hold do |conn|
|
125
|
+
conn.query(sql)
|
126
|
+
conn.use_result
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def execute_insert(sql)
|
131
|
+
@logger.info(sql) if @logger
|
132
|
+
@pool.hold do |conn|
|
133
|
+
conn.query(sql)
|
134
|
+
conn.insert_id
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def execute_affected(sql)
|
139
|
+
@logger.info(sql) if @logger
|
140
|
+
@pool.hold do |conn|
|
141
|
+
conn.query(sql)
|
142
|
+
conn.affected_rows
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def alter_table_sql(table, op)
|
147
|
+
case op[:op]
|
148
|
+
when :rename_column
|
149
|
+
"ALTER TABLE #{table} CHANGE COLUMN #{literal(op[:name])} #{literal(op[:new_name])} #{op[:type]}"
|
150
|
+
when :set_column_type
|
151
|
+
"ALTER TABLE #{table} CHANGE COLUMN #{literal(op[:name])} #{literal(op[:name])} #{op[:type]}"
|
152
|
+
when :drop_index
|
153
|
+
"DROP INDEX #{default_index_name(table, op[:columns])} ON #{table}"
|
154
|
+
else
|
155
|
+
super(table, op)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def transaction
|
160
|
+
@pool.hold do |conn|
|
161
|
+
@transactions ||= []
|
162
|
+
if @transactions.include? Thread.current
|
163
|
+
return yield(conn)
|
164
|
+
end
|
165
|
+
conn.query(SQL_BEGIN)
|
166
|
+
begin
|
167
|
+
@transactions << Thread.current
|
168
|
+
result = yield(conn)
|
169
|
+
conn.query(SQL_COMMIT)
|
170
|
+
result
|
171
|
+
rescue => e
|
172
|
+
conn.query(SQL_ROLLBACK)
|
173
|
+
raise e unless Error::Rollback === e
|
174
|
+
ensure
|
175
|
+
@transactions.delete(Thread.current)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
class Dataset < Sequel::Dataset
|
182
|
+
def quote_column_ref(c); "`#{c}`"; end
|
183
|
+
|
184
|
+
TRUE = '1'
|
185
|
+
FALSE = '0'
|
186
|
+
|
187
|
+
def literal(v)
|
188
|
+
case v
|
189
|
+
when LiteralString
|
190
|
+
v
|
191
|
+
when String
|
192
|
+
"'#{v.gsub(/'|\\/, '\&\&')}'"
|
193
|
+
when true
|
194
|
+
TRUE
|
195
|
+
when false
|
196
|
+
FALSE
|
197
|
+
else
|
198
|
+
super
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def match_expr(l, r)
|
203
|
+
case r
|
204
|
+
when Regexp
|
205
|
+
r.casefold? ? \
|
206
|
+
"(#{literal(l)} REGEXP #{literal(r.source)})" :
|
207
|
+
"(#{literal(l)} REGEXP BINARY #{literal(r.source)})"
|
208
|
+
else
|
209
|
+
super
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# MySQL supports ORDER and LIMIT clauses in UPDATE statements.
|
214
|
+
def update_sql(values, opts = nil)
|
215
|
+
sql = super
|
216
|
+
|
217
|
+
opts = opts ? @opts.merge(opts) : @opts
|
218
|
+
|
219
|
+
if order = opts[:order]
|
220
|
+
sql << " ORDER BY #{column_list(order)}"
|
221
|
+
end
|
222
|
+
|
223
|
+
if limit = opts[:limit]
|
224
|
+
sql << " LIMIT #{limit}"
|
225
|
+
end
|
226
|
+
|
227
|
+
sql
|
228
|
+
end
|
229
|
+
|
230
|
+
def insert(*values)
|
231
|
+
@db.execute_insert(insert_sql(*values))
|
232
|
+
end
|
233
|
+
|
234
|
+
def update(*args, &block)
|
235
|
+
@db.execute_affected(update_sql(*args, &block))
|
236
|
+
end
|
237
|
+
|
238
|
+
def delete(opts = nil)
|
239
|
+
@db.execute_affected(delete_sql(opts))
|
240
|
+
end
|
241
|
+
|
242
|
+
def fetch_rows(sql)
|
243
|
+
@db.synchronize do
|
244
|
+
r = @db.execute_select(sql)
|
245
|
+
begin
|
246
|
+
@columns = r.columns
|
247
|
+
r.each_hash {|row| yield row}
|
248
|
+
ensure
|
249
|
+
r.free
|
250
|
+
end
|
251
|
+
end
|
252
|
+
self
|
253
|
+
end
|
254
|
+
|
255
|
+
def array_tuples_fetch_rows(sql, &block)
|
256
|
+
@db.synchronize do
|
257
|
+
r = @db.execute_select(sql)
|
258
|
+
begin
|
259
|
+
@columns = r.columns
|
260
|
+
r.each_array(&block)
|
261
|
+
ensure
|
262
|
+
r.free
|
263
|
+
end
|
264
|
+
end
|
265
|
+
self
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'odbc'
|
2
|
+
|
3
|
+
module Sequel
|
4
|
+
module ODBC
|
5
|
+
class Database < Sequel::Database
|
6
|
+
set_adapter_scheme :odbc
|
7
|
+
|
8
|
+
def connect
|
9
|
+
conn = ::ODBC::connect(@opts[:database], @opts[:user], @opts[:password])
|
10
|
+
conn.autocommit = true
|
11
|
+
conn
|
12
|
+
end
|
13
|
+
|
14
|
+
def disconnect
|
15
|
+
@pool.disconnect {|c| c.disconnect}
|
16
|
+
end
|
17
|
+
|
18
|
+
def dataset(opts = nil)
|
19
|
+
ODBC::Dataset.new(self, opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
def execute(sql)
|
23
|
+
@logger.info(sql) if @logger
|
24
|
+
@pool.hold do |conn|
|
25
|
+
conn.run(sql)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def do(sql)
|
30
|
+
@logger.info(sql) if @logger
|
31
|
+
@pool.hold do |conn|
|
32
|
+
conn.do(sql)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Dataset < Sequel::Dataset
|
38
|
+
BOOL_TRUE = '1'.freeze
|
39
|
+
BOOL_FALSE = '0'.freeze
|
40
|
+
|
41
|
+
def literal(v)
|
42
|
+
case v
|
43
|
+
when true
|
44
|
+
BOOL_TRUE
|
45
|
+
when false
|
46
|
+
BOOL_FALSE
|
47
|
+
else
|
48
|
+
super
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def fetch_rows(sql, &block)
|
53
|
+
@db.synchronize do
|
54
|
+
s = @db.execute sql
|
55
|
+
begin
|
56
|
+
@columns = s.columns(true).map {|c| c.name.to_sym}
|
57
|
+
rows = s.fetch_all
|
58
|
+
rows.each {|row| yield hash_row(row)}
|
59
|
+
ensure
|
60
|
+
s.drop unless s.nil? rescue nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
def hash_row(row)
|
67
|
+
hash = {}
|
68
|
+
row.each_with_index do |v, idx|
|
69
|
+
hash[@columns[idx]] = convert_odbc_value(v)
|
70
|
+
end
|
71
|
+
hash
|
72
|
+
end
|
73
|
+
|
74
|
+
def convert_odbc_value(v)
|
75
|
+
# When fetching a result set, the Ruby ODBC driver converts all ODBC
|
76
|
+
# SQL types to an equivalent Ruby type; with the exception of
|
77
|
+
# SQL_TYPE_DATE, SQL_TYPE_TIME and SQL_TYPE_TIMESTAMP.
|
78
|
+
#
|
79
|
+
# The conversions below are consistent with the mappings in
|
80
|
+
# ODBCColumn#mapSqlTypeToGenericType and Column#klass.
|
81
|
+
case v
|
82
|
+
when ::ODBC::TimeStamp
|
83
|
+
DateTime.new(v.year, v.month, v.day, v.hour, v.minute, v.second)
|
84
|
+
when ::ODBC::Time
|
85
|
+
DateTime.now
|
86
|
+
Time.gm(now.year, now.month, now.day, v.hour, v.minute, v.second)
|
87
|
+
when ::ODBC::Date
|
88
|
+
Date.new(v.year, v.month, v.day)
|
89
|
+
else
|
90
|
+
v
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def array_tuples_fetch_rows(sql, &block)
|
95
|
+
@db.synchronize do
|
96
|
+
s = @db.execute sql
|
97
|
+
begin
|
98
|
+
@columns = s.columns(true).map {|c| c.name.to_sym}
|
99
|
+
rows = s.fetch_all
|
100
|
+
rows.each {|r| yield array_tuples_make_row(r)}
|
101
|
+
ensure
|
102
|
+
s.drop unless s.nil? rescue nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
self
|
106
|
+
end
|
107
|
+
|
108
|
+
def array_tuples_make_row(row)
|
109
|
+
row.keys = @columns
|
110
|
+
row.each_with_index do |v, idx|
|
111
|
+
# When fetching a result set, the Ruby ODBC driver converts all ODBC
|
112
|
+
# SQL types to an equivalent Ruby type; with the exception of
|
113
|
+
# SQL_TYPE_DATE, SQL_TYPE_TIME and SQL_TYPE_TIMESTAMP.
|
114
|
+
#
|
115
|
+
# The conversions below are consistent with the mappings in
|
116
|
+
# ODBCColumn#mapSqlTypeToGenericType and Column#klass.
|
117
|
+
case v
|
118
|
+
when ::ODBC::TimeStamp
|
119
|
+
row[idx] = DateTime.new(v.year, v.month, v.day, v.hour, v.minute, v.second)
|
120
|
+
when ::ODBC::Time
|
121
|
+
now = DateTime.now
|
122
|
+
row[idx] = Time.gm(now.year, now.month, now.day, v.hour, v.minute, v.second)
|
123
|
+
when ::ODBC::Date
|
124
|
+
row[idx] = Date.new(v.year, v.month, v.day)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
row
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
def insert(*values)
|
132
|
+
@db.do insert_sql(*values)
|
133
|
+
end
|
134
|
+
|
135
|
+
def update(*args, &block)
|
136
|
+
@db.do update_sql(*args, &block)
|
137
|
+
self
|
138
|
+
end
|
139
|
+
|
140
|
+
def delete(opts = nil)
|
141
|
+
@db.do delete_sql(opts)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|