sequel 5.18.0 → 5.20.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.
- checksums.yaml +4 -4
- data/CHANGELOG +40 -0
- data/doc/opening_databases.rdoc +5 -2
- data/doc/release_notes/5.19.0.txt +28 -0
- data/doc/release_notes/5.20.0.txt +89 -0
- data/doc/sharding.rdoc +12 -0
- data/doc/transactions.rdoc +38 -0
- data/lib/sequel/adapters/jdbc.rb +7 -2
- data/lib/sequel/adapters/mysql2.rb +2 -2
- data/lib/sequel/adapters/shared/postgres.rb +8 -8
- data/lib/sequel/adapters/shared/sqlite.rb +3 -1
- data/lib/sequel/adapters/sqlanywhere.rb +33 -17
- data/lib/sequel/adapters/sqlite.rb +20 -13
- data/lib/sequel/connection_pool.rb +0 -5
- data/lib/sequel/database/misc.rb +10 -9
- data/lib/sequel/database/query.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +1 -1
- data/lib/sequel/database/transactions.rb +57 -5
- data/lib/sequel/dataset/actions.rb +6 -5
- data/lib/sequel/dataset/graph.rb +2 -2
- data/lib/sequel/dataset/placeholder_literalizer.rb +4 -1
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/dataset/query.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +14 -0
- data/lib/sequel/extensions/pg_enum.rb +23 -15
- data/lib/sequel/extensions/schema_dumper.rb +1 -1
- data/lib/sequel/model/associations.rb +38 -12
- data/lib/sequel/model/base.rb +1 -1
- data/lib/sequel/model/plugins.rb +104 -0
- data/lib/sequel/plugins/association_dependencies.rb +3 -3
- data/lib/sequel/plugins/association_pks.rb +14 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +1 -0
- data/lib/sequel/plugins/composition.rb +13 -9
- data/lib/sequel/plugins/finder.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +17 -5
- data/lib/sequel/plugins/inverted_subsets.rb +2 -2
- data/lib/sequel/plugins/json_serializer.rb +3 -3
- data/lib/sequel/plugins/nested_attributes.rb +1 -1
- data/lib/sequel/plugins/pg_array_associations.rb +8 -4
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +61 -32
- data/lib/sequel/plugins/prepared_statements.rb +1 -1
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
- data/lib/sequel/plugins/subset_conditions.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +5 -3
- data/lib/sequel/plugins/validation_helpers.rb +2 -2
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +40 -0
- data/spec/core/database_spec.rb +73 -2
- data/spec/core/schema_spec.rb +7 -1
- data/spec/extensions/class_table_inheritance_spec.rb +30 -8
- data/spec/extensions/constraint_validations_spec.rb +20 -2
- data/spec/extensions/core_refinements_spec.rb +1 -1
- data/spec/extensions/hook_class_methods_spec.rb +22 -0
- data/spec/extensions/migration_spec.rb +13 -0
- data/spec/extensions/pg_auto_constraint_validations_spec.rb +8 -0
- data/spec/extensions/pg_enum_spec.rb +5 -0
- data/spec/extensions/s_spec.rb +1 -1
- data/spec/extensions/schema_dumper_spec.rb +4 -2
- data/spec/integration/plugin_test.rb +15 -0
- data/spec/integration/transaction_test.rb +50 -0
- data/spec/model/associations_spec.rb +84 -4
- data/spec/model/plugins_spec.rb +111 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e092b5439a78eec1bb50a0bbc8a62c1d84ee5b27b9c5f034c250b632d03e17af
|
4
|
+
data.tar.gz: 231708d52405407b11113c55d5fdcd95e7d6155b0a8283f736876569ced6e4b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c2d7e19056e53f2d780f57f5da3c4675531f9678c6a54e922e0d59895bd2e485f12ee0b2644ed801c832a53653f75531d849cb7d60dcd9fb6a4edbfa8cb4c0b
|
7
|
+
data.tar.gz: 701b041185cc57c1966ea3b4be040e26a9e0aabfd6df45f0192f5b0b51133bfb94629f0634fa6edfc513a1c9193d455cb6222b388683d638e474b344e663ca50
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,43 @@
|
|
1
|
+
=== 5.20.0 (2019-05-01)
|
2
|
+
|
3
|
+
* Fix reversing of alter_table add_foreign_key when :type option is used (jeremyevans) (#1615)
|
4
|
+
|
5
|
+
* Switch from using instance_exec to define_method for model associations and in some plugins (jeremyevans)
|
6
|
+
|
7
|
+
* Fix Database#server_version when using mysql2 adapter with mysql driver on MariaDB 10+ database (v-kolesnikov) (#1614)
|
8
|
+
|
9
|
+
* Make one_to_one setter method handle models that use joined datasets (jeremyevans) (#1612)
|
10
|
+
|
11
|
+
* Make auto_validations plugin work with the class_table_inheritance plugin (jeremyevans) (#1611)
|
12
|
+
|
13
|
+
* Avoid use of instance_exec for PlaceholderLiteralString#with_dataset (jeremyevans)
|
14
|
+
|
15
|
+
* Recognize float unsigned database types as float (keeguon, jeremyevans) (#1609)
|
16
|
+
|
17
|
+
* Support :savepoint options to Database#{after_commit,after_rollback} for making the hooks handle savepoints (jeremyevans)
|
18
|
+
|
19
|
+
* Avoid use of instance_exec in association_dependencies plugin (jeremyevans)
|
20
|
+
|
21
|
+
* Add pg_auto_constraint_validation_override to the pg_auto_constraint_validations plugin, for customizing columns and error message per constraint (jeremyevans)
|
22
|
+
|
23
|
+
* Make Database#check_constraints on PostgreSQL also include constraints where the related columns are not known (jeremyevans)
|
24
|
+
|
25
|
+
=== 5.19.0 (2019-04-02)
|
26
|
+
|
27
|
+
* Use more optimized approach to merging hashes in ruby 2.5+ (jeremyevans)
|
28
|
+
|
29
|
+
* Use SQLite extended result codes when using ruby-sqlite3 1.4.0+ (jeremyevans)
|
30
|
+
|
31
|
+
* Recognize additional SQLite extended result codes in the shared sqlite adapter (jeremyevans)
|
32
|
+
|
33
|
+
* Add Database#rename_enum_value to the pg_enum extension (AlexWayfer) (#1603)
|
34
|
+
|
35
|
+
* Make Database#drop_table delete constraint validations metadata for that table if using the constraint_validations extension (jeremyevans)
|
36
|
+
|
37
|
+
* Speed up row fetching in the sqlite adapter (jeremyevans)
|
38
|
+
|
39
|
+
* Speed up row fetching and type conversion in the sqlanywhere adapter (jeremyevans)
|
40
|
+
|
1
41
|
=== 5.18.0 (2019-03-01)
|
2
42
|
|
3
43
|
* Use singleton .call methods on plain objects instead of procs/methods for faster type conversion (jeremyevans)
|
data/doc/opening_databases.rdoc
CHANGED
@@ -187,9 +187,8 @@ For Derby, H2, HSQLDB, JTDS, MySQL, Postgres, SQLite3
|
|
187
187
|
the adapters can use the `jdbc-*` gem, for the others you need to have the `.jar` in your CLASSPATH
|
188
188
|
or load the Java class manually before calling Sequel.connect.
|
189
189
|
|
190
|
-
|
191
190
|
Note that when using a JDBC adapter, the best way to use Sequel
|
192
|
-
is via Sequel.connect, NOT Sequel.jdbc. Use the JDBC connection
|
191
|
+
is via Sequel.connect using a connection string, NOT Sequel.jdbc. Use the JDBC connection
|
193
192
|
string when connecting, which will be in a different format than
|
194
193
|
the native connection string. The connection string should start
|
195
194
|
with 'jdbc:'. For PostgreSQL, use 'jdbc:postgresql:', and for
|
@@ -201,6 +200,10 @@ Sequel does no preprocessing of JDBC connection strings, it passes them directly
|
|
201
200
|
So if you have problems getting a connection string to work, look up the
|
202
201
|
documentation for the JDBC driver.
|
203
202
|
|
203
|
+
The jdbc adapter does not handle common options such as +:host+,
|
204
|
+
+:user+, and +:port+. If you must use a hash of options when connecting,
|
205
|
+
provide the full JDBC connection string as the :uri option.
|
206
|
+
|
204
207
|
Example connection strings:
|
205
208
|
|
206
209
|
jdbc:sqlite::memory:
|
@@ -0,0 +1,28 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* A Database#rename_enum_value method has been added to the pg_enum
|
4
|
+
extension. It is supported on PostgreSQL 10+:
|
5
|
+
|
6
|
+
DB.rename_enum_value(:enum_type, 'old_name', 'new_name')
|
7
|
+
|
8
|
+
= Other Improvements
|
9
|
+
|
10
|
+
* The performance of row fetching and type conversion in the
|
11
|
+
sqlanywhere adapter has been improved.
|
12
|
+
|
13
|
+
* The performance of row fetching in the sqlite adapter has been
|
14
|
+
improved.
|
15
|
+
|
16
|
+
* Calling Database#drop_table now drops any constraint validations
|
17
|
+
metadata for the table if using the constraint_validations
|
18
|
+
extension. However, modifying the table using Database#alter_table
|
19
|
+
does not affect the constraint validations metadata.
|
20
|
+
|
21
|
+
* The sqlite adapter when used with ruby-sqlite3 1.4.0+ now uses
|
22
|
+
SQLite extended result codes for a more accurate determination of
|
23
|
+
specific database errors types.
|
24
|
+
|
25
|
+
* Performance for typecasting to decimal and floats has been improved
|
26
|
+
slightly.
|
27
|
+
|
28
|
+
* Performance when merging hashes has been improved slightly.
|
@@ -0,0 +1,89 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* Database#after_commit and #after_rollback transaction hook methods
|
4
|
+
now support a :savepoint option. Using the :savepoint option makes
|
5
|
+
the hooks savepoint-aware, so after_commit will only be called if
|
6
|
+
all enclosing savepoints and the transaction are committed, and
|
7
|
+
after_rollback will be called when any of the enclosing savepoints
|
8
|
+
are rolled back (which may be before transaction commit/rollback).
|
9
|
+
Examples:
|
10
|
+
|
11
|
+
x = nil
|
12
|
+
DB.transaction do # BEGIN
|
13
|
+
DB.transaction(savepoint: true) do # SAVEPOINT
|
14
|
+
DB.after_commit(savepoint: true){x = 1}
|
15
|
+
DB.after_rollback(savepoint: true){x = 2}
|
16
|
+
x # nil
|
17
|
+
end # RELEASE SAVEPOINT
|
18
|
+
x # nil
|
19
|
+
end # COMMIT
|
20
|
+
x # 1
|
21
|
+
|
22
|
+
x = nil
|
23
|
+
DB.transaction do # BEGIN
|
24
|
+
DB.transaction(savepoint: true) do # SAVEPOINT
|
25
|
+
DB.after_commit(savepoint: true){x = 1}
|
26
|
+
DB.after_rollback(savepoint: true){x = 2}
|
27
|
+
x # nil
|
28
|
+
raise Sequel::Rollback
|
29
|
+
end # ROLLBACK TO SAVEPOINT
|
30
|
+
x # 2
|
31
|
+
end # COMMIT
|
32
|
+
x # 2
|
33
|
+
|
34
|
+
x = nil
|
35
|
+
DB.transaction do # BEGIN
|
36
|
+
DB.transaction(savepoint: true) do # SAVEPOINT
|
37
|
+
DB.after_commit(savepoint: true){x = 1}
|
38
|
+
DB.after_rollback(savepoint: true){x = 2}
|
39
|
+
end # RELEASE SAVEPOINT
|
40
|
+
x # nil
|
41
|
+
raise Sequel::Rollback
|
42
|
+
end
|
43
|
+
x # 2
|
44
|
+
|
45
|
+
* The pg_auto_constraint_validations plugin now supports a
|
46
|
+
pg_auto_constraint_validation_override method for overriding
|
47
|
+
the columns and message for a specific constraint. This is
|
48
|
+
useful if the database cannot determine the columns (due
|
49
|
+
to the constraint containing a database function call), or
|
50
|
+
if you would like to customize the message per constraint.
|
51
|
+
|
52
|
+
= Other Improvements
|
53
|
+
|
54
|
+
* The one_to_one association setter now works with models that use
|
55
|
+
joined datasets, such as child models when using the
|
56
|
+
class_table_inheritance plugin.
|
57
|
+
|
58
|
+
* Database#check_constraints on PostgreSQL now also includes CHECK
|
59
|
+
constraints where the related columns are not known. The :columns
|
60
|
+
entry in the hash will be an empty array in such cases. The
|
61
|
+
exclusion of such constraints in previous versions was not
|
62
|
+
intentional, and the documentation implied that all CHECK
|
63
|
+
constraints were returned.
|
64
|
+
|
65
|
+
* Many cases where instance_exec was previously used on model
|
66
|
+
instances have been changed so that instance methods are defined
|
67
|
+
and called instead. This avoids the creation of singleton classes
|
68
|
+
for model instances, and can significantly improve performance in
|
69
|
+
some cases. This affects all associations as well as the
|
70
|
+
following plugins:
|
71
|
+
|
72
|
+
* composition
|
73
|
+
* hook_class_methods
|
74
|
+
* validation_class_methods
|
75
|
+
|
76
|
+
Other cases where instance_exec is now avoided and a different
|
77
|
+
approach is used:
|
78
|
+
|
79
|
+
* association_dependencies plugin
|
80
|
+
* PlaceholderLiteralString#with_dataset
|
81
|
+
|
82
|
+
* The auto_validations plugin now works with child models when using
|
83
|
+
the class_table_inheritance plugin.
|
84
|
+
|
85
|
+
* Database#server_version now works correctly in the mysql2 adapter
|
86
|
+
when using the MySQL driver with MariaDB 10+.
|
87
|
+
|
88
|
+
* The float unsigned type is now recognized and supported in the
|
89
|
+
schema parser and schema_dumper extension.
|
data/doc/sharding.rdoc
CHANGED
@@ -268,3 +268,15 @@ the Database, just remove that option. If you are setting:
|
|
268
268
|
Sequel.single_threaded = true
|
269
269
|
|
270
270
|
just remove or comment out that code.
|
271
|
+
|
272
|
+
== JDBC
|
273
|
+
|
274
|
+
If you are using the jdbc adapter, note that it does not handle separate
|
275
|
+
options such as +:host+, +:user+, and +:port+. If you would like to use
|
276
|
+
the +:servers+ option when connecting to a JDBC database, each hash value in
|
277
|
+
the +servers+ option should contain a +:uri+ key with a JDBC connection string
|
278
|
+
for that shard as the value. Example:
|
279
|
+
|
280
|
+
DB=Sequel.connect('jdbc:postgresql://primary_server/database',
|
281
|
+
servers: {read_only: {uri: 'jdbc:postgresql://replica_server/database'}})
|
282
|
+
|
data/doc/transactions.rdoc
CHANGED
@@ -169,6 +169,44 @@ If you want the current savepoint and potentially enclosing savepoints to be rol
|
|
169
169
|
end # ROLLBACK TO SAVEPOINT
|
170
170
|
end # ROLLBACK
|
171
171
|
|
172
|
+
=== Savepoint Hooks
|
173
|
+
|
174
|
+
When using savepoints, you can use the +:savepoint+ option to +after_commit+ or +after_rollback+ to use a savepoint hook. For +after_commit+, this will only run the hook after transaction commit if all enclosing savepoints are released (not rolled back). For +after_rollback+, this will run the hook after any enclosing savepoint is rolled back (before transaction commit), or after the transaction is rolled back if all enclosing savepoints are released:
|
175
|
+
|
176
|
+
x = nil
|
177
|
+
DB.transaction do # BEGIN
|
178
|
+
DB.transaction(savepoint: true) do # SAVEPOINT
|
179
|
+
DB.after_commit(savepoint: true){x = 1}
|
180
|
+
DB.after_rollback(savepoint: true){x = 2}
|
181
|
+
x # nil
|
182
|
+
end # RELEASE SAVEPOINT
|
183
|
+
x # nil
|
184
|
+
end # COMMIT
|
185
|
+
x # 1
|
186
|
+
|
187
|
+
x = nil
|
188
|
+
DB.transaction do # BEGIN
|
189
|
+
DB.transaction(savepoint: true) do # SAVEPOINT
|
190
|
+
DB.after_commit(savepoint: true){x = 1}
|
191
|
+
DB.after_rollback(savepoint: true){x = 2}
|
192
|
+
x # nil
|
193
|
+
raise Sequel::Rollback
|
194
|
+
end # ROLLBACK TO SAVEPOINT
|
195
|
+
x # 2
|
196
|
+
end # COMMIT
|
197
|
+
x # 2
|
198
|
+
|
199
|
+
x = nil
|
200
|
+
DB.transaction do # BEGIN
|
201
|
+
DB.transaction(savepoint: true) do # SAVEPOINT
|
202
|
+
DB.after_commit(savepoint: true){x = 1}
|
203
|
+
DB.after_rollback(savepoint: true){x = 2}
|
204
|
+
end # RELEASE SAVEPOINT
|
205
|
+
x # nil
|
206
|
+
raise Sequel::Rollback
|
207
|
+
end
|
208
|
+
x # 2
|
209
|
+
|
172
210
|
== Prepared Transactions / Two-Phase Commit
|
173
211
|
|
174
212
|
Sequel supports database prepared transactions on PostgreSQL, MySQL, and H2. With prepared transactions, at the end of the transaction, the transaction is not immediately committed (it acts like a rollback). Later, you can call +commit_prepared_transaction+ to commit the transaction or +rollback_prepared_transaction+ to roll the transaction back. Prepared transactions are usually used with distributed databases to make sure all databases commit the same transaction or none of them do.
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -254,7 +254,9 @@ module Sequel
|
|
254
254
|
log_connection_yield(sql, conn){stmt.execute(sql)}
|
255
255
|
when :insert
|
256
256
|
log_connection_yield(sql, conn){execute_statement_insert(stmt, sql)}
|
257
|
-
|
257
|
+
opts = Hash[opts]
|
258
|
+
opts[:stmt] = stmt
|
259
|
+
last_insert_id(conn, opts)
|
258
260
|
else
|
259
261
|
log_connection_yield(sql, conn){stmt.executeUpdate(sql)}
|
260
262
|
end
|
@@ -449,7 +451,10 @@ module Sequel
|
|
449
451
|
log_connection_yield(msg, conn, args){cps.execute}
|
450
452
|
when :insert
|
451
453
|
log_connection_yield(msg, conn, args){execute_prepared_statement_insert(cps)}
|
452
|
-
|
454
|
+
opts = Hash[opts]
|
455
|
+
opts[:prepared] = true
|
456
|
+
opts[:stmt] = cps
|
457
|
+
last_insert_id(conn, opts)
|
453
458
|
else
|
454
459
|
log_connection_yield(msg, conn, args){cps.executeUpdate}
|
455
460
|
end
|
@@ -78,8 +78,8 @@ module Sequel
|
|
78
78
|
end
|
79
79
|
|
80
80
|
# Return the version of the MySQL server to which we are connecting.
|
81
|
-
def server_version(
|
82
|
-
@server_version ||= (
|
81
|
+
def server_version(_server=nil)
|
82
|
+
@server_version ||= super()
|
83
83
|
end
|
84
84
|
|
85
85
|
private
|
@@ -220,24 +220,22 @@ module Sequel
|
|
220
220
|
# A hash of metadata for CHECK constraints on the table.
|
221
221
|
# Keys are CHECK constraint name symbols. Values are hashes with the following keys:
|
222
222
|
# :definition :: An SQL fragment for the definition of the constraint
|
223
|
-
# :columns :: An array of column symbols for the columns referenced in the constraint
|
223
|
+
# :columns :: An array of column symbols for the columns referenced in the constraint,
|
224
|
+
# can be an empty array if the database cannot deteremine the column symbols.
|
224
225
|
def check_constraints(table)
|
225
226
|
m = output_identifier_meth
|
226
227
|
|
227
228
|
rows = metadata_dataset.
|
228
229
|
from{pg_constraint.as(:co)}.
|
229
|
-
|
230
|
+
left_join(Sequel[:pg_attribute].as(:att), :attrelid=>:conrelid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:conkey])).
|
230
231
|
where(:conrelid=>regclass_oid(table), :contype=>'c').
|
231
232
|
select{[co[:conname].as(:constraint), att[:attname].as(:column), pg_get_constraintdef(co[:oid]).as(:definition)]}
|
232
233
|
|
233
234
|
hash = {}
|
234
235
|
rows.each do |row|
|
235
236
|
constraint = m.call(row[:constraint])
|
236
|
-
|
237
|
-
|
238
|
-
else
|
239
|
-
hash[constraint] = {:definition=>row[:definition], :columns=>[m.call(row[:column])]}
|
240
|
-
end
|
237
|
+
entry = hash[constraint] ||= {:definition=>row[:definition], :columns=>[]}
|
238
|
+
entry[:columns] << m.call(row[:column]) if row[:column]
|
241
239
|
end
|
242
240
|
|
243
241
|
hash
|
@@ -1733,7 +1731,9 @@ module Sequel
|
|
1733
1731
|
def _import(columns, values, opts=OPTS)
|
1734
1732
|
if @opts[:returning]
|
1735
1733
|
statements = multi_insert_sql(columns, values)
|
1736
|
-
|
1734
|
+
trans_opts = Hash[opts]
|
1735
|
+
trans_opts[:server] = @opts[:server]
|
1736
|
+
@db.transaction(trans_opts) do
|
1737
1737
|
statements.map{|st| returning_fetch_rows(st)}
|
1738
1738
|
end.first.map{|v| v.length == 1 ? v.values.first : v}
|
1739
1739
|
elsif opts[:return] == :primary_key
|
@@ -323,7 +323,7 @@ module Sequel
|
|
323
323
|
case sqlite_error_code(exception)
|
324
324
|
when 1299
|
325
325
|
NotNullConstraintViolation
|
326
|
-
when 2067
|
326
|
+
when 1555, 2067, 2579
|
327
327
|
UniqueConstraintViolation
|
328
328
|
when 787
|
329
329
|
ForeignKeyConstraintViolation
|
@@ -331,6 +331,8 @@ module Sequel
|
|
331
331
|
CheckConstraintViolation
|
332
332
|
when 19
|
333
333
|
ConstraintViolation
|
334
|
+
when 517
|
335
|
+
SerializationFailure
|
334
336
|
else
|
335
337
|
super
|
336
338
|
end
|
@@ -17,21 +17,34 @@ module Sequel
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
boolean = Object.new
|
21
|
+
def boolean.call(s)
|
22
|
+
s.to_i != 0
|
23
|
+
end
|
24
|
+
|
25
|
+
date = Object.new
|
26
|
+
def date.call(s)
|
27
|
+
::Date.strptime(s)
|
28
|
+
end
|
29
|
+
|
30
|
+
decimal = Object.new
|
31
|
+
class << decimal
|
32
|
+
alias call BigDecimal
|
33
|
+
public :call
|
34
|
+
end
|
35
|
+
|
36
|
+
time = Object.new
|
37
|
+
def time.call(s)
|
38
|
+
::Sequel.string_to_time(s)
|
39
|
+
end
|
27
40
|
|
28
41
|
SQLANYWHERE_TYPES = {}
|
29
42
|
{
|
30
|
-
[0, 484] =>
|
31
|
-
[384] =>
|
32
|
-
[388] =>
|
33
|
-
[500] =>
|
34
|
-
[524, 528] =>
|
43
|
+
[0, 484] => decimal,
|
44
|
+
[384] => date,
|
45
|
+
[388] => time,
|
46
|
+
[500] => boolean,
|
47
|
+
[524, 528] => ::Sequel::SQL::Blob
|
35
48
|
}.each do |k,v|
|
36
49
|
k.each{|n| SQLANYWHERE_TYPES[n] = v}
|
37
50
|
end
|
@@ -153,17 +166,20 @@ module Sequel
|
|
153
166
|
else
|
154
167
|
cps[type]
|
155
168
|
end
|
156
|
-
col_infos << [
|
169
|
+
col_infos << [output_identifier(name), cp]
|
157
170
|
end
|
158
171
|
|
159
|
-
self.columns = col_infos.map
|
172
|
+
self.columns = col_infos.map(&:first)
|
173
|
+
max = col_infos.length
|
160
174
|
|
161
175
|
if rs
|
162
176
|
while api.sqlany_fetch_next(rs) == 1
|
177
|
+
i = -1
|
163
178
|
h = {}
|
164
|
-
|
165
|
-
|
166
|
-
|
179
|
+
while (i+=1) < max
|
180
|
+
name, cp = col_infos[i]
|
181
|
+
v = api.sqlany_get_column(rs, i)[1]
|
182
|
+
h[name] = cp && v ? cp.call(v) : v
|
167
183
|
end
|
168
184
|
yield h
|
169
185
|
end
|
@@ -5,7 +5,7 @@ require_relative 'shared/sqlite'
|
|
5
5
|
|
6
6
|
module Sequel
|
7
7
|
module SQLite
|
8
|
-
FALSE_VALUES = (%w'0 false f no n' + [0]).freeze
|
8
|
+
FALSE_VALUES = (%w'0 false f no n'.each(&:freeze) + [0]).freeze
|
9
9
|
|
10
10
|
blob = Object.new
|
11
11
|
def blob.call(s)
|
@@ -77,6 +77,10 @@ module Sequel
|
|
77
77
|
k.each{|n| SQLITE_TYPES[n] = v}
|
78
78
|
end
|
79
79
|
SQLITE_TYPES.freeze
|
80
|
+
|
81
|
+
sqlite_version = SQLite3::VERSION.split('.').map(&:to_i)[0..1]
|
82
|
+
sqlite_version = sqlite_version[0] * 100 + sqlite_version[1]
|
83
|
+
USE_EXTENDED_RESULT_CODES = sqlite_version >= 104
|
80
84
|
|
81
85
|
class Database < Sequel::Database
|
82
86
|
include ::Sequel::SQLite::DatabaseMethods
|
@@ -109,6 +113,10 @@ module Sequel
|
|
109
113
|
sqlite3_opts[:readonly] = typecast_value_boolean(opts[:readonly]) if opts.has_key?(:readonly)
|
110
114
|
db = ::SQLite3::Database.new(opts[:database].to_s, sqlite3_opts)
|
111
115
|
db.busy_timeout(opts.fetch(:timeout, 5000))
|
116
|
+
|
117
|
+
if USE_EXTENDED_RESULT_CODES
|
118
|
+
db.extended_result_codes = true
|
119
|
+
end
|
112
120
|
|
113
121
|
connection_pragmas.each{|s| log_connection_yield(s, db){db.execute_batch(s)}}
|
114
122
|
|
@@ -279,13 +287,12 @@ module Sequel
|
|
279
287
|
Dataset
|
280
288
|
end
|
281
289
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
#end
|
290
|
+
if USE_EXTENDED_RESULT_CODES
|
291
|
+
# Support SQLite exception codes if ruby-sqlite3 supports them.
|
292
|
+
def sqlite_error_code(exception)
|
293
|
+
exception.code if exception.respond_to?(:code)
|
294
|
+
end
|
295
|
+
end
|
289
296
|
end
|
290
297
|
|
291
298
|
class Dataset < Sequel::Dataset
|
@@ -318,18 +325,18 @@ module Sequel
|
|
318
325
|
|
319
326
|
def fetch_rows(sql)
|
320
327
|
execute(sql) do |result|
|
321
|
-
i = -1
|
322
328
|
cps = db.conversion_procs
|
323
329
|
type_procs = result.types.map{|t| cps[base_type_name(t)]}
|
324
|
-
|
325
|
-
|
330
|
+
j = -1
|
331
|
+
cols = result.columns.map{|c| [output_identifier(c), type_procs[(j+=1)]]}
|
326
332
|
self.columns = cols.map(&:first)
|
333
|
+
max = cols.length
|
327
334
|
result.each do |values|
|
328
335
|
row = {}
|
329
336
|
i = -1
|
330
337
|
while (i += 1) < max
|
331
|
-
name,
|
332
|
-
v = values[
|
338
|
+
name, type_proc = cols[i]
|
339
|
+
v = values[i]
|
333
340
|
if type_proc && v
|
334
341
|
v = type_proc.call(v)
|
335
342
|
end
|