sequel 5.39.0 → 5.72.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +408 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +59 -27
- data/bin/sequel +11 -3
- data/doc/advanced_associations.rdoc +16 -14
- data/doc/association_basics.rdoc +119 -24
- data/doc/cheat_sheet.rdoc +11 -3
- data/doc/mass_assignment.rdoc +1 -1
- data/doc/migration.rdoc +13 -6
- data/doc/model_hooks.rdoc +1 -1
- data/doc/object_model.rdoc +8 -8
- data/doc/opening_databases.rdoc +26 -12
- data/doc/postgresql.rdoc +16 -8
- data/doc/querying.rdoc +5 -3
- data/doc/release_notes/5.40.0.txt +40 -0
- data/doc/release_notes/5.41.0.txt +25 -0
- data/doc/release_notes/5.42.0.txt +136 -0
- data/doc/release_notes/5.43.0.txt +98 -0
- data/doc/release_notes/5.44.0.txt +32 -0
- data/doc/release_notes/5.45.0.txt +34 -0
- data/doc/release_notes/5.46.0.txt +87 -0
- data/doc/release_notes/5.47.0.txt +59 -0
- data/doc/release_notes/5.48.0.txt +14 -0
- data/doc/release_notes/5.49.0.txt +59 -0
- data/doc/release_notes/5.50.0.txt +78 -0
- data/doc/release_notes/5.51.0.txt +47 -0
- data/doc/release_notes/5.52.0.txt +87 -0
- data/doc/release_notes/5.53.0.txt +23 -0
- data/doc/release_notes/5.54.0.txt +27 -0
- data/doc/release_notes/5.55.0.txt +21 -0
- data/doc/release_notes/5.56.0.txt +51 -0
- data/doc/release_notes/5.57.0.txt +23 -0
- data/doc/release_notes/5.58.0.txt +31 -0
- data/doc/release_notes/5.59.0.txt +73 -0
- data/doc/release_notes/5.60.0.txt +22 -0
- data/doc/release_notes/5.61.0.txt +43 -0
- data/doc/release_notes/5.62.0.txt +132 -0
- data/doc/release_notes/5.63.0.txt +33 -0
- data/doc/release_notes/5.64.0.txt +50 -0
- data/doc/release_notes/5.65.0.txt +21 -0
- data/doc/release_notes/5.66.0.txt +24 -0
- data/doc/release_notes/5.67.0.txt +32 -0
- data/doc/release_notes/5.68.0.txt +61 -0
- data/doc/release_notes/5.69.0.txt +26 -0
- data/doc/release_notes/5.70.0.txt +35 -0
- data/doc/release_notes/5.71.0.txt +21 -0
- data/doc/release_notes/5.72.0.txt +33 -0
- data/doc/schema_modification.rdoc +1 -1
- data/doc/security.rdoc +9 -9
- data/doc/sharding.rdoc +3 -1
- data/doc/sql.rdoc +28 -16
- data/doc/testing.rdoc +22 -11
- data/doc/transactions.rdoc +6 -6
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/access.rb +1 -1
- data/lib/sequel/adapters/ado.rb +17 -17
- data/lib/sequel/adapters/amalgalite.rb +3 -5
- data/lib/sequel/adapters/ibmdb.rb +2 -2
- data/lib/sequel/adapters/jdbc/derby.rb +8 -0
- data/lib/sequel/adapters/jdbc/h2.rb +60 -10
- data/lib/sequel/adapters/jdbc/hsqldb.rb +6 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +7 -4
- data/lib/sequel/adapters/jdbc.rb +16 -18
- data/lib/sequel/adapters/mysql.rb +92 -67
- data/lib/sequel/adapters/mysql2.rb +54 -49
- data/lib/sequel/adapters/odbc.rb +6 -2
- data/lib/sequel/adapters/oracle.rb +4 -3
- data/lib/sequel/adapters/postgres.rb +83 -40
- data/lib/sequel/adapters/shared/access.rb +11 -1
- data/lib/sequel/adapters/shared/db2.rb +30 -0
- data/lib/sequel/adapters/shared/mssql.rb +90 -9
- data/lib/sequel/adapters/shared/mysql.rb +47 -2
- data/lib/sequel/adapters/shared/oracle.rb +82 -1
- data/lib/sequel/adapters/shared/postgres.rb +496 -178
- data/lib/sequel/adapters/shared/sqlanywhere.rb +11 -1
- data/lib/sequel/adapters/shared/sqlite.rb +116 -11
- data/lib/sequel/adapters/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +60 -18
- data/lib/sequel/adapters/tinytds.rb +1 -1
- data/lib/sequel/adapters/trilogy.rb +117 -0
- data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/ast_transformer.rb +6 -0
- data/lib/sequel/connection_pool/sharded_single.rb +5 -7
- data/lib/sequel/connection_pool/sharded_threaded.rb +16 -11
- data/lib/sequel/connection_pool/sharded_timed_queue.rb +374 -0
- data/lib/sequel/connection_pool/single.rb +6 -8
- data/lib/sequel/connection_pool/threaded.rb +14 -8
- data/lib/sequel/connection_pool/timed_queue.rb +270 -0
- data/lib/sequel/connection_pool.rb +55 -31
- data/lib/sequel/core.rb +28 -18
- data/lib/sequel/database/connecting.rb +27 -3
- data/lib/sequel/database/dataset.rb +16 -6
- data/lib/sequel/database/misc.rb +69 -14
- data/lib/sequel/database/query.rb +73 -2
- data/lib/sequel/database/schema_generator.rb +46 -53
- data/lib/sequel/database/schema_methods.rb +18 -2
- data/lib/sequel/dataset/actions.rb +108 -14
- data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
- data/lib/sequel/dataset/features.rb +20 -0
- data/lib/sequel/dataset/misc.rb +12 -2
- data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
- data/lib/sequel/dataset/prepared_statements.rb +2 -0
- data/lib/sequel/dataset/query.rb +171 -44
- data/lib/sequel/dataset/sql.rb +182 -47
- data/lib/sequel/dataset.rb +4 -0
- data/lib/sequel/extensions/_model_pg_row.rb +0 -12
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/any_not_empty.rb +1 -1
- data/lib/sequel/extensions/async_thread_pool.rb +439 -0
- data/lib/sequel/extensions/auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/blank.rb +8 -0
- data/lib/sequel/extensions/connection_expiration.rb +15 -9
- data/lib/sequel/extensions/connection_validator.rb +16 -11
- data/lib/sequel/extensions/constraint_validations.rb +1 -1
- data/lib/sequel/extensions/core_refinements.rb +36 -11
- data/lib/sequel/extensions/date_arithmetic.rb +71 -31
- data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
- data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
- data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
- data/lib/sequel/extensions/eval_inspect.rb +2 -0
- data/lib/sequel/extensions/index_caching.rb +5 -1
- data/lib/sequel/extensions/inflector.rb +9 -1
- data/lib/sequel/extensions/is_distinct_from.rb +141 -0
- data/lib/sequel/extensions/looser_typecasting.rb +3 -0
- data/lib/sequel/extensions/migration.rb +11 -2
- data/lib/sequel/extensions/named_timezones.rb +26 -6
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +32 -4
- data/lib/sequel/extensions/pg_array_ops.rb +2 -2
- data/lib/sequel/extensions/pg_auto_parameterize.rb +509 -0
- data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +110 -0
- data/lib/sequel/extensions/pg_enum.rb +2 -3
- data/lib/sequel/extensions/pg_extended_date_support.rb +38 -27
- data/lib/sequel/extensions/pg_extended_integer_support.rb +116 -0
- data/lib/sequel/extensions/pg_hstore.rb +6 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +53 -3
- data/lib/sequel/extensions/pg_inet.rb +10 -11
- data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
- data/lib/sequel/extensions/pg_interval.rb +45 -19
- data/lib/sequel/extensions/pg_json.rb +13 -15
- data/lib/sequel/extensions/pg_json_ops.rb +73 -2
- data/lib/sequel/extensions/pg_loose_count.rb +3 -1
- data/lib/sequel/extensions/pg_multirange.rb +367 -0
- data/lib/sequel/extensions/pg_range.rb +11 -24
- data/lib/sequel/extensions/pg_range_ops.rb +37 -9
- data/lib/sequel/extensions/pg_row.rb +21 -19
- data/lib/sequel/extensions/pg_row_ops.rb +1 -1
- data/lib/sequel/extensions/query.rb +2 -0
- data/lib/sequel/extensions/s.rb +2 -1
- data/lib/sequel/extensions/schema_caching.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +45 -11
- data/lib/sequel/extensions/server_block.rb +10 -13
- data/lib/sequel/extensions/set_literalizer.rb +58 -0
- data/lib/sequel/extensions/sql_comments.rb +110 -3
- data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
- data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
- data/lib/sequel/extensions/string_agg.rb +1 -1
- data/lib/sequel/extensions/string_date_time.rb +19 -23
- data/lib/sequel/extensions/symbol_aref.rb +2 -0
- data/lib/sequel/model/associations.rb +345 -101
- data/lib/sequel/model/base.rb +51 -27
- data/lib/sequel/model/dataset_module.rb +3 -0
- data/lib/sequel/model/errors.rb +10 -1
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model/plugins.rb +5 -0
- data/lib/sequel/plugins/association_proxies.rb +2 -0
- data/lib/sequel/plugins/async_thread_pool.rb +39 -0
- data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
- data/lib/sequel/plugins/auto_validations.rb +87 -15
- data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/column_encryption.rb +728 -0
- data/lib/sequel/plugins/composition.rb +10 -4
- data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
- data/lib/sequel/plugins/constraint_validations.rb +10 -6
- data/lib/sequel/plugins/dataset_associations.rb +4 -1
- data/lib/sequel/plugins/defaults_setter.rb +16 -0
- data/lib/sequel/plugins/dirty.rb +1 -1
- data/lib/sequel/plugins/enum.rb +124 -0
- data/lib/sequel/plugins/finder.rb +4 -2
- data/lib/sequel/plugins/insert_conflict.rb +4 -0
- data/lib/sequel/plugins/instance_specific_default.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +39 -24
- data/lib/sequel/plugins/lazy_attributes.rb +3 -0
- data/lib/sequel/plugins/list.rb +3 -1
- data/lib/sequel/plugins/many_through_many.rb +109 -10
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -38
- data/lib/sequel/plugins/nested_attributes.rb +12 -7
- data/lib/sequel/plugins/optimistic_locking.rb +9 -42
- data/lib/sequel/plugins/optimistic_locking_base.rb +55 -0
- data/lib/sequel/plugins/pg_array_associations.rb +56 -38
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +11 -3
- data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
- data/lib/sequel/plugins/prepared_statements.rb +12 -2
- data/lib/sequel/plugins/prepared_statements_safe.rb +2 -1
- data/lib/sequel/plugins/primary_key_lookup_check_values.rb +154 -0
- data/lib/sequel/plugins/rcte_tree.rb +27 -19
- data/lib/sequel/plugins/require_valid_schema.rb +67 -0
- data/lib/sequel/plugins/serialization.rb +9 -3
- data/lib/sequel/plugins/serialization_modification_detection.rb +2 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +8 -0
- data/lib/sequel/plugins/sql_comments.rb +189 -0
- data/lib/sequel/plugins/static_cache.rb +39 -1
- data/lib/sequel/plugins/static_cache_cache.rb +5 -1
- data/lib/sequel/plugins/subclasses.rb +28 -11
- data/lib/sequel/plugins/tactical_eager_loading.rb +23 -10
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/unused_associations.rb +521 -0
- data/lib/sequel/plugins/update_or_create.rb +1 -1
- data/lib/sequel/plugins/validate_associated.rb +22 -12
- data/lib/sequel/plugins/validation_helpers.rb +46 -12
- data/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
- data/lib/sequel/plugins/xml_serializer.rb +1 -1
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/timezones.rb +12 -14
- data/lib/sequel/version.rb +1 -1
- metadata +132 -38
data/doc/sql.rdoc
CHANGED
@@ -59,7 +59,7 @@ Then, you call the +insert+, +update+, or +delete+ method on the returned datase
|
|
59
59
|
update_ds.update
|
60
60
|
delete_ds.delete
|
61
61
|
|
62
|
-
+update+ and +delete+
|
62
|
+
+update+ and +delete+ generally return the number of rows affected, and +insert+ generally returns the autogenerated primary key integer for the row inserted (if any), but not all adapters/databases support this behavior for datasets using custom SQL (notably it is not supported for +insert+ on PostgreSQL).
|
63
63
|
|
64
64
|
=== Other Queries
|
65
65
|
|
@@ -223,22 +223,22 @@ If the database supports window functions, Sequel can handle them by calling the
|
|
223
223
|
DB[:albums].select{count.function.*.over}
|
224
224
|
# SELECT count(*) OVER () FROM albums
|
225
225
|
|
226
|
-
DB[:albums].select{function(:col1).over(:
|
226
|
+
DB[:albums].select{function(:col1).over(partition: col2, order: col3)}
|
227
227
|
# SELECT function(col1) OVER (PARTITION BY col2 ORDER BY col3) FROM albums
|
228
228
|
|
229
|
-
DB[:albums].select{function(c1, c2).over(:
|
229
|
+
DB[:albums].select{function(c1, c2).over(partition: [c3, c4], order: [c5, c6.desc])}
|
230
230
|
# SELECT function(c1, c2) OVER (PARTITION BY c3, c4 ORDER BY c5, c6 DESC) FROM albums
|
231
231
|
|
232
|
-
DB[:albums].select{function(c1).over(:
|
232
|
+
DB[:albums].select{function(c1).over(partition: c2, order: :c3, frame: :rows)}
|
233
233
|
# SELECT function(c1) OVER (PARTITION BY c2 ORDER BY c3 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM albums
|
234
234
|
|
235
|
-
DB[:albums].select{function(c1).over(:
|
235
|
+
DB[:albums].select{function(c1).over(partition: c2, order: :c3, frame: {type: :range, start: 1, end: 1})}
|
236
236
|
# SELECT function(c1) OVER (PARTITION BY c2 ORDER BY c3 RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM albums
|
237
237
|
|
238
|
-
DB[:albums].select{function(c1).over(:
|
238
|
+
DB[:albums].select{function(c1).over(partition: c2, order: :c3, frame: {type: :groups, start: [2, :preceding], end: [1, :preceding]})}
|
239
239
|
# SELECT function(c1) OVER (PARTITION BY c2 ORDER BY c3 GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING) FROM albums
|
240
240
|
|
241
|
-
DB[:albums].select{function(c1).over(:
|
241
|
+
DB[:albums].select{function(c1).over(partition: c2, order: :c3, frame: {type: :range, start: :preceding, exclude: :current})}
|
242
242
|
# SELECT function(c1) OVER (PARTITION BY c2 ORDER BY c3 RANGE UNBOUNDED PRECEDING EXCLUDE CURRENT ROW) FROM albums
|
243
243
|
|
244
244
|
=== Schema Qualified Functions
|
@@ -428,6 +428,18 @@ As you can see, these literalize with ANDs by default. You can use the <tt>Sequ
|
|
428
428
|
|
429
429
|
Sequel.or(column1: 1, column2: 2) # (("column1" = 1) OR ("column2" = 2))
|
430
430
|
|
431
|
+
As you can see in the above examples, <tt>Sequel.|</tt> and <tt>Sequel.or</tt> work differently.
|
432
|
+
<tt>Sequel.|</tt> is for combining an arbitrary number of expressions using OR. If you pass a single
|
433
|
+
argument, <tt>Sequel.|</tt> will just convert it to a Sequel expression, similar to <tt>Sequel.expr</tt>.
|
434
|
+
<tt>Sequel.or</tt> is for taking a single hash or array of two element arrays and combining the
|
435
|
+
elements of that single argument using OR instead of AND:
|
436
|
+
|
437
|
+
Sequel.|(column1: 1, column2: 2) # (("column1" = 1) AND ("column2" = 2))
|
438
|
+
Sequel.or(column1: 1, column2: 2) # (("column1" = 1) OR ("column2" = 2))
|
439
|
+
|
440
|
+
Sequel.|({column1: 1}, {column2: 2}) # (("column1" = 1) OR ("column2" = 2))
|
441
|
+
Sequel.or({column1: 1}, {column2: 2}) # ArgumentError
|
442
|
+
|
431
443
|
You've already seen the <tt>Sequel.negate</tt> method, which will use ANDs if multiple entries are used:
|
432
444
|
|
433
445
|
Sequel.negate(column1: 1, column2: 2) # (("column1" != 1) AND ("column2" != 2))
|
@@ -516,7 +528,7 @@ Inverting the LIKE operator works like other inversions:
|
|
516
528
|
|
517
529
|
~Sequel.like(:name, 'A%') # ("name" NOT LIKE 'A%' ESCAPE '\')
|
518
530
|
|
519
|
-
Sequel also supports SQL regular expressions on MySQL and PostgreSQL. You can use these by passing a Ruby regular expression to +like+ or +ilike+, or by making the regular expression a hash value:
|
531
|
+
Sequel also supports SQL regular expressions on MySQL and PostgreSQL (and SQLite when using the sqlite adapter with the :setup_regexp_function Database option). You can use these by passing a Ruby regular expression to +like+ or +ilike+, or by making the regular expression a hash value:
|
520
532
|
|
521
533
|
Sequel.like(:name, /^A/) # ("name" ~ '^A')
|
522
534
|
~Sequel.ilike(:name, /^A/) # ("name" !~* '^A')
|
@@ -539,12 +551,12 @@ You can also use the <tt>Sequel.asc</tt> and <tt>Sequel.desc</tt> methods:
|
|
539
551
|
|
540
552
|
On some databases, you can specify null ordering:
|
541
553
|
|
542
|
-
Sequel.asc(:column, :
|
543
|
-
Sequel.desc(Sequel[:table][:column], :
|
554
|
+
Sequel.asc(:column, nulls: :first) # "column" ASC NULLS FIRST
|
555
|
+
Sequel.desc(Sequel[:table][:column], nulls: :last) # "table"."column" DESC NULLS LAST
|
544
556
|
|
545
557
|
=== All Columns (.*)
|
546
558
|
|
547
|
-
To select all columns in a table, Sequel supports the * method on identifiers and qualified without an argument:
|
559
|
+
To select all columns in a table, Sequel supports the * method on identifiers and qualified identifiers without an argument:
|
548
560
|
|
549
561
|
Sequel[:table].* # "table".*
|
550
562
|
Sequel[:schema][:table].* # "schema"."table".*
|
@@ -617,16 +629,16 @@ Also note that while the SELECT clause is displayed when you look at a dataset,
|
|
617
629
|
|
618
630
|
ds = DB[:albums]
|
619
631
|
ds.all # SELECT * FROM albums
|
620
|
-
ds.insert(:
|
621
|
-
ds.update(:
|
632
|
+
ds.insert(name: 'RF') # INSERT INTO albums (name) VALUES ('RF')
|
633
|
+
ds.update(name: 'RF') # UPDATE albums SET name = 'RF'
|
622
634
|
ds.delete # DELETE FROM albums
|
623
635
|
|
624
636
|
In general, the +insert+, +update+, and +delete+ methods use the appropriate clauses you defined on the dataset:
|
625
637
|
|
626
|
-
ds = DB[:albums].where(:
|
638
|
+
ds = DB[:albums].where(id: 1)
|
627
639
|
ds.all # SELECT * FROM albums WHERE (id = 1)
|
628
|
-
ds.insert(:
|
629
|
-
ds.update(:
|
640
|
+
ds.insert(name: 'RF') # INSERT INTO albums (name) VALUES ('RF')
|
641
|
+
ds.update(name: 'RF') # UPDATE albums SET name = 'RF' WHERE (id = 1)
|
630
642
|
ds.delete # DELETE FROM albums WHERE (id = 1)
|
631
643
|
|
632
644
|
Note how +update+ and +delete+ used the +where+ argument, but +insert+ did not, because INSERT doesn't use a WHERE clause.
|
data/doc/testing.rdoc
CHANGED
@@ -15,7 +15,7 @@ These run each test in its own transaction, the recommended way to test.
|
|
15
15
|
|
16
16
|
class Minitest::HooksSpec
|
17
17
|
def around
|
18
|
-
DB.transaction(:
|
18
|
+
DB.transaction(rollback: :always, auto_savepoint: true){super}
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -24,7 +24,7 @@ These run each test in its own transaction, the recommended way to test.
|
|
24
24
|
|
25
25
|
class Minitest::Spec
|
26
26
|
def run(*args, &block)
|
27
|
-
DB.transaction(:
|
27
|
+
DB.transaction(rollback: :always, auto_savepoint: true){super}
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -34,7 +34,7 @@ These run each test in its own transaction, the recommended way to test.
|
|
34
34
|
# Use this class as the base class for your tests
|
35
35
|
class SequelTestCase < Minitest::Test
|
36
36
|
def run(*args, &block)
|
37
|
-
DB.transaction(:
|
37
|
+
DB.transaction(rollback: :always, auto_savepoint: true){super}
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -43,7 +43,7 @@ These run each test in its own transaction, the recommended way to test.
|
|
43
43
|
|
44
44
|
RSpec.configure do |c|
|
45
45
|
c.around(:each) do |example|
|
46
|
-
DB.transaction(:
|
46
|
+
DB.transaction(rollback: :always, auto_savepoint: true){example.run}
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -51,11 +51,11 @@ These run each test in its own transaction, the recommended way to test.
|
|
51
51
|
|
52
52
|
You can use the Sequel.transaction method to run a transaction on multiple databases, rolling all of them back. Instead of:
|
53
53
|
|
54
|
-
DB.transaction(:
|
54
|
+
DB.transaction(rollback: :always)
|
55
55
|
|
56
56
|
Use Sequel.transaction with an array of databases:
|
57
57
|
|
58
|
-
Sequel.transaction([DB1, DB2, DB3], :
|
58
|
+
Sequel.transaction([DB1, DB2, DB3], rollback: :always)
|
59
59
|
|
60
60
|
== Transactional testing with savepoints
|
61
61
|
|
@@ -71,11 +71,11 @@ Example:
|
|
71
71
|
require 'minitest/hooks/default'
|
72
72
|
class Minitest::HooksSpec
|
73
73
|
def around
|
74
|
-
DB.transaction(:
|
74
|
+
DB.transaction(rollback: :always, savepoint: true, auto_savepoint: true){super}
|
75
75
|
end
|
76
76
|
|
77
77
|
def around_all
|
78
|
-
DB.transaction(:
|
78
|
+
DB.transaction(rollback: :always){super}
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
@@ -113,7 +113,7 @@ The order in which you delete/truncate the tables is important if you are using
|
|
113
113
|
|
114
114
|
= Testing Sequel Itself
|
115
115
|
|
116
|
-
Sequel has multiple separate test suites. All test suites use minitest/spec, with the minitest-hooks and minitest-
|
116
|
+
Sequel has multiple separate test suites. All test suites use minitest/spec, with the minitest-hooks and minitest-global_expectations extensions. To install the dependencies necessary to test Sequel, run <tt>gem install --development sequel</tt>.
|
117
117
|
|
118
118
|
== rake
|
119
119
|
|
@@ -145,6 +145,8 @@ The <tt>spec_<i>adapter</i></tt> specs run against a real database connection wi
|
|
145
145
|
|
146
146
|
These specs are broken down into two parts. For each database, there are specific specs that only apply to that database, and these are called the adapter specs. There are also shared specs that apply to all (or almost all) databases, these are called the integration specs. For database types that don't have specific adapter tests, you can use <tt>rake spec_integration</tt> to just run the shared integration tests.
|
147
147
|
|
148
|
+
Each adapter needs a specific gem installed in order to run. Please see the {connecting to a database guide}[rdoc-ref:doc/opening_databases.rdoc] for which gem you need to install for the adapter you are testing.
|
149
|
+
|
148
150
|
== Environment variables
|
149
151
|
|
150
152
|
Sequel uses environment variables when testing to specify either the database to be tested or specify how testing should be done. You can also specify the databases to test by copying <tt>spec/spec_config.rb.example</tt> to <tt>spec/spec_config.rb</tt> and modifying it. See that file for details. It may be necessary to use +spec_config.rb+ as opposed to an environment variable if your database connection cannot be specified by a connection string.
|
@@ -157,21 +159,30 @@ The SEQUEL_INTEGRATION_URL environment variable specifies the Database connectio
|
|
157
159
|
|
158
160
|
=== Other
|
159
161
|
|
162
|
+
SEQUEL_ASYNC_THREAD_POOL :: Use the async_thread_pool extension when running the specs
|
163
|
+
SEQUEL_ASYNC_THREAD_POOL_PREEMPT :: Use the async_thread_pool extension when running the specs, with the :preempt_async_thread option
|
164
|
+
SEQUEL_CHECK_PENDING :: Try running all specs (note, can cause lockups for some adapters), and raise errors for skipped specs that don't fail
|
160
165
|
SEQUEL_COLUMNS_INTROSPECTION :: Use the columns_introspection extension when running the specs
|
166
|
+
SEQUEL_CONCURRENT_EAGER_LOADING :: Use the async_thread_pool extension and concurrent_eager_loading plugin when running the specs
|
161
167
|
SEQUEL_CONNECTION_VALIDATOR :: Use the connection validator extension when running the specs
|
162
168
|
SEQUEL_DUPLICATE_COLUMNS_HANDLER :: Use the duplicate columns handler extension with value given when running the specs
|
163
169
|
SEQUEL_ERROR_SQL :: Use the error_sql extension when running the specs
|
164
|
-
SEQUEL_INDEX_CACHING :: Use the index_caching extension when running the specs
|
165
170
|
SEQUEL_FIBER_CONCURRENCY :: Use the fiber_concurrency extension when running the adapter and integration specs
|
166
171
|
SEQUEL_FREEZE_DATABASE :: Freeze the database before running the integration specs
|
167
172
|
SEQUEL_IDENTIFIER_MANGLING :: Use the identifier_mangling extension when running the specs
|
173
|
+
SEQUEL_INDEX_CACHING :: Use the index_caching extension when running the specs
|
168
174
|
SEQUEL_INTEGER64 :: Use the integer64 extension when running the adapter or integration specs
|
169
175
|
SEQUEL_MODEL_PREPARED_STATEMENTS :: Use the prepared_statements plugin when running the specs
|
170
176
|
SEQUEL_MODEL_THROW_FAILURES :: Use the throw_failures plugin when running the specs
|
171
177
|
SEQUEL_NO_CACHE_ASSOCIATIONS :: Don't cache association metadata when running the specs
|
172
|
-
SEQUEL_CHECK_PENDING :: Try running all specs (note, can cause lockups for some adapters), and raise errors for skipped specs that don't fail
|
173
178
|
SEQUEL_NO_PENDING :: Don't skip any specs, try running all specs (note, can cause lockups for some adapters)
|
179
|
+
SEQUEL_PG_AUTO_PARAMETERIZE :: Use the pg_auto_parameterize extension when running the postgres specs. Value can be +in_array+ to test the pg_auto_parameterize_in_array extension, and +in_array_string+ to test the pg_auto_parameterize_in_array extension with the +:treat_in_string_list_as_text_array+ Database option set.
|
174
180
|
SEQUEL_PG_TIMESTAMPTZ :: Use the pg_timestamptz extension when running the postgres specs
|
181
|
+
SEQUEL_PRIMARY_KEY_LOOKUP_CHECK_VALUES :: Use the primary_key_lookup_check_values extension when running the adapter or integration specs
|
182
|
+
SEQUEL_QUERY_PER_ASSOCIATION_DB_0_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
|
183
|
+
SEQUEL_QUERY_PER_ASSOCIATION_DB_1_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
|
184
|
+
SEQUEL_QUERY_PER_ASSOCIATION_DB_2_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
|
185
|
+
SEQUEL_QUERY_PER_ASSOCIATION_DB_3_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
|
175
186
|
SEQUEL_SPLIT_SYMBOLS :: Turn on symbol splitting when running the adapter and integration specs
|
176
187
|
SEQUEL_SYNCHRONIZE_SQL :: Use the synchronize_sql extension when running the specs
|
177
188
|
SEQUEL_TZINFO_VERSION :: Force the given tzinfo version when running the specs (e.g. '>=2')
|
data/doc/transactions.rdoc
CHANGED
@@ -127,28 +127,28 @@ Other exceptions, unless rescued inside the outer transaction block, will rollba
|
|
127
127
|
end # ROLLBACK
|
128
128
|
# ArgumentError raised
|
129
129
|
|
130
|
-
If you want the current savepoint to be rolled back when the savepoint block exits instead of being committed (even if an exception is not raised), use <tt>Database#rollback_on_exit(:
|
130
|
+
If you want the current savepoint to be rolled back when the savepoint block exits instead of being committed (even if an exception is not raised), use <tt>Database#rollback_on_exit(savepoint: true)</tt>
|
131
131
|
|
132
132
|
DB.transaction do # BEGIN
|
133
133
|
DB.transaction(savepoint: true) do # SAVEPOINT
|
134
|
-
DB.rollback_on_exit(:
|
134
|
+
DB.rollback_on_exit(savepoint: true)
|
135
135
|
end # ROLLBACK TO SAVEPOINT
|
136
136
|
end # COMMIT
|
137
137
|
|
138
138
|
DB.transaction do # BEGIN
|
139
139
|
DB.transaction(savepoint: true) do # SAVEPOINT
|
140
140
|
DB.transaction(savepoint: true) do # SAVEPOINT
|
141
|
-
DB.rollback_on_exit(:
|
141
|
+
DB.rollback_on_exit(savepoint: true)
|
142
142
|
end # ROLLBACK TO SAVEPOINT
|
143
143
|
end # RELEASE SAVEPOINT
|
144
144
|
end # COMMIT
|
145
145
|
|
146
|
-
If you want the current savepoint and potentially enclosing savepoints to be rolled back when the savepoint blocks exit (even if an exception is not raised), use <tt>Database#rollback_on_exit(:
|
146
|
+
If you want the current savepoint and potentially enclosing savepoints to be rolled back when the savepoint blocks exit (even if an exception is not raised), use <tt>Database#rollback_on_exit(savepoint: integer)</tt>
|
147
147
|
|
148
148
|
DB.transaction do # BEGIN
|
149
149
|
DB.transaction(savepoint: true) do # SAVEPOINT
|
150
150
|
DB.transaction(savepoint: true) do # SAVEPOINT
|
151
|
-
DB.rollback_on_exit(:
|
151
|
+
DB.rollback_on_exit(savepoint: 2)
|
152
152
|
end # ROLLBACK TO SAVEPOINT
|
153
153
|
end # ROLLBACK TO SAVEPOINT
|
154
154
|
end # COMMIT
|
@@ -156,7 +156,7 @@ If you want the current savepoint and potentially enclosing savepoints to be rol
|
|
156
156
|
DB.transaction do # BEGIN
|
157
157
|
DB.transaction(savepoint: true) do # SAVEPOINT
|
158
158
|
DB.transaction(savepoint: true) do # SAVEPOINT
|
159
|
-
DB.rollback_on_exit(:
|
159
|
+
DB.rollback_on_exit(savepoint: 3)
|
160
160
|
end # ROLLBACK TO SAVEPOINT
|
161
161
|
end # ROLLBACK TO SAVEPOINT
|
162
162
|
end # ROLLBACK
|
data/doc/virtual_rows.rdoc
CHANGED
@@ -23,7 +23,7 @@ With virtual rows, you can use the less verbose:
|
|
23
23
|
Virtual row blocks behave differently depending on whether the block accepts
|
24
24
|
an argument. If the block accepts an argument, it is called with an instance
|
25
25
|
of Sequel::SQL::VirtualRow. If it does not accept an argument, it is
|
26
|
-
evaluated in the context of an instance of Sequel::SQL::VirtualRow.
|
26
|
+
evaluated in the <em> context of an instance </em> of Sequel::SQL::VirtualRow.
|
27
27
|
|
28
28
|
ds = DB[:items]
|
29
29
|
# Regular block
|
@@ -54,7 +54,7 @@ methods in the surrounding scope. For example:
|
|
54
54
|
|
55
55
|
# Regular block
|
56
56
|
ds.where{|o| o.c > a - b + @d}
|
57
|
-
# WHERE (c >
|
57
|
+
# WHERE (c > 110)
|
58
58
|
|
59
59
|
# Instance-evaled block
|
60
60
|
ds.where{c > a - b + @d}
|
data/lib/sequel/adapters/ado.rb
CHANGED
@@ -161,7 +161,7 @@ module Sequel
|
|
161
161
|
begin
|
162
162
|
r = log_connection_yield(sql, conn){conn.Execute(sql)}
|
163
163
|
begin
|
164
|
-
yield r if
|
164
|
+
yield r if defined?(yield)
|
165
165
|
ensure
|
166
166
|
begin
|
167
167
|
r.close
|
@@ -195,10 +195,25 @@ module Sequel
|
|
195
195
|
end
|
196
196
|
|
197
197
|
@conversion_procs = CONVERSION_PROCS.dup
|
198
|
+
@conversion_procs[AdDBTimeStamp] = method(:adb_timestamp_to_application_timestamp)
|
198
199
|
|
199
200
|
super
|
200
201
|
end
|
201
202
|
|
203
|
+
def adb_timestamp_to_application_timestamp(v)
|
204
|
+
# This hard codes a timestamp_precision of 6 when converting.
|
205
|
+
# That is the default timestamp_precision, but the ado/mssql adapter uses a timestamp_precision
|
206
|
+
# of 3. However, timestamps returned by ado/mssql have nsec values that end up rounding to a
|
207
|
+
# the same value as if a timestamp_precision of 3 was hard coded (either xxx999yzz, where y is
|
208
|
+
# 5-9 or xxx000yzz where y is 0-4).
|
209
|
+
#
|
210
|
+
# ADO subadapters should override this they would like a different timestamp precision and the
|
211
|
+
# this code does not work for them (for example, if they provide full nsec precision).
|
212
|
+
#
|
213
|
+
# Note that fractional second handling for WIN32OLE objects is not correct on ruby <2.2
|
214
|
+
to_application_timestamp([v.year, v.month, v.day, v.hour, v.min, v.sec, (v.nsec/1000.0).round * 1000])
|
215
|
+
end
|
216
|
+
|
202
217
|
def dataset_class_default
|
203
218
|
Dataset
|
204
219
|
end
|
@@ -233,23 +248,8 @@ module Sequel
|
|
233
248
|
cols = []
|
234
249
|
conversion_procs = db.conversion_procs
|
235
250
|
|
236
|
-
ts_cp = nil
|
237
251
|
recordset.Fields.each do |field|
|
238
|
-
|
239
|
-
cp = if type == AdDBTimeStamp
|
240
|
-
ts_cp ||= begin
|
241
|
-
nsec_div = 1000000000.0/(10**(timestamp_precision))
|
242
|
-
nsec_mul = 10**(timestamp_precision+3)
|
243
|
-
meth = db.method(:to_application_timestamp)
|
244
|
-
lambda do |v|
|
245
|
-
# Fractional second handling is not correct on ruby <2.2
|
246
|
-
meth.call([v.year, v.month, v.day, v.hour, v.min, v.sec, (v.nsec/nsec_div).round * nsec_mul])
|
247
|
-
end
|
248
|
-
end
|
249
|
-
else
|
250
|
-
conversion_procs[type]
|
251
|
-
end
|
252
|
-
cols << [output_identifier(field.Name), cp]
|
252
|
+
cols << [output_identifier(field.Name), conversion_procs[field.Type]]
|
253
253
|
end
|
254
254
|
|
255
255
|
self.columns = cols.map(&:first)
|
@@ -118,11 +118,9 @@ module Sequel
|
|
118
118
|
# Yield an available connection. Rescue
|
119
119
|
# any Amalgalite::Errors and turn them into DatabaseErrors.
|
120
120
|
def _execute(sql, opts)
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
raise_error(e)
|
125
|
-
end
|
121
|
+
synchronize(opts[:server]){|conn| yield conn}
|
122
|
+
rescue ::Amalgalite::Error, ::Amalgalite::SQLite3::Error => e
|
123
|
+
raise_error(e)
|
126
124
|
end
|
127
125
|
|
128
126
|
# The Amagalite adapter does not need the pool to convert exceptions.
|
@@ -246,7 +246,7 @@ module Sequel
|
|
246
246
|
end
|
247
247
|
begin
|
248
248
|
stmt = log_connection_yield(log_sql, conn, args){conn.execute_prepared(ps_name, *args)}
|
249
|
-
if
|
249
|
+
if defined?(yield)
|
250
250
|
yield(stmt)
|
251
251
|
else
|
252
252
|
stmt.affected
|
@@ -268,7 +268,7 @@ module Sequel
|
|
268
268
|
# is given or returning the number of affected rows if not, and ensuring the statement is freed.
|
269
269
|
def _execute(conn, sql, opts)
|
270
270
|
stmt = log_connection_yield(sql, conn){conn.execute(sql)}
|
271
|
-
if
|
271
|
+
if defined?(yield)
|
272
272
|
yield(stmt)
|
273
273
|
else
|
274
274
|
stmt.affected
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
Sequel::JDBC.load_driver('org.apache.derby.jdbc.EmbeddedDriver', :Derby)
|
4
4
|
require_relative 'transactions'
|
5
|
+
require_relative '../utils/columns_limit_1'
|
5
6
|
|
6
7
|
module Sequel
|
7
8
|
module JDBC
|
@@ -182,6 +183,8 @@ module Sequel
|
|
182
183
|
end
|
183
184
|
|
184
185
|
class Dataset < JDBC::Dataset
|
186
|
+
include ::Sequel::Dataset::ColumnsLimit1
|
187
|
+
|
185
188
|
# Derby doesn't support an expression between CASE and WHEN,
|
186
189
|
# so remove conditions.
|
187
190
|
def case_expression_sql_append(sql, ce)
|
@@ -232,6 +235,11 @@ module Sequel
|
|
232
235
|
false
|
233
236
|
end
|
234
237
|
|
238
|
+
# Derby 10.11+ supports MERGE.
|
239
|
+
def supports_merge?
|
240
|
+
db.svn_version >= 1616546
|
241
|
+
end
|
242
|
+
|
235
243
|
# Derby does not support IN/NOT IN with multiple columns
|
236
244
|
def supports_multiple_column_in?
|
237
245
|
false
|
@@ -24,6 +24,7 @@ module Sequel
|
|
24
24
|
|
25
25
|
def freeze
|
26
26
|
h2_version
|
27
|
+
version2?
|
27
28
|
super
|
28
29
|
end
|
29
30
|
|
@@ -140,13 +141,36 @@ module Sequel
|
|
140
141
|
DATABASE_ERROR_REGEXPS
|
141
142
|
end
|
142
143
|
|
143
|
-
|
144
|
+
def execute_statement_insert(stmt, sql)
|
145
|
+
stmt.executeUpdate(sql, JavaSQL::Statement::RETURN_GENERATED_KEYS)
|
146
|
+
end
|
147
|
+
|
148
|
+
def prepare_jdbc_statement(conn, sql, opts)
|
149
|
+
opts[:type] == :insert ? conn.prepareStatement(sql, JavaSQL::Statement::RETURN_GENERATED_KEYS) : super
|
150
|
+
end
|
151
|
+
|
152
|
+
# Get the last inserted id using getGeneratedKeys, scope_identity, or identity.
|
144
153
|
def last_insert_id(conn, opts=OPTS)
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
154
|
+
if stmt = opts[:stmt]
|
155
|
+
rs = stmt.getGeneratedKeys
|
156
|
+
begin
|
157
|
+
if rs.next
|
158
|
+
begin
|
159
|
+
rs.getLong(1)
|
160
|
+
rescue
|
161
|
+
rs.getObject(1) rescue nil
|
162
|
+
end
|
163
|
+
end
|
164
|
+
ensure
|
165
|
+
rs.close
|
166
|
+
end
|
167
|
+
elsif !version2?
|
168
|
+
statement(conn) do |stmt|
|
169
|
+
sql = 'SELECT IDENTITY()'
|
170
|
+
rs = log_connection_yield(sql, conn){stmt.executeQuery(sql)}
|
171
|
+
rs.next
|
172
|
+
rs.getLong(1)
|
173
|
+
end
|
150
174
|
end
|
151
175
|
end
|
152
176
|
|
@@ -161,7 +185,12 @@ module Sequel
|
|
161
185
|
|
162
186
|
# Use BIGINT IDENTITY for identity columns that use :Bignum type
|
163
187
|
def type_literal_generic_bignum_symbol(column)
|
164
|
-
column[:identity] ? 'BIGINT
|
188
|
+
column[:identity] ? 'BIGINT AUTO_INCREMENT' : super
|
189
|
+
end
|
190
|
+
|
191
|
+
def version2?
|
192
|
+
return @version2 if defined?(@version2)
|
193
|
+
@version2 = h2_version.to_i >= 2
|
165
194
|
end
|
166
195
|
end
|
167
196
|
|
@@ -200,6 +229,11 @@ module Sequel
|
|
200
229
|
false
|
201
230
|
end
|
202
231
|
|
232
|
+
# H2 supports MERGE
|
233
|
+
def supports_merge?
|
234
|
+
true
|
235
|
+
end
|
236
|
+
|
203
237
|
# H2 doesn't support multiple columns in IN/NOT IN
|
204
238
|
def supports_multiple_column_in?
|
205
239
|
false
|
@@ -209,9 +243,21 @@ module Sequel
|
|
209
243
|
|
210
244
|
# H2 expects hexadecimal strings for blob values
|
211
245
|
def literal_blob_append(sql, v)
|
212
|
-
|
246
|
+
if db.send(:version2?)
|
247
|
+
super
|
248
|
+
else
|
249
|
+
sql << "'" << v.unpack("H*").first << "'"
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def literal_false
|
254
|
+
'FALSE'
|
213
255
|
end
|
214
256
|
|
257
|
+
def literal_true
|
258
|
+
'TRUE'
|
259
|
+
end
|
260
|
+
|
215
261
|
# H2 handles fractional seconds in timestamps, but not in times
|
216
262
|
def literal_sqltime(v)
|
217
263
|
v.strftime("'%H:%M:%S'")
|
@@ -223,8 +269,12 @@ module Sequel
|
|
223
269
|
end
|
224
270
|
|
225
271
|
def select_only_offset_sql(sql)
|
226
|
-
|
227
|
-
|
272
|
+
if db.send(:version2?)
|
273
|
+
super
|
274
|
+
else
|
275
|
+
sql << " LIMIT -1 OFFSET "
|
276
|
+
literal_append(sql, @opts[:offset])
|
277
|
+
end
|
228
278
|
end
|
229
279
|
|
230
280
|
# H2 supports quoted function names.
|
@@ -179,6 +179,12 @@ module Sequel
|
|
179
179
|
true
|
180
180
|
end
|
181
181
|
|
182
|
+
# HSQLDB 2.3.4+ supports MERGE. Older versions also support MERGE, but not all
|
183
|
+
# features that are in Sequel's tests.
|
184
|
+
def supports_merge?
|
185
|
+
db.db_version >= 20304
|
186
|
+
end
|
187
|
+
|
182
188
|
private
|
183
189
|
|
184
190
|
def empty_from_sql
|
@@ -35,9 +35,9 @@ module Sequel
|
|
35
35
|
data = opts[:data]
|
36
36
|
data = Array(data) if data.is_a?(String)
|
37
37
|
|
38
|
-
if
|
38
|
+
if defined?(yield) && data
|
39
39
|
raise Error, "Cannot provide both a :data option and a block to copy_into"
|
40
|
-
elsif !
|
40
|
+
elsif !defined?(yield) && !data
|
41
41
|
raise Error, "Must provide either a :data option or a block to copy_into"
|
42
42
|
end
|
43
43
|
|
@@ -45,7 +45,7 @@ module Sequel
|
|
45
45
|
begin
|
46
46
|
copy_manager = org.postgresql.copy.CopyManager.new(conn)
|
47
47
|
copier = copy_manager.copy_in(copy_into_sql(table, opts))
|
48
|
-
if
|
48
|
+
if defined?(yield)
|
49
49
|
while buf = yield
|
50
50
|
java_bytes = buf.to_java_bytes
|
51
51
|
copier.writeToCopy(java_bytes, 0, java_bytes.length)
|
@@ -77,7 +77,7 @@ module Sequel
|
|
77
77
|
copy_manager = org.postgresql.copy.CopyManager.new(conn)
|
78
78
|
copier = copy_manager.copy_out(copy_table_sql(table, opts))
|
79
79
|
begin
|
80
|
-
if
|
80
|
+
if defined?(yield)
|
81
81
|
while buf = copier.readFromCopy
|
82
82
|
yield(String.from_java_bytes(buf))
|
83
83
|
end
|
@@ -199,6 +199,7 @@ module Sequel
|
|
199
199
|
v.strftime("'%H:%M:%S#{sprintf(".%03d", (v.usec/1000.0).round)}'")
|
200
200
|
end
|
201
201
|
|
202
|
+
INTEGER_TYPE = Java::JavaSQL::Types::INTEGER
|
202
203
|
STRING_TYPE = Java::JavaSQL::Types::VARCHAR
|
203
204
|
ARRAY_TYPE = Java::JavaSQL::Types::ARRAY
|
204
205
|
PG_SPECIFIC_TYPES = [Java::JavaSQL::Types::ARRAY, Java::JavaSQL::Types::OTHER, Java::JavaSQL::Types::STRUCT, Java::JavaSQL::Types::TIME_WITH_TIMEZONE, Java::JavaSQL::Types::TIME].freeze
|
@@ -219,6 +220,8 @@ module Sequel
|
|
219
220
|
oid = meta.getField(i).getOID
|
220
221
|
if pr = db.oid_convertor_proc(oid)
|
221
222
|
pr
|
223
|
+
elsif oid == 28 # XID (Transaction ID)
|
224
|
+
map[INTEGER_TYPE]
|
222
225
|
elsif oid == 2950 # UUID
|
223
226
|
map[STRING_TYPE]
|
224
227
|
elsif meta.getPGType(i) == 'hstore'
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -32,15 +32,13 @@ module Sequel
|
|
32
32
|
|
33
33
|
# Allow loading the necessary JDBC support via a gem.
|
34
34
|
def self.load_gem(name)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
jdbc_module.load_driver if jdbc_module.respond_to?(:load_driver)
|
43
|
-
end
|
35
|
+
require "jdbc/#{name.to_s.downcase}"
|
36
|
+
rescue LoadError
|
37
|
+
# jdbc gem not used, hopefully the user has the .jar in their CLASSPATH
|
38
|
+
else
|
39
|
+
if defined?(::Jdbc) && ( ::Jdbc.const_defined?(name) rescue nil )
|
40
|
+
jdbc_module = ::Jdbc.const_get(name) # e.g. Jdbc::SQLite3
|
41
|
+
jdbc_module.load_driver if jdbc_module.respond_to?(:load_driver)
|
44
42
|
end
|
45
43
|
end
|
46
44
|
|
@@ -71,11 +69,11 @@ module Sequel
|
|
71
69
|
class TypeConvertor
|
72
70
|
CONVERTORS = convertors = {}
|
73
71
|
%w'Boolean Float Double Int Long Short'.each do |meth|
|
74
|
-
x = convertors[meth.to_sym] = Object.new
|
72
|
+
x = x = convertors[meth.to_sym] = Object.new
|
75
73
|
class_eval("def x.call(r, i) v = r.get#{meth}(i); v unless r.wasNull end", __FILE__, __LINE__)
|
76
74
|
end
|
77
75
|
%w'Object Array String Time Date Timestamp BigDecimal Blob Bytes Clob'.each do |meth|
|
78
|
-
x = convertors[meth.to_sym] = Object.new
|
76
|
+
x = x = convertors[meth.to_sym] = Object.new
|
79
77
|
class_eval("def x.call(r, i) r.get#{meth}(i) end", __FILE__, __LINE__)
|
80
78
|
end
|
81
79
|
x = convertors[:RubyTime] = Object.new
|
@@ -190,13 +188,13 @@ module Sequel
|
|
190
188
|
args = opts[:args] || []
|
191
189
|
sql = "{call #{name}(#{args.map{'?'}.join(',')})}"
|
192
190
|
synchronize(opts[:server]) do |conn|
|
193
|
-
|
191
|
+
begin
|
192
|
+
cps = conn.prepareCall(sql)
|
194
193
|
|
195
|
-
|
196
|
-
|
194
|
+
i = 0
|
195
|
+
args.each{|arg| set_ps_arg(cps, arg, i+=1)}
|
197
196
|
|
198
|
-
|
199
|
-
if block_given?
|
197
|
+
if defined?(yield)
|
200
198
|
yield log_connection_yield(sql, conn){cps.executeQuery}
|
201
199
|
else
|
202
200
|
log_connection_yield(sql, conn){cps.executeUpdate}
|
@@ -207,7 +205,7 @@ module Sequel
|
|
207
205
|
rescue *DATABASE_ERROR_CLASSES => e
|
208
206
|
raise_error(e)
|
209
207
|
ensure
|
210
|
-
cps.close
|
208
|
+
cps.close if cps
|
211
209
|
end
|
212
210
|
end
|
213
211
|
end
|
@@ -461,7 +459,7 @@ module Sequel
|
|
461
459
|
msg << ")"
|
462
460
|
end
|
463
461
|
begin
|
464
|
-
if
|
462
|
+
if defined?(yield)
|
465
463
|
yield log_connection_yield(msg, conn, args){cps.executeQuery}
|
466
464
|
else
|
467
465
|
case opts[:type]
|