sequel 3.12.1 → 3.13.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +42 -0
- data/README.rdoc +137 -118
- data/Rakefile +21 -66
- data/doc/active_record.rdoc +9 -9
- data/doc/advanced_associations.rdoc +59 -188
- data/doc/association_basics.rdoc +15 -2
- data/doc/cheat_sheet.rdoc +38 -33
- data/doc/dataset_filtering.rdoc +16 -7
- data/doc/prepared_statements.rdoc +7 -7
- data/doc/querying.rdoc +5 -4
- data/doc/release_notes/3.13.0.txt +210 -0
- data/doc/sharding.rdoc +1 -1
- data/doc/sql.rdoc +5 -5
- data/doc/validations.rdoc +11 -11
- data/lib/sequel/adapters/ado.rb +1 -1
- data/lib/sequel/adapters/do.rb +3 -3
- data/lib/sequel/adapters/firebird.rb +3 -3
- data/lib/sequel/adapters/jdbc/h2.rb +39 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +5 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +3 -3
- data/lib/sequel/adapters/mysql.rb +7 -4
- data/lib/sequel/adapters/oracle.rb +3 -3
- data/lib/sequel/adapters/shared/mssql.rb +10 -1
- data/lib/sequel/adapters/shared/mysql.rb +63 -0
- data/lib/sequel/adapters/shared/postgres.rb +61 -3
- data/lib/sequel/adapters/sqlite.rb +105 -18
- data/lib/sequel/connection_pool.rb +31 -30
- data/lib/sequel/core.rb +58 -58
- data/lib/sequel/core_sql.rb +52 -43
- data/lib/sequel/database/misc.rb +11 -0
- data/lib/sequel/database/query.rb +55 -17
- data/lib/sequel/dataset/actions.rb +2 -1
- data/lib/sequel/dataset/query.rb +2 -3
- data/lib/sequel/dataset/sql.rb +24 -11
- data/lib/sequel/extensions/schema_dumper.rb +1 -1
- data/lib/sequel/metaprogramming.rb +4 -0
- data/lib/sequel/model.rb +37 -19
- data/lib/sequel/model/associations.rb +33 -25
- data/lib/sequel/model/base.rb +2 -2
- data/lib/sequel/model/plugins.rb +7 -2
- data/lib/sequel/plugins/active_model.rb +1 -1
- data/lib/sequel/plugins/association_pks.rb +2 -2
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/boolean_readers.rb +2 -2
- data/lib/sequel/plugins/class_table_inheritance.rb +10 -2
- data/lib/sequel/plugins/identity_map.rb +3 -3
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +212 -0
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/list.rb +174 -0
- data/lib/sequel/plugins/many_through_many.rb +2 -2
- data/lib/sequel/plugins/rcte_tree.rb +6 -7
- data/lib/sequel/plugins/tree.rb +118 -0
- data/lib/sequel/plugins/xml_serializer.rb +321 -0
- data/lib/sequel/sql.rb +315 -206
- data/lib/sequel/timezones.rb +40 -17
- data/lib/sequel/version.rb +8 -2
- data/spec/adapters/firebird_spec.rb +2 -2
- data/spec/adapters/informix_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +2 -2
- data/spec/adapters/mysql_spec.rb +2 -2
- data/spec/adapters/oracle_spec.rb +1 -1
- data/spec/adapters/postgres_spec.rb +36 -6
- data/spec/adapters/spec_helper.rb +2 -2
- data/spec/adapters/sqlite_spec.rb +1 -1
- data/spec/core/connection_pool_spec.rb +3 -3
- data/spec/core/core_sql_spec.rb +31 -13
- data/spec/core/database_spec.rb +39 -2
- data/spec/core/dataset_spec.rb +24 -12
- data/spec/core/expression_filters_spec.rb +5 -1
- data/spec/core/object_graph_spec.rb +1 -1
- data/spec/core/schema_generator_spec.rb +1 -1
- data/spec/core/schema_spec.rb +1 -1
- data/spec/core/spec_helper.rb +1 -1
- data/spec/core/version_spec.rb +1 -1
- data/spec/extensions/active_model_spec.rb +82 -67
- data/spec/extensions/association_dependencies_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +1 -1
- data/spec/extensions/association_proxies_spec.rb +1 -1
- data/spec/extensions/blank_spec.rb +1 -1
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/caching_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +3 -2
- data/spec/extensions/composition_spec.rb +2 -5
- data/spec/extensions/force_encoding_spec.rb +3 -1
- data/spec/extensions/hook_class_methods_spec.rb +1 -1
- data/spec/extensions/identity_map_spec.rb +1 -1
- data/spec/extensions/inflector_spec.rb +1 -1
- data/spec/extensions/instance_filters_spec.rb +1 -1
- data/spec/extensions/instance_hooks_spec.rb +1 -1
- data/spec/extensions/json_serializer_spec.rb +154 -0
- data/spec/extensions/lazy_attributes_spec.rb +1 -2
- data/spec/extensions/list_spec.rb +251 -0
- data/spec/extensions/looser_typecasting_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +3 -3
- data/spec/extensions/migration_spec.rb +1 -1
- data/spec/extensions/named_timezones_spec.rb +5 -6
- data/spec/extensions/nested_attributes_spec.rb +1 -1
- data/spec/extensions/optimistic_locking_spec.rb +1 -1
- data/spec/extensions/pagination_spec.rb +1 -1
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +1 -1
- data/spec/extensions/rcte_tree_spec.rb +1 -1
- data/spec/extensions/schema_dumper_spec.rb +3 -2
- data/spec/extensions/schema_spec.rb +1 -1
- data/spec/extensions/serialization_spec.rb +6 -2
- data/spec/extensions/sharding_spec.rb +1 -1
- data/spec/extensions/single_table_inheritance_spec.rb +1 -1
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +7 -3
- data/spec/extensions/sql_expr_spec.rb +1 -1
- data/spec/extensions/string_date_time_spec.rb +1 -1
- data/spec/extensions/string_stripper_spec.rb +1 -1
- data/spec/extensions/subclasses_spec.rb +1 -1
- data/spec/extensions/tactical_eager_loading_spec.rb +1 -1
- data/spec/extensions/thread_local_timezones_spec.rb +1 -1
- data/spec/extensions/timestamps_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +1 -1
- data/spec/extensions/tree_spec.rb +119 -0
- data/spec/extensions/typecast_on_load_spec.rb +1 -1
- data/spec/extensions/update_primary_key_spec.rb +1 -1
- data/spec/extensions/validation_class_methods_spec.rb +1 -1
- data/spec/extensions/validation_helpers_spec.rb +1 -1
- data/spec/extensions/xml_serializer_spec.rb +142 -0
- data/spec/integration/associations_test.rb +1 -1
- data/spec/integration/database_test.rb +1 -1
- data/spec/integration/dataset_test.rb +29 -14
- data/spec/integration/eager_loader_test.rb +1 -1
- data/spec/integration/migrator_test.rb +1 -1
- data/spec/integration/model_test.rb +1 -1
- data/spec/integration/plugin_test.rb +316 -1
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/schema_test.rb +8 -8
- data/spec/integration/spec_helper.rb +1 -1
- data/spec/integration/timezone_test.rb +1 -1
- data/spec/integration/transaction_test.rb +35 -20
- data/spec/integration/type_test.rb +1 -1
- data/spec/model/association_reflection_spec.rb +1 -1
- data/spec/model/associations_spec.rb +49 -34
- data/spec/model/base_spec.rb +1 -1
- data/spec/model/dataset_methods_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +1 -1
- data/spec/model/hooks_spec.rb +1 -1
- data/spec/model/inflector_spec.rb +1 -1
- data/spec/model/model_spec.rb +7 -1
- data/spec/model/plugins_spec.rb +1 -1
- data/spec/model/record_spec.rb +1 -3
- data/spec/model/spec_helper.rb +2 -2
- data/spec/model/validations_spec.rb +1 -1
- metadata +29 -5
data/lib/sequel/timezones.rb
CHANGED
@@ -9,21 +9,44 @@ module Sequel
|
|
9
9
|
@database_timezone = nil
|
10
10
|
@typecast_timezone = nil
|
11
11
|
|
12
|
+
# Sequel doesn't pay much attention to timezones by default, but you can set it
|
13
|
+
# handle timezones if you want. There are three separate timezone settings, application_timezone,
|
14
|
+
# database_timezone, and typecast_timezone. All three timezones have getter and setter methods.
|
15
|
+
# You can set all three timezones to the same value at once via <tt>Sequel.default_timezone=</tt>.
|
16
|
+
#
|
17
|
+
# The only timezone values that are supported by default are <tt>:utc</tt> (convert to UTC),
|
18
|
+
# <tt>:local</tt> (convert to local time), and +nil+ (don't convert). If you need to
|
19
|
+
# convert to a specific timezone, or need the timezones being used to change based
|
20
|
+
# on the environment (e.g. current user), you need to use the +named_timezones+ extension (and use
|
21
|
+
# +DateTime+ as the +datetime_class+). Sequel also ships with a +thread_local_timezones+ extensions
|
22
|
+
# which allows each thread to have its own timezone values for each of the timezones.
|
12
23
|
module Timezones
|
13
|
-
|
24
|
+
# The timezone you want the application to use. This is the timezone
|
25
|
+
# that incoming times from the database and typecasting are converted to.
|
26
|
+
attr_reader :application_timezone
|
27
|
+
|
28
|
+
# The timezone for storage in the database. This is the
|
29
|
+
# timezone to which Sequel will convert timestamps before literalizing them
|
30
|
+
# for storage in the database. It is also the timezone that Sequel will assume
|
31
|
+
# database timestamp values are already in (if they don't include an offset).
|
32
|
+
attr_reader :database_timezone
|
33
|
+
|
34
|
+
# The timezone that incoming data that Sequel needs to typecast
|
35
|
+
# is assumed to be already in (if they don't include an offset).
|
36
|
+
attr_reader :typecast_timezone
|
14
37
|
|
15
38
|
%w'application database typecast'.each do |t|
|
16
39
|
class_eval("def #{t}_timezone=(tz); @#{t}_timezone = convert_timezone_setter_arg(tz) end", __FILE__, __LINE__)
|
17
40
|
end
|
18
41
|
|
19
|
-
# Convert the given Time
|
42
|
+
# Convert the given +Time+/+DateTime+ object into the database timezone, used when
|
20
43
|
# literalizing objects in an SQL string.
|
21
44
|
def application_to_database_timestamp(v)
|
22
45
|
convert_output_timestamp(v, Sequel.database_timezone)
|
23
46
|
end
|
24
47
|
|
25
|
-
# Convert the given object into an object of Sequel.datetime_class in the
|
26
|
-
# application_timezone
|
48
|
+
# Convert the given object into an object of <tt>Sequel.datetime_class</tt> in the
|
49
|
+
# +application_timezone+. Used when coverting datetime/timestamp columns
|
27
50
|
# returned by the database.
|
28
51
|
def database_to_application_timestamp(v)
|
29
52
|
convert_timestamp(v, Sequel.database_timezone)
|
@@ -36,8 +59,8 @@ module Sequel
|
|
36
59
|
self.typecast_timezone = tz
|
37
60
|
end
|
38
61
|
|
39
|
-
# Convert the given object into an object of Sequel.datetime_class in the
|
40
|
-
# application_timezone
|
62
|
+
# Convert the given object into an object of <tt>Sequel.datetime_class</tt> in the
|
63
|
+
# +application_timezone+. Used when typecasting values when assigning them
|
41
64
|
# to model datetime attributes.
|
42
65
|
def typecast_to_application_timestamp(v)
|
43
66
|
convert_timestamp(v, Sequel.typecast_timezone)
|
@@ -45,7 +68,7 @@ module Sequel
|
|
45
68
|
|
46
69
|
private
|
47
70
|
|
48
|
-
# Convert the given DateTime to the given input_timezone, keeping the
|
71
|
+
# Convert the given +DateTime+ to the given input_timezone, keeping the
|
49
72
|
# same time and just modifying the timezone.
|
50
73
|
def convert_input_datetime_no_offset(v, input_timezone)
|
51
74
|
case input_timezone
|
@@ -58,16 +81,16 @@ module Sequel
|
|
58
81
|
end
|
59
82
|
end
|
60
83
|
|
61
|
-
# Convert the given DateTime to the given input_timezone that is not supported
|
62
|
-
# by default (
|
84
|
+
# Convert the given +DateTime+ to the given input_timezone that is not supported
|
85
|
+
# by default (i.e. one other than +nil+, <tt>:local</tt>, or <tt>:utc</tt>). Raises an +InvalidValue+ by default.
|
63
86
|
# Can be overridden in extensions.
|
64
87
|
def convert_input_datetime_other(v, input_timezone)
|
65
88
|
raise InvalidValue, "Invalid input_timezone: #{input_timezone.inspect}"
|
66
89
|
end
|
67
90
|
|
68
|
-
# Converts the object from a String
|
69
|
-
# instance of Sequel.datetime_class
|
70
|
-
# contain an offset, assume that the array/string is already in the given input_timezone
|
91
|
+
# Converts the object from a +String+, +Array+, +Date+, +DateTime+, or +Time+ into an
|
92
|
+
# instance of <tt>Sequel.datetime_class</tt>. If given an array or a string that doesn't
|
93
|
+
# contain an offset, assume that the array/string is already in the given +input_timezone+.
|
71
94
|
def convert_input_timestamp(v, input_timezone)
|
72
95
|
case v
|
73
96
|
when String
|
@@ -110,14 +133,14 @@ module Sequel
|
|
110
133
|
end
|
111
134
|
end
|
112
135
|
|
113
|
-
# Convert the given DateTime to the given output_timezone that is not supported
|
114
|
-
# by default (
|
136
|
+
# Convert the given +DateTime+ to the given output_timezone that is not supported
|
137
|
+
# by default (i.e. one other than +nil+, <tt>:local</tt>, or <tt>:utc</tt>). Raises an +InvalidValue+ by default.
|
115
138
|
# Can be overridden in extensions.
|
116
139
|
def convert_output_datetime_other(v, output_timezone)
|
117
140
|
raise InvalidValue, "Invalid output_timezone: #{output_timezone.inspect}"
|
118
141
|
end
|
119
142
|
|
120
|
-
# Converts the object to the given output_timezone
|
143
|
+
# Converts the object to the given +output_timezone+.
|
121
144
|
def convert_output_timestamp(v, output_timezone)
|
122
145
|
if output_timezone
|
123
146
|
if v.is_a?(DateTime)
|
@@ -138,8 +161,8 @@ module Sequel
|
|
138
161
|
end
|
139
162
|
|
140
163
|
# Converts the given object from the given input timezone to the
|
141
|
-
#
|
142
|
-
# convert_output_timestamp
|
164
|
+
# +application_timezone+ using +convert_input_timestamp+ and
|
165
|
+
# +convert_output_timestamp+.
|
143
166
|
def convert_timestamp(v, input_timezone)
|
144
167
|
begin
|
145
168
|
convert_output_timestamp(convert_input_timestamp(v, input_timezone), Sequel.application_timezone)
|
data/lib/sequel/version.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
module Sequel
|
2
|
+
# The major version of Sequel. Only bumped for major changes.
|
2
3
|
MAJOR = 3
|
3
|
-
|
4
|
-
|
4
|
+
# The minor version of Sequel. Bumped for every non-patch level
|
5
|
+
# release, generally around once a month.
|
6
|
+
MINOR = 13
|
7
|
+
# The tiny version of Sequel. Usually 0, only bumped for bugfix
|
8
|
+
# releases that fix regressions from previous versions.
|
9
|
+
TINY = 0
|
5
10
|
|
11
|
+
# The version of Sequel you are using, as a string (e.g. "2.11.0")
|
6
12
|
VERSION = [MAJOR, MINOR, TINY].join('.')
|
7
13
|
|
8
14
|
# The version of Sequel you are using, as a string (e.g. "2.11.0")
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
2
2
|
|
3
3
|
unless defined?(FIREBIRD_DB)
|
4
4
|
FIREBIRD_URL = 'firebird://sysdba:masterkey@localhost/reality_spec' unless defined? FIREBIRD_URL
|
@@ -13,7 +13,7 @@ logger = Object.new
|
|
13
13
|
def logger.method_missing(m, msg)
|
14
14
|
FIREBIRD_DB.sqls.push(msg)
|
15
15
|
end
|
16
|
-
FIREBIRD_DB.
|
16
|
+
FIREBIRD_DB.loggers = [logger]
|
17
17
|
|
18
18
|
FIREBIRD_DB.create_table! :test do
|
19
19
|
varchar :name, :size => 50
|
data/spec/adapters/mssql_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
2
2
|
|
3
3
|
require ENV['SEQUEL_MSSQL_SPEC_REQUIRE'] if ENV['SEQUEL_MSSQL_SPEC_REQUIRE']
|
4
4
|
|
@@ -15,7 +15,7 @@ logger = Object.new
|
|
15
15
|
def logger.method_missing(m, msg)
|
16
16
|
MSSQL_DB.sqls << msg
|
17
17
|
end
|
18
|
-
MSSQL_DB.
|
18
|
+
MSSQL_DB.loggers = [logger]
|
19
19
|
|
20
20
|
MSSQL_DB.create_table! :test do
|
21
21
|
text :name
|
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
2
2
|
|
3
3
|
unless defined?(MYSQL_USER)
|
4
4
|
MYSQL_USER = 'root'
|
@@ -25,7 +25,7 @@ logger = Object.new
|
|
25
25
|
def logger.method_missing(m, msg)
|
26
26
|
MYSQL_DB.sqls << msg
|
27
27
|
end
|
28
|
-
MYSQL_DB.
|
28
|
+
MYSQL_DB.loggers = [logger]
|
29
29
|
MYSQL_DB.drop_table(:items) rescue nil
|
30
30
|
MYSQL_DB.drop_table(:dolls) rescue nil
|
31
31
|
MYSQL_DB.drop_table(:booltest) rescue nil
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
2
2
|
|
3
3
|
unless defined?(POSTGRES_DB)
|
4
4
|
POSTGRES_URL = 'postgres://postgres:postgres@localhost:5432/reality_spec' unless defined? POSTGRES_URL
|
@@ -13,7 +13,7 @@ logger = Object.new
|
|
13
13
|
def logger.method_missing(m, msg)
|
14
14
|
POSTGRES_DB.sqls << msg
|
15
15
|
end
|
16
|
-
POSTGRES_DB.
|
16
|
+
POSTGRES_DB.loggers = [logger]
|
17
17
|
|
18
18
|
#POSTGRES_DB.instance_variable_set(:@server_version, 80100)
|
19
19
|
POSTGRES_DB.create_table! :test do
|
@@ -130,6 +130,15 @@ context "A PostgreSQL dataset" do
|
|
130
130
|
@d.filter(:name => /^bc/).count.should == 1
|
131
131
|
end
|
132
132
|
|
133
|
+
specify "should support NULLS FIRST and NULLS LAST" do
|
134
|
+
@d << {:name => 'abc'}
|
135
|
+
@d << {:name => 'bcd'}
|
136
|
+
@d << {:name => 'bcd', :value => 2}
|
137
|
+
@d.order(:value.asc(:nulls=>:first), :name).select_map(:name).should == %w[abc bcd bcd]
|
138
|
+
@d.order(:value.asc(:nulls=>:last), :name).select_map(:name).should == %w[bcd abc bcd]
|
139
|
+
@d.order(:value.asc(:nulls=>:first), :name).reverse.select_map(:name).should == %w[bcd bcd abc]
|
140
|
+
end
|
141
|
+
|
133
142
|
specify "#lock should lock tables and yield if a block is given" do
|
134
143
|
@d.lock('EXCLUSIVE'){@d.insert(:name=>'a')}
|
135
144
|
end
|
@@ -557,9 +566,11 @@ context "Postgres::Database schema qualified tables" do
|
|
557
566
|
POSTGRES_DB.drop_table(:schema_test.qualify(:schema_test))
|
558
567
|
end
|
559
568
|
|
560
|
-
specify "#tables should include
|
569
|
+
specify "#tables should not include tables in a default non-public schema" do
|
561
570
|
POSTGRES_DB.create_table(:schema_test__schema_test){integer :i}
|
562
|
-
POSTGRES_DB.tables.
|
571
|
+
POSTGRES_DB.tables.should include(:schema_test)
|
572
|
+
POSTGRES_DB.tables.should_not include(:pg_am)
|
573
|
+
POSTGRES_DB.tables.should_not include(:domain_udt_usage)
|
563
574
|
end
|
564
575
|
|
565
576
|
specify "#tables should return tables in the schema provided by the :schema argument" do
|
@@ -567,9 +578,28 @@ context "Postgres::Database schema qualified tables" do
|
|
567
578
|
POSTGRES_DB.tables(:schema=>:schema_test).should == [:schema_test]
|
568
579
|
end
|
569
580
|
|
570
|
-
specify "#
|
581
|
+
specify "#schema should not include columns from tables in a default non-public schema" do
|
582
|
+
POSTGRES_DB.create_table(:schema_test__domains){integer :i}
|
583
|
+
sch = POSTGRES_DB.schema(:domains)
|
584
|
+
cs = sch.map{|x| x.first}
|
585
|
+
cs.should include(:i)
|
586
|
+
cs.should_not include(:data_type)
|
587
|
+
end
|
588
|
+
|
589
|
+
specify "#schema should only include columns from the table in the given :schema argument" do
|
590
|
+
POSTGRES_DB.create_table!(:domains){integer :d}
|
591
|
+
POSTGRES_DB.create_table(:schema_test__domains){integer :i}
|
592
|
+
sch = POSTGRES_DB.schema(:domains, :schema=>:schema_test)
|
593
|
+
cs = sch.map{|x| x.first}
|
594
|
+
cs.should include(:i)
|
595
|
+
cs.should_not include(:d)
|
596
|
+
POSTGRES_DB.drop_table(:domains)
|
597
|
+
end
|
598
|
+
|
599
|
+
specify "#table_exists? should not include tables from the default non-public schemas" do
|
571
600
|
POSTGRES_DB.create_table(:schema_test__schema_test){integer :i}
|
572
|
-
POSTGRES_DB.table_exists?(:schema_test).should ==
|
601
|
+
POSTGRES_DB.table_exists?(:schema_test).should == true
|
602
|
+
POSTGRES_DB.table_exists?(:domain_udt_usage).should == false
|
573
603
|
end
|
574
604
|
|
575
605
|
specify "#table_exists? should see if the table is in a given schema" do
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'logger'
|
3
3
|
unless Object.const_defined?('Sequel')
|
4
|
-
$:.unshift(File.join(File.dirname(__FILE__), "../../lib/"))
|
4
|
+
$:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), "../../lib/"))
|
5
5
|
require 'sequel'
|
6
6
|
Sequel.quote_identifiers = false
|
7
7
|
end
|
8
8
|
begin
|
9
|
-
require File.join(File.dirname(File.dirname(__FILE__)), 'spec_config.rb')
|
9
|
+
require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'spec_config.rb')
|
10
10
|
rescue LoadError
|
11
11
|
end
|
12
12
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
|
2
2
|
CONNECTION_POOL_DEFAULTS = {:pool_timeout=>5, :pool_sleep_time=>0.001, :max_connections=>4}
|
3
3
|
|
4
4
|
context "An empty ConnectionPool" do
|
@@ -70,7 +70,7 @@ context "A connection pool handling connections" do
|
|
70
70
|
@cpool.hold {:block_return}.should == :block_return
|
71
71
|
end
|
72
72
|
|
73
|
-
if RUBY_VERSION < '1.9.0' and
|
73
|
+
if RUBY_VERSION < '1.9.0' and !defined?(RUBY_ENGINE)
|
74
74
|
specify "#hold should remove dead threads from the pool if it reaches its max_size" do
|
75
75
|
Thread.new{@cpool.hold{Thread.current.exit!}}.join
|
76
76
|
@cpool.allocated.keys.map{|t| t.alive?}.should == [false]
|
@@ -96,7 +96,7 @@ context "A connection pool handling connections" do
|
|
96
96
|
|
97
97
|
specify "#hold should remove the connection if a DatabaseDisconnectError is raised" do
|
98
98
|
@cpool.created_count.should == 0
|
99
|
-
@cpool.hold{Thread.new{@cpool.hold{}}; sleep 0.
|
99
|
+
@cpool.hold{Thread.new{@cpool.hold{}}; sleep 0.03}
|
100
100
|
@cpool.created_count.should == 2
|
101
101
|
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.should raise_error(Sequel::DatabaseDisconnectError)
|
102
102
|
@cpool.created_count.should == 1
|
data/spec/core/core_sql_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
|
2
2
|
|
3
3
|
context "Array#all_two_pairs?" do
|
4
4
|
specify "should return false if empty" do
|
@@ -39,6 +39,10 @@ context "Array#case and Hash#case" do
|
|
39
39
|
@d.literal([[:x, :y], [:a, :b]].case(:z, :exp__w)).should == '(CASE exp.w WHEN x THEN y WHEN a THEN b ELSE z END)'
|
40
40
|
end
|
41
41
|
|
42
|
+
specify "should return SQL CASE expression with expression even if nil" do
|
43
|
+
@d.literal({:x=>:y}.case(:z, nil)).should == '(CASE NULL WHEN x THEN y ELSE z END)'
|
44
|
+
end
|
45
|
+
|
42
46
|
specify "should raise an error if an array that isn't all two pairs is used" do
|
43
47
|
proc{[:b].case(:a)}.should raise_error(Sequel::Error)
|
44
48
|
proc{[:b, :c].case(:a)}.should raise_error(Sequel::Error)
|
@@ -51,19 +55,28 @@ context "Array#case and Hash#case" do
|
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
|
-
context "Array#sql_array" do
|
58
|
+
context "Array#sql_value_list and #sql_array" do
|
55
59
|
before do
|
56
60
|
@d = Sequel::Dataset.new(nil)
|
57
61
|
end
|
58
62
|
|
59
|
-
specify "should treat the array as an SQL
|
60
|
-
@d.
|
61
|
-
@d.
|
63
|
+
specify "should treat the array as an SQL value list instead of conditions when used as a placeholder value" do
|
64
|
+
@d.filter("(a, b) IN ?", [[:x, 1], [:y, 2]]).sql.should == 'SELECT * WHERE ((a, b) IN ((x = 1) AND (y = 2)))'
|
65
|
+
@d.filter("(a, b) IN ?", [[:x, 1], [:y, 2]].sql_value_list).sql.should == 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
|
66
|
+
@d.filter("(a, b) IN ?", [[:x, 1], [:y, 2]].sql_array).sql.should == 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
|
67
|
+
end
|
68
|
+
|
69
|
+
specify "should be no difference when used as a hash value" do
|
70
|
+
@d.filter([:a, :b]=>[[:x, 1], [:y, 2]]).sql.should == 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
|
71
|
+
@d.filter([:a, :b]=>[[:x, 1], [:y, 2]].sql_value_list).sql.should == 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
|
62
72
|
@d.filter([:a, :b]=>[[:x, 1], [:y, 2]].sql_array).sql.should == 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
|
63
73
|
end
|
64
74
|
end
|
65
75
|
|
66
76
|
context "String#lit" do
|
77
|
+
before do
|
78
|
+
@ds = ds = MockDatabase.new.dataset
|
79
|
+
end
|
67
80
|
specify "should return an LiteralString object" do
|
68
81
|
'xyz'.lit.should be_a_kind_of(Sequel::LiteralString)
|
69
82
|
'xyz'.lit.to_s.should == 'xyz'
|
@@ -77,19 +90,24 @@ context "String#lit" do
|
|
77
90
|
specify "should return a PlaceholderLiteralString object if args are given" do
|
78
91
|
a = 'DISTINCT ?'.lit(:a)
|
79
92
|
a.should be_a_kind_of(Sequel::SQL::PlaceholderLiteralString)
|
80
|
-
ds
|
81
|
-
ds.
|
82
|
-
ds.
|
83
|
-
ds.literal(a).should == 'DISTINCT "a"'
|
93
|
+
@ds.literal(a).should == 'DISTINCT a'
|
94
|
+
@ds.quote_identifiers = true
|
95
|
+
@ds.literal(a).should == 'DISTINCT "a"'
|
84
96
|
end
|
85
97
|
|
86
98
|
specify "should handle named placeholders if given a single argument hash" do
|
87
99
|
a = 'DISTINCT :b'.lit(:b=>:a)
|
88
100
|
a.should be_a_kind_of(Sequel::SQL::PlaceholderLiteralString)
|
89
|
-
ds
|
90
|
-
ds.
|
91
|
-
ds.
|
92
|
-
|
101
|
+
@ds.literal(a).should == 'DISTINCT a'
|
102
|
+
@ds.quote_identifiers = true
|
103
|
+
@ds.literal(a).should == 'DISTINCT "a"'
|
104
|
+
end
|
105
|
+
|
106
|
+
specify "should treat placeholder literal strings as generic expressions" do
|
107
|
+
a = ':b'.lit(:b=>:a)
|
108
|
+
@ds.literal(a + 1).should == "(a + 1)"
|
109
|
+
@ds.literal(a & :b).should == "(a AND b)"
|
110
|
+
@ds.literal(a.sql_string + :b).should == "(a || b)"
|
93
111
|
end
|
94
112
|
end
|
95
113
|
|
data/spec/core/database_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
|
2
2
|
|
3
3
|
context "A new Database" do
|
4
4
|
before do
|
@@ -213,6 +213,7 @@ context "Database#log_info" do
|
|
213
213
|
before do
|
214
214
|
@o = Object.new
|
215
215
|
def @o.logs; @logs || []; end
|
216
|
+
def @o.to_ary; [self]; end
|
216
217
|
def @o.method_missing(*args); (@logs ||= []) << args; end
|
217
218
|
@db = Sequel::Database.new(:logger=>@o)
|
218
219
|
end
|
@@ -234,6 +235,7 @@ context "Database#log_yield" do
|
|
234
235
|
def @o.logs; @logs || []; end
|
235
236
|
def @o.warn(*args); (@logs ||= []) << [:warn] + args; end
|
236
237
|
def @o.method_missing(*args); (@logs ||= []) << args; end
|
238
|
+
def @o.to_ary; [self]; end
|
237
239
|
@db = Sequel::Database.new(:logger=>@o)
|
238
240
|
end
|
239
241
|
|
@@ -693,10 +695,33 @@ context "Database#transaction" do
|
|
693
695
|
end
|
694
696
|
|
695
697
|
specify "should wrap the supplied block with BEGIN + COMMIT statements" do
|
696
|
-
@db.transaction
|
698
|
+
@db.transaction{@db.execute 'DROP TABLE test;'}
|
697
699
|
@db.sql.should == ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
698
700
|
end
|
699
701
|
|
702
|
+
specify "should support transaction isolation levels" do
|
703
|
+
@db.meta_def(:supports_transaction_isolation_levels?){true}
|
704
|
+
[:uncommitted, :committed, :repeatable, :serializable].each do |l|
|
705
|
+
@db.transaction(:isolation=>l){@db.run "DROP TABLE #{l}"}
|
706
|
+
end
|
707
|
+
@db.sql.should == ['BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', 'DROP TABLE uncommitted', 'COMMIT',
|
708
|
+
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED', 'DROP TABLE committed', 'COMMIT',
|
709
|
+
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL REPEATABLE READ', 'DROP TABLE repeatable', 'COMMIT',
|
710
|
+
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE', 'DROP TABLE serializable', 'COMMIT']
|
711
|
+
end
|
712
|
+
|
713
|
+
specify "should allow specifying a default transaction isolation level" do
|
714
|
+
@db.meta_def(:supports_transaction_isolation_levels?){true}
|
715
|
+
[:uncommitted, :committed, :repeatable, :serializable].each do |l|
|
716
|
+
@db.transaction_isolation_level = l
|
717
|
+
@db.transaction{@db.run "DROP TABLE #{l}"}
|
718
|
+
end
|
719
|
+
@db.sql.should == ['BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', 'DROP TABLE uncommitted', 'COMMIT',
|
720
|
+
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED', 'DROP TABLE committed', 'COMMIT',
|
721
|
+
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL REPEATABLE READ', 'DROP TABLE repeatable', 'COMMIT',
|
722
|
+
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE', 'DROP TABLE serializable', 'COMMIT']
|
723
|
+
end
|
724
|
+
|
700
725
|
specify "should handle returning inside of the block by committing" do
|
701
726
|
def @db.ret_commit
|
702
727
|
transaction do
|
@@ -1581,6 +1606,18 @@ context "Database#supports_savepoints?" do
|
|
1581
1606
|
end
|
1582
1607
|
end
|
1583
1608
|
|
1609
|
+
context "Database#supports_prepared_transactions?" do
|
1610
|
+
specify "should be false by default" do
|
1611
|
+
Sequel::Database.new.supports_prepared_transactions?.should == false
|
1612
|
+
end
|
1613
|
+
end
|
1614
|
+
|
1615
|
+
context "Database#supports_transaction_isolation_levels?" do
|
1616
|
+
specify "should be false by default" do
|
1617
|
+
Sequel::Database.new.supports_transaction_isolation_levels?.should == false
|
1618
|
+
end
|
1619
|
+
end
|
1620
|
+
|
1584
1621
|
context "Database#input_identifier_meth" do
|
1585
1622
|
specify "should be the input_identifer method of a default dataset for this database" do
|
1586
1623
|
db = Sequel::Database.new
|