sequel 0.4.4.1 → 0.4.4.2

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.
Files changed (45) hide show
  1. data/CHANGELOG +10 -0
  2. data/Rakefile +161 -159
  3. data/lib/sequel.rb +14 -10
  4. data/lib/sequel/adapters/adapter_skeleton.rb +2 -1
  5. data/lib/sequel/adapters/ado.rb +2 -1
  6. data/lib/sequel/adapters/db2.rb +5 -3
  7. data/lib/sequel/adapters/dbi.rb +2 -1
  8. data/lib/sequel/adapters/informix.rb +2 -1
  9. data/lib/sequel/adapters/jdbc.rb +3 -2
  10. data/lib/sequel/adapters/mysql.rb +268 -264
  11. data/lib/sequel/adapters/odbc.rb +7 -2
  12. data/lib/sequel/adapters/odbc_mssql.rb +1 -1
  13. data/lib/sequel/adapters/openbase.rb +2 -1
  14. data/lib/sequel/adapters/oracle.rb +2 -1
  15. data/lib/sequel/adapters/postgres.rb +32 -16
  16. data/lib/sequel/adapters/sqlite.rb +7 -6
  17. data/lib/sequel/array_keys.rb +295 -295
  18. data/lib/sequel/connection_pool.rb +1 -1
  19. data/lib/sequel/core_sql.rb +14 -5
  20. data/lib/sequel/database.rb +4 -4
  21. data/lib/sequel/dataset.rb +12 -10
  22. data/lib/sequel/dataset/convenience.rb +10 -8
  23. data/lib/sequel/dataset/sequelizer.rb +19 -16
  24. data/lib/sequel/dataset/sql.rb +43 -30
  25. data/lib/sequel/exceptions.rb +45 -0
  26. data/lib/sequel/migration.rb +7 -5
  27. data/lib/sequel/model.rb +1 -1
  28. data/lib/sequel/model/base.rb +3 -3
  29. data/lib/sequel/model/hooks.rb +0 -4
  30. data/lib/sequel/model/record.rb +9 -9
  31. data/lib/sequel/model/relations.rb +2 -2
  32. data/lib/sequel/pretty_table.rb +6 -3
  33. data/lib/sequel/schema/schema_sql.rb +11 -6
  34. data/lib/sequel/worker.rb +8 -7
  35. data/spec/adapters/sqlite_spec.rb +3 -3
  36. data/spec/array_keys_spec.rb +543 -543
  37. data/spec/connection_pool_spec.rb +6 -3
  38. data/spec/database_spec.rb +4 -4
  39. data/spec/dataset_spec.rb +25 -25
  40. data/spec/migration_spec.rb +1 -1
  41. data/spec/model_spec.rb +16 -16
  42. data/spec/sequelizer_spec.rb +7 -7
  43. data/spec/spec.opts +8 -0
  44. metadata +5 -5
  45. data/lib/sequel/error.rb +0 -22
@@ -1,265 +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 SequelRollbackError === 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: v
190
- when String: "'#{v.gsub(/'|\\/, '\&\&')}'"
191
- when true: TRUE
192
- when false: FALSE
193
- else
194
- super
195
- end
196
- end
197
-
198
- def match_expr(l, r)
199
- case r
200
- when Regexp:
201
- r.casefold? ? \
202
- "(#{literal(l)} REGEXP #{literal(r.source)})" :
203
- "(#{literal(l)} REGEXP BINARY #{literal(r.source)})"
204
- else
205
- super
206
- end
207
- end
208
-
209
- # MySQL supports ORDER and LIMIT clauses in UPDATE statements.
210
- def update_sql(values, opts = nil)
211
- sql = super
212
-
213
- opts = opts ? @opts.merge(opts) : @opts
214
-
215
- if order = opts[:order]
216
- sql << " ORDER BY #{column_list(order)}"
217
- end
218
-
219
- if limit = opts[:limit]
220
- sql << " LIMIT #{limit}"
221
- end
222
-
223
- sql
224
- end
225
-
226
- def insert(*values)
227
- @db.execute_insert(insert_sql(*values))
228
- end
229
-
230
- def update(*args, &block)
231
- @db.execute_affected(update_sql(*args, &block))
232
- end
233
-
234
- def delete(opts = nil)
235
- @db.execute_affected(delete_sql(opts))
236
- end
237
-
238
- def fetch_rows(sql)
239
- @db.synchronize do
240
- r = @db.execute_select(sql)
241
- begin
242
- @columns = r.columns
243
- r.each_hash {|row| yield row}
244
- ensure
245
- r.free
246
- end
247
- end
248
- self
249
- end
250
-
251
- def array_tuples_fetch_rows(sql, &block)
252
- @db.synchronize do
253
- r = @db.execute_select(sql)
254
- begin
255
- @columns = r.columns
256
- r.each_array(&block)
257
- ensure
258
- r.free
259
- end
260
- end
261
- self
262
- end
263
- end
264
- end
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
265
269
  end