sequel 3.47.0 → 3.48.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +230 -0
- data/README.rdoc +31 -40
- data/Rakefile +1 -14
- data/doc/active_record.rdoc +29 -29
- data/doc/association_basics.rdoc +4 -13
- data/doc/cheat_sheet.rdoc +8 -6
- data/doc/code_order.rdoc +89 -0
- data/doc/core_extensions.rdoc +3 -3
- data/doc/dataset_basics.rdoc +7 -8
- data/doc/dataset_filtering.rdoc +7 -2
- data/doc/mass_assignment.rdoc +2 -3
- data/doc/migration.rdoc +8 -8
- data/doc/model_hooks.rdoc +11 -7
- data/doc/object_model.rdoc +2 -2
- data/doc/opening_databases.rdoc +5 -14
- data/doc/prepared_statements.rdoc +5 -9
- data/doc/querying.rdoc +23 -28
- data/doc/reflection.rdoc +11 -0
- data/doc/release_notes/3.48.0.txt +477 -0
- data/doc/schema_modification.rdoc +12 -5
- data/doc/security.rdoc +2 -2
- data/doc/sharding.rdoc +1 -2
- data/doc/sql.rdoc +10 -13
- data/doc/testing.rdoc +8 -4
- data/doc/transactions.rdoc +2 -2
- data/doc/validations.rdoc +40 -17
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado.rb +25 -20
- data/lib/sequel/adapters/ado/access.rb +1 -0
- data/lib/sequel/adapters/ado/mssql.rb +1 -0
- data/lib/sequel/adapters/db2.rb +9 -7
- data/lib/sequel/adapters/dbi.rb +16 -16
- data/lib/sequel/adapters/do.rb +17 -18
- data/lib/sequel/adapters/do/mysql.rb +1 -0
- data/lib/sequel/adapters/do/postgres.rb +2 -0
- data/lib/sequel/adapters/do/sqlite.rb +1 -0
- data/lib/sequel/adapters/firebird.rb +5 -7
- data/lib/sequel/adapters/ibmdb.rb +23 -20
- data/lib/sequel/adapters/informix.rb +8 -2
- data/lib/sequel/adapters/jdbc.rb +39 -35
- data/lib/sequel/adapters/jdbc/as400.rb +1 -0
- data/lib/sequel/adapters/jdbc/cubrid.rb +1 -0
- data/lib/sequel/adapters/jdbc/db2.rb +1 -0
- data/lib/sequel/adapters/jdbc/derby.rb +1 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +1 -0
- data/lib/sequel/adapters/jdbc/h2.rb +1 -0
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -0
- data/lib/sequel/adapters/jdbc/informix.rb +1 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +1 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +1 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +2 -0
- data/lib/sequel/adapters/jdbc/progress.rb +1 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -0
- data/lib/sequel/adapters/mock.rb +30 -31
- data/lib/sequel/adapters/mysql.rb +6 -7
- data/lib/sequel/adapters/mysql2.rb +5 -6
- data/lib/sequel/adapters/odbc.rb +22 -20
- data/lib/sequel/adapters/odbc/mssql.rb +1 -0
- data/lib/sequel/adapters/openbase.rb +4 -1
- data/lib/sequel/adapters/oracle.rb +10 -8
- data/lib/sequel/adapters/postgres.rb +12 -10
- data/lib/sequel/adapters/shared/access.rb +6 -0
- data/lib/sequel/adapters/shared/cubrid.rb +2 -0
- data/lib/sequel/adapters/shared/db2.rb +2 -0
- data/lib/sequel/adapters/shared/firebird.rb +2 -0
- data/lib/sequel/adapters/shared/informix.rb +2 -0
- data/lib/sequel/adapters/shared/mssql.rb +14 -8
- data/lib/sequel/adapters/shared/mysql.rb +6 -0
- data/lib/sequel/adapters/shared/oracle.rb +2 -0
- data/lib/sequel/adapters/shared/postgres.rb +14 -4
- data/lib/sequel/adapters/shared/progress.rb +1 -0
- data/lib/sequel/adapters/shared/sqlite.rb +4 -3
- data/lib/sequel/adapters/sqlite.rb +6 -7
- data/lib/sequel/adapters/swift.rb +20 -21
- data/lib/sequel/adapters/swift/mysql.rb +1 -0
- data/lib/sequel/adapters/swift/postgres.rb +2 -0
- data/lib/sequel/adapters/swift/sqlite.rb +1 -0
- data/lib/sequel/adapters/tinytds.rb +5 -6
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +68 -0
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +57 -50
- data/lib/sequel/database/connecting.rb +9 -10
- data/lib/sequel/database/dataset.rb +11 -6
- data/lib/sequel/database/dataset_defaults.rb +61 -69
- data/lib/sequel/database/features.rb +21 -0
- data/lib/sequel/database/misc.rb +23 -3
- data/lib/sequel/database/query.rb +13 -7
- data/lib/sequel/database/schema_methods.rb +6 -6
- data/lib/sequel/database/transactions.rb +1 -0
- data/lib/sequel/dataset/actions.rb +51 -38
- data/lib/sequel/dataset/features.rb +1 -0
- data/lib/sequel/dataset/graph.rb +9 -33
- data/lib/sequel/dataset/misc.rb +30 -5
- data/lib/sequel/dataset/mutation.rb +2 -3
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/dataset/query.rb +91 -27
- data/lib/sequel/dataset/sql.rb +40 -6
- data/lib/sequel/deprecated.rb +74 -0
- data/lib/sequel/deprecated_core_extensions.rb +135 -0
- data/lib/sequel/extensions/columns_introspection.rb +1 -5
- data/lib/sequel/extensions/core_extensions.rb +10 -3
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +33 -0
- data/lib/sequel/extensions/filter_having.rb +58 -0
- data/lib/sequel/extensions/graph_each.rb +63 -0
- data/lib/sequel/extensions/hash_aliases.rb +44 -0
- data/lib/sequel/extensions/looser_typecasting.rb +14 -3
- data/lib/sequel/extensions/migration.rb +2 -3
- data/lib/sequel/extensions/named_timezones.rb +14 -1
- data/lib/sequel/extensions/null_dataset.rb +7 -1
- data/lib/sequel/extensions/pagination.rb +15 -5
- data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +48 -14
- data/lib/sequel/extensions/pg_json.rb +7 -7
- data/lib/sequel/extensions/pg_range_ops.rb +8 -2
- data/lib/sequel/extensions/pg_statement_cache.rb +1 -0
- data/lib/sequel/extensions/pretty_table.rb +13 -4
- data/lib/sequel/extensions/query.rb +21 -4
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +22 -0
- data/lib/sequel/extensions/schema_caching.rb +10 -7
- data/lib/sequel/extensions/schema_dumper.rb +35 -48
- data/lib/sequel/extensions/select_remove.rb +13 -4
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +117 -0
- data/lib/sequel/extensions/set_overrides.rb +43 -0
- data/lib/sequel/extensions/to_dot.rb +6 -0
- data/lib/sequel/model.rb +12 -6
- data/lib/sequel/model/associations.rb +80 -38
- data/lib/sequel/model/base.rb +137 -52
- data/lib/sequel/model/errors.rb +7 -2
- data/lib/sequel/plugins/active_model.rb +13 -0
- data/lib/sequel/plugins/after_initialize.rb +43 -0
- data/lib/sequel/plugins/association_proxies.rb +63 -7
- data/lib/sequel/plugins/auto_validations.rb +56 -16
- data/lib/sequel/plugins/blacklist_security.rb +63 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +9 -0
- data/lib/sequel/plugins/constraint_validations.rb +50 -8
- data/lib/sequel/plugins/dataset_associations.rb +2 -0
- data/lib/sequel/plugins/hook_class_methods.rb +7 -1
- data/lib/sequel/plugins/identity_map.rb +4 -0
- data/lib/sequel/plugins/json_serializer.rb +32 -13
- data/lib/sequel/plugins/optimistic_locking.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +4 -4
- data/lib/sequel/plugins/scissors.rb +33 -0
- data/lib/sequel/plugins/serialization.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +6 -0
- data/lib/sequel/plugins/tree.rb +5 -1
- data/lib/sequel/plugins/validation_class_methods.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +15 -11
- data/lib/sequel/plugins/xml_serializer.rb +12 -3
- data/lib/sequel/sql.rb +12 -2
- data/lib/sequel/timezones.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/lib/sequel_core.rb +1 -0
- data/lib/sequel_model.rb +1 -0
- data/spec/adapters/mssql_spec.rb +24 -57
- data/spec/adapters/postgres_spec.rb +27 -55
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +1 -1
- data/spec/bin_spec.rb +251 -0
- data/spec/core/database_spec.rb +46 -32
- data/spec/core/dataset_spec.rb +233 -181
- data/spec/core/deprecated_spec.rb +78 -0
- data/spec/core/expression_filters_spec.rb +3 -4
- data/spec/core/mock_adapter_spec.rb +9 -9
- data/spec/core/object_graph_spec.rb +9 -19
- data/spec/core/schema_spec.rb +3 -1
- data/spec/core/spec_helper.rb +19 -0
- data/spec/core_extensions_spec.rb +80 -30
- data/spec/extensions/after_initialize_spec.rb +24 -0
- data/spec/extensions/association_proxies_spec.rb +37 -1
- data/spec/extensions/auto_validations_spec.rb +20 -4
- data/spec/extensions/blacklist_security_spec.rb +87 -0
- data/spec/extensions/boolean_readers_spec.rb +2 -1
- data/spec/extensions/class_table_inheritance_spec.rb +7 -0
- data/spec/extensions/columns_introspection_spec.rb +3 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +83 -5
- data/spec/extensions/core_refinements_spec.rb +7 -7
- data/spec/extensions/dataset_associations_spec.rb +2 -2
- data/spec/extensions/date_arithmetic_spec.rb +1 -1
- data/spec/extensions/defaults_setter_spec.rb +2 -1
- data/spec/extensions/empty_array_ignore_nulls_spec.rb +24 -0
- data/spec/extensions/filter_having_spec.rb +40 -0
- data/spec/extensions/graph_each_spec.rb +109 -0
- data/spec/extensions/hash_aliases_spec.rb +16 -0
- data/spec/extensions/hook_class_methods_spec.rb +2 -2
- data/spec/extensions/identity_map_spec.rb +3 -3
- data/spec/extensions/json_serializer_spec.rb +19 -19
- data/spec/extensions/lazy_attributes_spec.rb +1 -0
- data/spec/extensions/list_spec.rb +13 -13
- data/spec/extensions/looser_typecasting_spec.rb +10 -3
- data/spec/extensions/many_through_many_spec.rb +1 -1
- data/spec/extensions/migration_spec.rb +7 -7
- data/spec/extensions/named_timezones_spec.rb +6 -0
- data/spec/extensions/nested_attributes_spec.rb +2 -2
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/pagination_spec.rb +2 -2
- data/spec/extensions/pg_hstore_ops_spec.rb +75 -0
- data/spec/extensions/pg_range_ops_spec.rb +4 -2
- data/spec/extensions/pg_row_plugin_spec.rb +1 -1
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +3 -3
- data/spec/extensions/schema_caching_spec.rb +3 -3
- data/spec/extensions/schema_dumper_spec.rb +27 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/scissors_spec.rb +26 -0
- data/spec/extensions/select_remove_spec.rb +1 -1
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +102 -0
- data/spec/extensions/set_overrides_spec.rb +45 -0
- data/spec/extensions/single_table_inheritance_spec.rb +10 -0
- data/spec/extensions/spec_helper.rb +24 -1
- data/spec/extensions/static_cache_spec.rb +1 -1
- data/spec/extensions/string_stripper_spec.rb +2 -1
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/typecast_on_load_spec.rb +3 -2
- data/spec/extensions/update_primary_key_spec.rb +2 -2
- data/spec/extensions/validation_class_methods_spec.rb +19 -19
- data/spec/extensions/validation_helpers_spec.rb +30 -21
- data/spec/extensions/xml_serializer_spec.rb +5 -5
- data/spec/integration/associations_test.rb +10 -30
- data/spec/integration/dataset_test.rb +20 -24
- data/spec/integration/eager_loader_test.rb +5 -5
- data/spec/integration/model_test.rb +3 -3
- data/spec/integration/plugin_test.rb +7 -39
- data/spec/integration/schema_test.rb +4 -38
- data/spec/integration/spec_helper.rb +2 -1
- data/spec/model/association_reflection_spec.rb +70 -5
- data/spec/model/associations_spec.rb +11 -11
- data/spec/model/base_spec.rb +25 -8
- data/spec/model/class_dataset_methods_spec.rb +143 -0
- data/spec/model/dataset_methods_spec.rb +1 -1
- data/spec/model/eager_loading_spec.rb +25 -25
- data/spec/model/hooks_spec.rb +1 -1
- data/spec/model/model_spec.rb +22 -7
- data/spec/model/plugins_spec.rb +1 -6
- data/spec/model/record_spec.rb +37 -29
- data/spec/model/spec_helper.rb +23 -1
- data/spec/model/validations_spec.rb +15 -17
- metadata +32 -3
@@ -5,14 +5,14 @@ Here's a brief description of the most common schema modification methods:
|
|
5
5
|
== +create_table+
|
6
6
|
|
7
7
|
+create_table+ is the most common schema modification method, and it's used for adding new tables
|
8
|
-
to the
|
8
|
+
to the database. You provide it with the name of the table as a symbol, as well a block:
|
9
9
|
|
10
10
|
create_table(:artists) do
|
11
11
|
primary_key :id
|
12
12
|
String :name
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
Note that if you want a primary key for the table, you need to specify it, Sequel does not create one
|
16
16
|
by default.
|
17
17
|
|
18
18
|
=== Column types
|
@@ -521,11 +521,18 @@ ruby class, in which case it gets converted to an appropriate database type.
|
|
521
521
|
|
522
522
|
=== +set_column_allow_null+
|
523
523
|
|
524
|
-
This
|
524
|
+
This allows you to set the column as allowing NULL values:
|
525
525
|
|
526
526
|
alter_table(:albums) do
|
527
|
-
set_column_allow_null :artist_id
|
528
|
-
|
527
|
+
set_column_allow_null :artist_id
|
528
|
+
end
|
529
|
+
|
530
|
+
=== +set_column_not_null+
|
531
|
+
|
532
|
+
This allows you to set the column as not allowing NULL values:
|
533
|
+
|
534
|
+
alter_table(:albums) do
|
535
|
+
set_column_not_null :artist_id
|
529
536
|
end
|
530
537
|
|
531
538
|
== Other +Database+ schema modification methods
|
data/doc/security.rdoc
CHANGED
@@ -32,7 +32,7 @@ vulnerable to code execution.
|
|
32
32
|
== SQL Injection
|
33
33
|
|
34
34
|
The primary security concern in SQL database libraries is SQL injection.
|
35
|
-
Because Sequel
|
35
|
+
Because Sequel promotes using ruby objects for SQL concepts instead
|
36
36
|
of raw SQL, it is less likely to be vulnerable to SQL injection.
|
37
37
|
However, because Sequel still makes it easy to use raw SQL, misuse of the
|
38
38
|
library can result in SQL injection in your application.
|
@@ -153,7 +153,7 @@ class methods also call down to the filter methods.
|
|
153
153
|
|
154
154
|
==== SQL Fragment passed to Dataset#update
|
155
155
|
|
156
|
-
Similar to the filter methods, Sequel::Dataset#update
|
156
|
+
Similar to the filter methods, Sequel::Dataset#update also treats a
|
157
157
|
string argument as raw SQL:
|
158
158
|
|
159
159
|
DB[:table].update("column = 1")
|
data/doc/sharding.rdoc
CHANGED
@@ -15,8 +15,7 @@ support is to use the empty hash:
|
|
15
15
|
|
16
16
|
DB=Sequel.connect('postgres://master_server/database', :servers=>{})
|
17
17
|
|
18
|
-
In most cases, you are probably not going to want to use an empty hash
|
19
|
-
so you'll want to have entries in the hash. Keys in the server hash are
|
18
|
+
In most cases, you are probably not going to want to use an empty hash. Keys in the server hash are
|
20
19
|
not restricted to type, but the general recommendation is to use a symbol
|
21
20
|
unless you have special requirements. Values in the server hash should be
|
22
21
|
either hashes or procs that return hashes. These hashes are merged into
|
data/doc/sql.rdoc
CHANGED
@@ -86,13 +86,13 @@ So you can use Sequel's DSL everywhere you find it helpful, and fallback to lite
|
|
86
86
|
|
87
87
|
== Translating SQL Expressions into Sequel
|
88
88
|
|
89
|
-
The rest of this guide assumes you want to use Sequel's DSL to represent your query, that you know how to write the query in SQL, but you aren't sure how to write it in Sequel.
|
89
|
+
The rest of this guide assumes you want to use Sequel's DSL to represent your query, that you know how to write the query in SQL, but you aren't sure how to write it in Sequel's DSL.
|
90
90
|
|
91
91
|
This section will describe how specific SQL expressions are handled in Sequel. The next section will discuss how to create queries by using method chaining on datasets.
|
92
92
|
|
93
93
|
=== <tt>Database#literal</tt>
|
94
94
|
|
95
|
-
|
95
|
+
It's important to get familiar with the <tt>Database#literal</tt> method, which will return the SQL that will be used for a given expression:
|
96
96
|
|
97
97
|
DB.literal(1)
|
98
98
|
# => "1"
|
@@ -101,7 +101,7 @@ Before we get started, I think it's important to get familiar with the <tt>Datab
|
|
101
101
|
DB.literal('string')
|
102
102
|
# => "'string'"
|
103
103
|
|
104
|
-
|
104
|
+
Try playing around to see how different objects get literalized into SQL
|
105
105
|
|
106
106
|
=== Database Loggers
|
107
107
|
|
@@ -346,18 +346,15 @@ Sequel defines the & and | methods on most Sequel-specific expression objects to
|
|
346
346
|
Sequel.expr(:column1=>1) | {:column2=>2} # (("column1" = 1) OR ("column2" = 2))
|
347
347
|
(Sequel.function(:func) > 1) & :column3 # ((func() > 1) AND "column3")
|
348
348
|
|
349
|
-
Note the use of parentheses in the last statement. If you omit them, you won't get what you expect
|
349
|
+
Note the use of parentheses in the last statement. If you omit them, you won't get what you expect.
|
350
|
+
Because & has higher precedence than >
|
350
351
|
|
351
|
-
Sequel.function(:func) > 1 & :column3
|
352
|
+
Sequel.function(:func) > 1 & :column3
|
352
353
|
|
353
|
-
|
354
|
+
is parsed as:
|
354
355
|
|
355
356
|
Sequel.function(:func) > (1 & :column3)
|
356
357
|
|
357
|
-
In this case, <tt>:column3.to_int</tt> returns an odd integer, so:
|
358
|
-
|
359
|
-
1 & :column3 # => 1
|
360
|
-
|
361
358
|
You and also use the <tt>Sequel.&</tt> and <tt>Sequel.|</tt> methods:
|
362
359
|
|
363
360
|
Sequel.&(:column1, :column2) # ("column1" AND "column2")
|
@@ -505,7 +502,7 @@ If the hash or array has multiple arguments, multiple WHEN clauses are used:
|
|
505
502
|
Sequel.case({:c=>1, :d=>2}, 0) # (CASE WHEN "c" THEN 1 WHEN "d" THEN 2 ELSE 0 END)
|
506
503
|
Sequel.case([[:c, 1], [:d, 2]], 0) # (CASE WHEN "c" THEN 1 WHEN "d" THEN 2 ELSE 0 END)
|
507
504
|
|
508
|
-
If you provide a
|
505
|
+
If you provide a 3rd argument to <tt>Sequel.case</tt>, it goes between CASE and WHEN:
|
509
506
|
|
510
507
|
Sequel.case({2=>1, 3=>5}, 0, :column) # (CASE column WHEN 2 THEN 1 WHEN 3 THEN 5 ELSE 0 END)
|
511
508
|
|
@@ -538,9 +535,9 @@ If you want to select from multiple FROM tables, use multiple arguments:
|
|
538
535
|
|
539
536
|
DB[:albums, :artists] # SELECT * FROM albums, artists
|
540
537
|
|
541
|
-
If you don't want to select from any FROM tables,
|
538
|
+
If you don't want to select from any FROM tables, just call dataset:
|
542
539
|
|
543
|
-
DB
|
540
|
+
DB.dataset # SELECT *
|
544
541
|
|
545
542
|
=== Chaining Methods
|
546
543
|
|
data/doc/testing.rdoc
CHANGED
@@ -6,8 +6,6 @@ Whether or not you use Sequel in your application, you are usually going to want
|
|
6
6
|
|
7
7
|
These run each test in its own transaction, the recommended way to test.
|
8
8
|
|
9
|
-
Make sure you are using Sequel 3.29.0 or above when using these examples, as older versions don't support the <tt>:rollback=>:always</tt> option.
|
10
|
-
|
11
9
|
=== RSpec 1
|
12
10
|
|
13
11
|
class Spec::Example::ExampleGroup
|
@@ -103,7 +101,7 @@ Use Sequel.transaction with an array of databases:
|
|
103
101
|
|
104
102
|
In some cases, it is not possible to use transactions. For example, if you are testing a web application that is running in a separate process, you don't have access to that process's database connections, so you can't run your examples in transactions. In that case, the best way to handle things is to cleanup after each test by deleting or truncating the database tables used in the test.
|
105
103
|
|
106
|
-
The order in which you delete/truncate the tables is important if you are using referential integrity in your database (which you
|
104
|
+
The order in which you delete/truncate the tables is important if you are using referential integrity in your database (which you should be doing). If you are using referential integrity, you need to make sure to delete in tables referencing other tables before the tables that are being referenced. For example, if you have an +albums+ table with an +artist_id+ field referencing the +artists+ table, you want to delete/truncate the +albums+ table before the +artists+ table. Note that if you have cyclic references in your database, you will probably need to write your own custom cleaning code.
|
107
105
|
|
108
106
|
=== RSpec
|
109
107
|
|
@@ -138,16 +136,22 @@ The +spec+ rake task (which is also the default rake task) runs Sequel's core an
|
|
138
136
|
|
139
137
|
The +spec_plugin+ rake task runs the specs for the plugins and extensions that ship with Sequel. These also use a mocked database connection, and operate very similarly to the general Sequel core and model specs.
|
140
138
|
|
139
|
+
== rake spec_bin
|
140
|
+
|
141
|
+
The +spec_bin+ rake task runs the specs for bin/sequel. These use an SQLite3 database, and require either the sqlite3 (non-JRuby) or jdbc-sqlite3 (JRuby) gem.
|
142
|
+
|
141
143
|
== rake spec_<i>adapter</i> (e.g. rake spec_postgres)
|
142
144
|
|
143
145
|
The <tt>spec_<i>adapter</i></tt> specs run against a real database connection with nothing mocked, and test for correct results. They are slower than the standard specs, but they will catch errors that are mocked out by the default specs, as well as show issues that only occur on a certain database, adapter, or a combination of the two.
|
144
146
|
|
145
|
-
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.
|
147
|
+
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 rake spec_integration to just run the shared integration tests.
|
146
148
|
|
147
149
|
== Environment variables
|
148
150
|
|
149
151
|
Sequel often 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 spec/spec_config.rb.example to spec/spec_config.rb 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.
|
150
152
|
|
153
|
+
Sequel does not create test databases automatically, except for file-based databases such as SQLite/H2/HSQLDB/Derby. It's up to the user to create the test databases manually and give Sequel a valid connection string in an environment variable (or setup the connection object in spec_config.rb).
|
154
|
+
|
151
155
|
=== Connection Strings
|
152
156
|
|
153
157
|
The following environment variables specify Database connection URL strings:
|
data/doc/transactions.rdoc
CHANGED
@@ -27,7 +27,6 @@ If the block raises a Sequel::Rollback exception, the transaction is rolled back
|
|
27
27
|
|
28
28
|
If any other exception is raised, the transaction is rolled back, and the exception is raised outside the block:
|
29
29
|
|
30
|
-
# ArgumentError raised
|
31
30
|
DB.transaction do # BEGIN
|
32
31
|
raise ArgumentError
|
33
32
|
end # ROLLBACK
|
@@ -45,6 +44,7 @@ If you always want to rollback (useful for testing), use the <tt>:rollback => :a
|
|
45
44
|
DB.transaction(:rollback => :always) do # BEGIN
|
46
45
|
DB[:foo].insert(1) # INSERT
|
47
46
|
end # ROLLBACK
|
47
|
+
# no exception raised
|
48
48
|
|
49
49
|
If you want to check whether you are currently in a transaction, use the Database#in_transaction? method:
|
50
50
|
|
@@ -129,7 +129,7 @@ or roll the prepared transaction back:
|
|
129
129
|
|
130
130
|
== Transaction Isolation Levels
|
131
131
|
|
132
|
-
The SQL standard supports 4 isolation levels: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, and SERIALIZABLE. Not all databases implement the levels as specified in the standard (or implement the levels at all), but on
|
132
|
+
The SQL standard supports 4 isolation levels: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, and SERIALIZABLE. Not all databases implement the levels as specified in the standard (or implement the levels at all), but on most databases, you can specify which transaction isolation level you want to use via the :isolation option to <tt>Database#transaction</tt>. The isolation level is specified as one of the following symbols: :uncommitted, :committed, :repeatable, and :serializable. Using this option make Sequel use the correct transaction isolation syntax for your database:
|
133
133
|
|
134
134
|
DB.transaction(:isolation => :serializable) do # BEGIN
|
135
135
|
# SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
|
data/doc/validations.rdoc
CHANGED
@@ -32,7 +32,7 @@ to ensure that all values have at least two characters.
|
|
32
32
|
Unfortunately, sometimes there are situations where that is not possible. For
|
33
33
|
example, if you are using MySQL and don't have control over the database configuration,
|
34
34
|
it's possible that if you attempt to insert a string with 300 characters into a
|
35
|
-
varchar(255) field,
|
35
|
+
varchar(255) field, then MySQL may just silently truncate it for you, instead of
|
36
36
|
raising an error. In that case, it may be necessary to use a model validation
|
37
37
|
to enforce the database integrity.
|
38
38
|
|
@@ -172,16 +172,22 @@ This is probably the most commonly used helper method, which checks if the speci
|
|
172
172
|
|
173
173
|
class Album < Sequel::Model
|
174
174
|
def validate
|
175
|
+
super
|
175
176
|
validates_presence [:name, :website, :debut_album]
|
176
177
|
end
|
177
178
|
end
|
178
179
|
|
180
|
+
=== +validates_not_null+
|
181
|
+
|
182
|
+
This is similar to +validates_presence+, but only checks for NULL/nil values, allowing other blank objects such as empty strings or strings with just whitespace.
|
183
|
+
|
179
184
|
=== +validates_format+
|
180
185
|
|
181
186
|
+validates_format+ is used to ensure that the string value of the specified attributes matches the specified regular expression. It's useful for checking that fields such as email addresses, URLs, UPC codes, ISBN codes, and the like, are in a specific format. It can also be used to validate that only certain characters are used in the string.
|
182
187
|
|
183
188
|
class Album < Sequel::Model
|
184
189
|
def validate
|
190
|
+
super
|
185
191
|
validates_format /\A\d\d\d-\d-\d{7}-\d-\d\z/, :isbn
|
186
192
|
validates_format /\a[0-9a-zA-Z:' ]+\z/, :name
|
187
193
|
end
|
@@ -194,6 +200,7 @@ These methods all deal with ensuring that the length of the specified attribute
|
|
194
200
|
|
195
201
|
class Album < Sequel::Model
|
196
202
|
def validate
|
203
|
+
super
|
197
204
|
validates_exact_length 17, :isbn
|
198
205
|
validates_min_length 3, :name
|
199
206
|
validates_max_length 100, :name
|
@@ -207,6 +214,7 @@ These methods check that the specified attributes can be valid integers or valid
|
|
207
214
|
|
208
215
|
class Album < Sequel::Model
|
209
216
|
def validate
|
217
|
+
super
|
210
218
|
validates_integer :copies_sold
|
211
219
|
validates_numeric :replaygain
|
212
220
|
end
|
@@ -224,35 +232,33 @@ These methods check that the specified attributes can be valid integers or valid
|
|
224
232
|
|
225
233
|
=== +validates_type+
|
226
234
|
|
227
|
-
+validates_type+ checks that the specified attributes are instances of the class specified in the first argument. The class can be specified as the class itself, or as a string or symbol with the class name
|
235
|
+
+validates_type+ checks that the specified attributes are instances of the class specified in the first argument. The class can be specified as the class itself, or as a string or symbol with the class name, or as a an array of classes.
|
228
236
|
|
229
237
|
class Album < Sequel::Model
|
230
238
|
def validate
|
239
|
+
super
|
231
240
|
validates_type String, [:name, :website]
|
232
241
|
validates_type :Artist, :artist
|
242
|
+
validates_type [String, Integer], :foo
|
233
243
|
end
|
234
244
|
end
|
235
245
|
|
236
|
-
=== +
|
237
|
-
|
238
|
-
+validates_not_string+ is a special validation designed to be used with the <tt>raise_on_typecast_failure = false</tt> setting. By default, Sequel raises errors when typecasting fails, immediately when you try to set the value on the object:
|
246
|
+
=== +validates_schema_types+
|
239
247
|
|
240
|
-
|
241
|
-
album.copies_sold = 'banana' # raises Sequel::InvalidValue
|
242
|
-
|
243
|
-
The <tt>raise_on_typecast_failure = false</tt> setting tells Sequel to attempt to typecast values, but to silently ignore any errors raised:
|
248
|
+
+validates_schema_types+ uses the database metadata for the model's table to determine which ruby type(s) should be used for the given database type, and calls +validates_type+ with that ruby type. It's designed to be used with the <tt>raise_on_typecast_failure = false</tt> setting (the default starting in Sequel 4). <tt>raise_on_typecast_failure = false</tt, Sequel attempts to typecast values, but silently ignores any errors raised:
|
244
249
|
|
245
250
|
Album.raise_on_typecast_failure = false
|
246
251
|
album = Album.new
|
247
252
|
album.copies_sold = 'banana'
|
248
253
|
album.copies_sold # => 'banana'
|
249
254
|
|
250
|
-
|
255
|
+
When <tt>raise_on_typecast_failure = false</tt>, you can call +validates_schema_types+ with all columns. If any of those columns has a value that doesn't match the type that Sequel expects, it's probably because the column was set and Sequel was not able to typecast it correctly, which means it probably isn't valid. For example, let's say that you want to check that a couple of columns contain valid dates:
|
251
256
|
|
252
257
|
class Album < Sequel::Model
|
253
258
|
self.raise_on_typecast_failure = false
|
254
259
|
def validate
|
255
|
-
|
260
|
+
super
|
261
|
+
validates_schema_types [:release_date, :record_date]
|
256
262
|
end
|
257
263
|
end
|
258
264
|
|
@@ -264,7 +270,7 @@ The <tt>raise_on_typecast_failure = false</tt> setting tells Sequel to attempt t
|
|
264
270
|
album.valid? # => false
|
265
271
|
album.errors # => {:release_date=>["is not a valid date"]}
|
266
272
|
|
267
|
-
For web applications, you usually want the <tt>raise_on_typecast_failure = false</tt> setting, so that you can accept all of the input without raising an error, and then present the user with all error messages. Without the setting, if the user submits any invalid data, Sequel will immediately raise an error. +
|
273
|
+
For web applications, you usually want the <tt>raise_on_typecast_failure = false</tt> setting, so that you can accept all of the input without raising an error, and then present the user with all error messages. Without the setting, if the user submits any invalid data, Sequel will immediately raise an error. +validates_schema_types+ is helpful because it allows you to check for typecasting errors on columns, and provides a good default error message stating that the attribute is not of the expected type.
|
268
274
|
|
269
275
|
=== +validates_unique+
|
270
276
|
|
@@ -301,10 +307,11 @@ All +validation_helpers+ methods except +validates_unique+ accept the following
|
|
301
307
|
|
302
308
|
=== <tt>:message</tt>
|
303
309
|
|
304
|
-
The most commonly used option, used to override the default validation message. Can be either a string or a proc. If a string, it is used directly. If a proc, the proc is called and should return a string. If the validation method takes an argument before the array of attributes, that argument is passed as an argument to the proc. The exception is the +validates_not_string+ method, which doesn't take an argument, but passes the schema type symbol as the argument to the proc.
|
310
|
+
The most commonly used option, used to override the default validation message. Can be either a string or a proc. If a string, it is used directly. If a proc, the proc is called and should return a string. If the validation method takes an argument before the array of attributes, that argument is passed as an argument to the proc. The exception is the +validates_not_string+ method, which doesn't take an argument, but passes the schema type symbol as the argument to the proc.
|
305
311
|
|
306
312
|
class Album < Sequel::Model
|
307
313
|
def validate
|
314
|
+
super
|
308
315
|
validates_presence :copies_sold, :message=>'was not given'
|
309
316
|
validates_min_length 3, :name, :message=>proc{|s| "should be more than #{s} characters"}
|
310
317
|
end
|
@@ -316,6 +323,7 @@ The <tt>:allow_nil</tt> option skips the validation if the attribute value is ni
|
|
316
323
|
|
317
324
|
class Album < Sequel::Model
|
318
325
|
def validate
|
326
|
+
super
|
319
327
|
validates_presence :copies_sold
|
320
328
|
validates_integer :copies_sold, :allow_nil=>true
|
321
329
|
end
|
@@ -329,6 +337,7 @@ The <tt>:allow_blank</tt> is similar to the <tt>:allow_nil</tt> option, but inst
|
|
329
337
|
|
330
338
|
class Album < Sequel::Model
|
331
339
|
def validate
|
340
|
+
super
|
332
341
|
validates_format /\Ahttps?:\/\//, :website, :allow_blank=>true
|
333
342
|
end
|
334
343
|
end
|
@@ -386,8 +395,9 @@ These are the default error messages for all of the helper methods in +validatio
|
|
386
395
|
:length_range :: is too short or too long
|
387
396
|
:max_length :: is longer than #{arg} characters
|
388
397
|
:min_length :: is shorter than #{arg} characters
|
389
|
-
:
|
398
|
+
:not_null :: is not present
|
390
399
|
:numeric :: is not a number
|
400
|
+
:schema_types :: is not a valid #{schema_type}
|
391
401
|
:type :: is not a #{arg}
|
392
402
|
:presence :: is not present
|
393
403
|
:unique :: is already taken
|
@@ -404,6 +414,8 @@ It's easy to modify the default options used by +validation_helpers+. All of th
|
|
404
414
|
|
405
415
|
This updates the default messages that will be used for the presence, includes, max_length, and format validations, and sets the default value of the <tt>:allow_nil</tt> option to true for the includes, max_length, and format validations.
|
406
416
|
|
417
|
+
You can also override <tt>Sequel::Model#default_validation_helpers_options</tt> private method to override these settings on a per-model or even per-instance basis.
|
418
|
+
|
407
419
|
== Custom Validations
|
408
420
|
|
409
421
|
Just as the first validation example showed, you aren't limited to the validation methods defined by +validation_helpers+. Inside the +validate+ method, you can add your own validations by adding to the instance's errors using <tt>errors.add</tt> whenever an attribute is not valid:
|
@@ -442,7 +454,7 @@ Let's say you want to add some default validations that apply to all of your mod
|
|
442
454
|
|
443
455
|
def validate
|
444
456
|
super
|
445
|
-
validates_format(/\A[^\x00-\x08\x0e-\x1f\x7f\x81\x8d\x8f\x90\x9d]*\z
|
457
|
+
validates_format(/\A[^\x00-\x08\x0e-\x1f\x7f\x81\x8d\x8f\x90\x9d]*\z/n,
|
446
458
|
model.string_columns,
|
447
459
|
:message=>"contains invalid characters")
|
448
460
|
end
|
@@ -496,6 +508,17 @@ Here, you don't care about validating the release date if there were validation
|
|
496
508
|
|
497
509
|
album.errors.count # => 1
|
498
510
|
|
499
|
-
==
|
511
|
+
== Other Validation Plugins
|
512
|
+
|
513
|
+
=== +constraint_validations+
|
514
|
+
|
515
|
+
Sequel ships with a +constraint_validations+ plugin and extension, that allows you to setup constraints when creating your database tables, and have Model validations automatically created that mirror those constraints.
|
516
|
+
|
517
|
+
=== +auto_validations+
|
518
|
+
|
519
|
+
Autovalidations uses the not null and type information obtained from parsing the database schema, and the unique index information from parsing the database's index information, and automatically setting up not_null, schema_types, and unique validations. If you don't require customizing validation messages on a per-column basis, it can DRY up a lot of validation code.
|
520
|
+
|
521
|
+
=== +validation_class_methods+
|
522
|
+
|
523
|
+
Sequel ships with the +validation_class_methods+ plugin, which uses class methods instead of instance methods to define validations. It exists mostly for legacy compatibility, but it is still supported.
|
500
524
|
|
501
|
-
Sequel actually ships with two validation plugins. The recommended one that this guide focused on is the +validation_helpers+ plugin. However, Sequel also ships with the +validation_class_methods+ plugin, which uses class methods instead of instance methods to define validations. It exists mostly for legacy compatibility, but it is still supported.
|
data/doc/virtual_rows.rdoc
CHANGED
@@ -9,7 +9,7 @@ many Sequel::Dataset methods that take virtual row blocks.
|
|
9
9
|
|
10
10
|
Virtual Rows were created to work around the issue that some parts of
|
11
11
|
Sequel's standard DSL could not be used on ruby 1.9. For example, the
|
12
|
-
following Sequel code
|
12
|
+
following Sequel code historically worked on ruby 1.8, but not ruby 1.9:
|
13
13
|
|
14
14
|
dataset.where(:a > :b[:c])
|
15
15
|
# WHERE a > b(c)
|
@@ -243,7 +243,7 @@ doesn't look as nice:
|
|
243
243
|
== Returning multiple values
|
244
244
|
|
245
245
|
It's common when using select and order virtual row blocks to want to
|
246
|
-
return multiple values. If you want to do that, you just need to return
|
246
|
+
return multiple values. If you want to do that, you just need to return an
|
247
247
|
array:
|
248
248
|
|
249
249
|
ds.select{|o| [o.column1, o.sum(o.column2).as(o.sum)]}
|
data/lib/sequel/adapters/ado.rb
CHANGED
@@ -8,25 +8,6 @@ module Sequel
|
|
8
8
|
|
9
9
|
set_adapter_scheme :ado
|
10
10
|
|
11
|
-
def initialize(opts)
|
12
|
-
super
|
13
|
-
case @opts[:conn_string]
|
14
|
-
when /Microsoft\.(Jet|ACE)\.OLEDB/io
|
15
|
-
Sequel.ts_require 'adapters/ado/access'
|
16
|
-
extend Sequel::ADO::Access::DatabaseMethods
|
17
|
-
@dataset_class = ADO::Access::Dataset
|
18
|
-
else
|
19
|
-
@opts[:driver] ||= 'SQL Server'
|
20
|
-
case @opts[:driver]
|
21
|
-
when 'SQL Server'
|
22
|
-
Sequel.ts_require 'adapters/ado/mssql'
|
23
|
-
extend Sequel::ADO::MSSQL::DatabaseMethods
|
24
|
-
@dataset_class = ADO::MSSQL::Dataset
|
25
|
-
set_mssql_unicode_strings
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
11
|
# In addition to the usual database options,
|
31
12
|
# the following options have an effect:
|
32
13
|
#
|
@@ -59,6 +40,8 @@ module Sequel
|
|
59
40
|
|
60
41
|
def disconnect_connection(conn)
|
61
42
|
conn.Close
|
43
|
+
rescue WIN32OLERuntimeError
|
44
|
+
nil
|
62
45
|
end
|
63
46
|
|
64
47
|
# Just execute so it doesn't attempt to return the number of rows modified.
|
@@ -98,10 +81,32 @@ module Sequel
|
|
98
81
|
end
|
99
82
|
nil
|
100
83
|
end
|
101
|
-
|
84
|
+
def do(*a, &block)
|
85
|
+
Sequel::Deprecation.deprecate('Database#do', 'Please use Database#execute')
|
86
|
+
execute(*a, &block)
|
87
|
+
end
|
102
88
|
|
103
89
|
private
|
104
90
|
|
91
|
+
def adapter_initialize
|
92
|
+
case @opts[:conn_string]
|
93
|
+
when /Microsoft\.(Jet|ACE)\.OLEDB/io
|
94
|
+
Sequel.require 'adapters/ado/access'
|
95
|
+
extend Sequel::ADO::Access::DatabaseMethods
|
96
|
+
self.dataset_class = ADO::Access::Dataset
|
97
|
+
else
|
98
|
+
@opts[:driver] ||= 'SQL Server'
|
99
|
+
case @opts[:driver]
|
100
|
+
when 'SQL Server'
|
101
|
+
Sequel.require 'adapters/ado/mssql'
|
102
|
+
extend Sequel::ADO::MSSQL::DatabaseMethods
|
103
|
+
self.dataset_class = ADO::MSSQL::Dataset
|
104
|
+
set_mssql_unicode_strings
|
105
|
+
end
|
106
|
+
end
|
107
|
+
super
|
108
|
+
end
|
109
|
+
|
105
110
|
# The ADO adapter's default provider doesn't support transactions, since it
|
106
111
|
# creates a new native connection for each query. So Sequel only attempts
|
107
112
|
# to use transactions if an explicit :provider is given.
|