sequel 2.11.0 → 2.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +168 -0
- data/README.rdoc +77 -95
- data/Rakefile +100 -80
- data/bin/sequel +2 -1
- data/doc/advanced_associations.rdoc +23 -32
- data/doc/cheat_sheet.rdoc +23 -40
- data/doc/dataset_filtering.rdoc +6 -6
- data/doc/prepared_statements.rdoc +22 -22
- data/doc/release_notes/2.12.0.txt +534 -0
- data/doc/schema.rdoc +3 -1
- data/doc/sharding.rdoc +8 -8
- data/doc/virtual_rows.rdoc +65 -0
- data/lib/sequel.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/ado.rb +3 -3
- data/lib/{sequel_core → sequel}/adapters/db2.rb +0 -0
- data/lib/{sequel_core → sequel}/adapters/dbi.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/do.rb +9 -5
- data/lib/{sequel_core → sequel}/adapters/do/mysql.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/do/postgres.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/do/sqlite.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/firebird.rb +84 -80
- data/lib/{sequel_core → sequel}/adapters/informix.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/jdbc.rb +21 -14
- data/lib/{sequel_core → sequel}/adapters/jdbc/h2.rb +14 -13
- data/lib/{sequel_core → sequel}/adapters/jdbc/mysql.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/jdbc/oracle.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/jdbc/postgresql.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/jdbc/sqlite.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/mysql.rb +60 -39
- data/lib/{sequel_core → sequel}/adapters/odbc.rb +8 -4
- data/lib/{sequel_core → sequel}/adapters/openbase.rb +0 -0
- data/lib/{sequel_core → sequel}/adapters/oracle.rb +38 -7
- data/lib/{sequel_core → sequel}/adapters/postgres.rb +24 -24
- data/lib/{sequel_core → sequel}/adapters/shared/mssql.rb +5 -5
- data/lib/{sequel_core → sequel}/adapters/shared/mysql.rb +126 -71
- data/lib/{sequel_core → sequel}/adapters/shared/oracle.rb +7 -10
- data/lib/{sequel_core → sequel}/adapters/shared/postgres.rb +159 -125
- data/lib/{sequel_core → sequel}/adapters/shared/progress.rb +1 -2
- data/lib/{sequel_core → sequel}/adapters/shared/sqlite.rb +72 -67
- data/lib/{sequel_core → sequel}/adapters/sqlite.rb +11 -7
- data/lib/{sequel_core → sequel}/adapters/utils/date_format.rb +0 -0
- data/lib/{sequel_core → sequel}/adapters/utils/stored_procedures.rb +0 -0
- data/lib/{sequel_core → sequel}/adapters/utils/unsupported.rb +19 -0
- data/lib/{sequel_core → sequel}/connection_pool.rb +7 -5
- data/lib/sequel/core.rb +221 -0
- data/lib/{sequel_core → sequel}/core_sql.rb +91 -49
- data/lib/{sequel_core → sequel}/database.rb +264 -149
- data/lib/{sequel_core/schema/generator.rb → sequel/database/schema_generator.rb} +6 -2
- data/lib/{sequel_core/database/schema.rb → sequel/database/schema_methods.rb} +12 -12
- data/lib/sequel/database/schema_sql.rb +224 -0
- data/lib/{sequel_core → sequel}/dataset.rb +78 -236
- data/lib/{sequel_core → sequel}/dataset/convenience.rb +99 -61
- data/lib/{sequel_core/object_graph.rb → sequel/dataset/graph.rb} +16 -14
- data/lib/{sequel_core → sequel}/dataset/prepared_statements.rb +1 -1
- data/lib/{sequel_core → sequel}/dataset/sql.rb +150 -99
- data/lib/sequel/deprecated.rb +593 -0
- data/lib/sequel/deprecated_migration.rb +91 -0
- data/lib/sequel/exceptions.rb +48 -0
- data/lib/sequel/extensions/blank.rb +42 -0
- data/lib/{sequel_model → sequel/extensions}/inflector.rb +8 -1
- data/lib/{sequel_core → sequel/extensions}/migration.rb +1 -1
- data/lib/{sequel_core/dataset → sequel/extensions}/pagination.rb +0 -0
- data/lib/{sequel_core → sequel/extensions}/pretty_table.rb +7 -0
- data/lib/{sequel_core/dataset → sequel/extensions}/query.rb +7 -0
- data/lib/sequel/extensions/string_date_time.rb +47 -0
- data/lib/sequel/metaprogramming.rb +43 -0
- data/lib/sequel/model.rb +110 -0
- data/lib/sequel/model/associations.rb +1300 -0
- data/lib/sequel/model/base.rb +937 -0
- data/lib/sequel/model/deprecated.rb +204 -0
- data/lib/sequel/model/deprecated_hooks.rb +103 -0
- data/lib/sequel/model/deprecated_inflector.rb +335 -0
- data/lib/sequel/model/deprecated_validations.rb +388 -0
- data/lib/sequel/model/errors.rb +39 -0
- data/lib/{sequel_model → sequel/model}/exceptions.rb +4 -4
- data/lib/sequel/model/inflections.rb +208 -0
- data/lib/sequel/model/plugins.rb +76 -0
- data/lib/sequel/plugins/caching.rb +122 -0
- data/lib/sequel/plugins/hook_class_methods.rb +122 -0
- data/lib/sequel/plugins/schema.rb +53 -0
- data/lib/sequel/plugins/serialization.rb +117 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +63 -0
- data/lib/sequel/plugins/validation_class_methods.rb +384 -0
- data/lib/sequel/plugins/validation_helpers.rb +150 -0
- data/lib/{sequel_core → sequel}/sql.rb +125 -190
- data/lib/{sequel_core → sequel}/version.rb +2 -1
- data/lib/sequel_core.rb +1 -172
- data/lib/sequel_model.rb +1 -91
- data/spec/adapters/firebird_spec.rb +5 -5
- data/spec/adapters/informix_spec.rb +1 -1
- data/spec/adapters/mysql_spec.rb +128 -42
- data/spec/adapters/oracle_spec.rb +47 -19
- data/spec/adapters/postgres_spec.rb +64 -52
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +12 -17
- data/spec/{sequel_core → core}/connection_pool_spec.rb +10 -10
- data/spec/{sequel_core → core}/core_ext_spec.rb +19 -19
- data/spec/{sequel_core → core}/core_sql_spec.rb +68 -71
- data/spec/{sequel_core → core}/database_spec.rb +135 -99
- data/spec/{sequel_core → core}/dataset_spec.rb +398 -242
- data/spec/{sequel_core → core}/expression_filters_spec.rb +13 -13
- data/spec/core/migration_spec.rb +263 -0
- data/spec/{sequel_core → core}/object_graph_spec.rb +10 -10
- data/spec/{sequel_core → core}/pretty_table_spec.rb +2 -2
- data/spec/{sequel_core → core}/schema_generator_spec.rb +0 -0
- data/spec/{sequel_core → core}/schema_spec.rb +8 -10
- data/spec/{sequel_core → core}/spec_helper.rb +29 -2
- data/spec/{sequel_core → core}/version_spec.rb +0 -0
- data/spec/extensions/blank_spec.rb +67 -0
- data/spec/extensions/caching_spec.rb +201 -0
- data/spec/{sequel_model/hooks_spec.rb → extensions/hook_class_methods_spec.rb} +8 -23
- data/spec/{sequel_model → extensions}/inflector_spec.rb +3 -0
- data/spec/{sequel_core → extensions}/migration_spec.rb +4 -4
- data/spec/extensions/pagination_spec.rb +99 -0
- data/spec/extensions/pretty_table_spec.rb +91 -0
- data/spec/extensions/query_spec.rb +85 -0
- data/spec/{sequel_model → extensions}/schema_spec.rb +22 -1
- data/spec/extensions/serialization_spec.rb +109 -0
- data/spec/extensions/single_table_inheritance_spec.rb +53 -0
- data/spec/{sequel_model → extensions}/spec_helper.rb +13 -4
- data/spec/extensions/string_date_time_spec.rb +93 -0
- data/spec/{sequel_model/validations_spec.rb → extensions/validation_class_methods_spec.rb} +15 -103
- data/spec/extensions/validation_helpers_spec.rb +291 -0
- data/spec/integration/dataset_test.rb +31 -0
- data/spec/integration/eager_loader_test.rb +17 -30
- data/spec/integration/schema_test.rb +8 -5
- data/spec/integration/spec_helper.rb +17 -0
- data/spec/integration/transaction_test.rb +68 -0
- data/spec/{sequel_model → model}/association_reflection_spec.rb +0 -0
- data/spec/{sequel_model → model}/associations_spec.rb +23 -10
- data/spec/{sequel_model → model}/base_spec.rb +29 -20
- data/spec/{sequel_model → model}/caching_spec.rb +16 -14
- data/spec/{sequel_model → model}/dataset_methods_spec.rb +0 -0
- data/spec/{sequel_model → model}/eager_loading_spec.rb +8 -8
- data/spec/model/hooks_spec.rb +472 -0
- data/spec/model/inflector_spec.rb +126 -0
- data/spec/{sequel_model → model}/model_spec.rb +25 -20
- data/spec/model/plugins_spec.rb +142 -0
- data/spec/{sequel_model → model}/record_spec.rb +121 -62
- data/spec/model/schema_spec.rb +92 -0
- data/spec/model/spec_helper.rb +124 -0
- data/spec/model/validations_spec.rb +1080 -0
- metadata +136 -107
- data/lib/sequel_core/core_ext.rb +0 -217
- data/lib/sequel_core/dataset/callback.rb +0 -13
- data/lib/sequel_core/dataset/schema.rb +0 -15
- data/lib/sequel_core/deprecated.rb +0 -26
- data/lib/sequel_core/exceptions.rb +0 -44
- data/lib/sequel_core/schema.rb +0 -2
- data/lib/sequel_core/schema/sql.rb +0 -325
- data/lib/sequel_model/association_reflection.rb +0 -267
- data/lib/sequel_model/associations.rb +0 -499
- data/lib/sequel_model/base.rb +0 -539
- data/lib/sequel_model/caching.rb +0 -82
- data/lib/sequel_model/dataset_methods.rb +0 -26
- data/lib/sequel_model/eager_loading.rb +0 -370
- data/lib/sequel_model/hooks.rb +0 -101
- data/lib/sequel_model/plugins.rb +0 -62
- data/lib/sequel_model/record.rb +0 -568
- data/lib/sequel_model/schema.rb +0 -49
- data/lib/sequel_model/validations.rb +0 -429
- data/spec/sequel_model/plugins_spec.rb +0 -80
data/doc/schema.rdoc
CHANGED
@@ -8,7 +8,7 @@ The format of the individual migration files themselves is explained in the Sequ
|
|
8
8
|
|
9
9
|
Migrations are not required, you can just call the schema modification methods directly on the database object. This is often done in test code and examples. However, it is recommended that you use the migration framework unless the database schema will not be changing in the future, as it provides a way to easily handle modifications to existing database schema.
|
10
10
|
|
11
|
-
|
11
|
+
Sequel has the ability to have database independent migrations using ruby classes as types. When you use a ruby class as a type, Sequel translates it to the most comparable type in the database you are using. Here's an example using all supported types:
|
12
12
|
|
13
13
|
DB.create_table(:cats) do
|
14
14
|
primary_key :id, :type=>Integer # integer
|
@@ -27,3 +27,5 @@ Also, new in Sequel 2.10 is the ability to have database independent migrations
|
|
27
27
|
end
|
28
28
|
|
29
29
|
Basically, if you use one of the ruby classes above, it will translate into a database specific type. If you use a lowercase method, symbol, or string to specify the type, Sequel won't attempt to translate it.
|
30
|
+
|
31
|
+
Note that if you use a ruby class, you shouldn't use a :size option. Using a ruby class means that you want Sequel to pick the database type to use. If you want to specify the size, you are no longer in database independent territory, and you need to specify the type as well, using a lowercase method, symbol, or string.
|
data/doc/sharding.rdoc
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
= Read-Only Slaves/Writable Master and Database Sharding
|
2
2
|
|
3
|
-
|
3
|
+
Sequel has support for read only slave databases
|
4
4
|
with a writable master database, as well as database sharding (where you can
|
5
|
-
pick a
|
5
|
+
pick a server to use for a given dataset). Support for both
|
6
6
|
features is database independent, and should work for all database adapters
|
7
7
|
included with Sequel.
|
8
8
|
|
9
9
|
== The :servers Database option
|
10
10
|
|
11
|
-
Both features use the
|
11
|
+
Both features use the :servers Database option. The :servers option should
|
12
12
|
be a hash with symbol keys and values that are either hashes or procs that
|
13
|
-
return hashes. Note that all servers should have the same schema
|
14
|
-
really know what you are doing.
|
13
|
+
return hashes. Note that all servers should have the same schema for all
|
14
|
+
tables you are accessing, unless you really know what you are doing.
|
15
15
|
|
16
16
|
== Master and Slave Database Configurations
|
17
17
|
|
@@ -23,7 +23,7 @@ is the simplest configuration:
|
|
23
23
|
DB=Sequel.connect('postgres://master_server/database', \
|
24
24
|
:servers=>{:read_only=>{:host=>'slave_server'}})
|
25
25
|
|
26
|
-
This will use the
|
26
|
+
This will use the slave_server for SELECT queries and master_server for
|
27
27
|
other queries.
|
28
28
|
|
29
29
|
=== Multiple Read-Only Slaves, Single Master
|
@@ -67,7 +67,7 @@ There is specific support in Sequel for handling master/slave database
|
|
67
67
|
combinations, with the only necessary setup being the database configuration.
|
68
68
|
However, since sharding is always going to be implementation dependent, Sequel
|
69
69
|
supplies the basic infrastructure, but you have to tell it which server to use
|
70
|
-
for each dataset. Let's assume
|
70
|
+
for each dataset. Let's assume a simple scenario, a distributed rainbow
|
71
71
|
table for SHA-1 hashes, sharding based on the first hex character (for a total
|
72
72
|
of 16 shards). First, you need to configure the database:
|
73
73
|
|
@@ -89,7 +89,7 @@ since it considers the default server and shard servers independent. Note that
|
|
89
89
|
if you always set the shard on a dataset before using it in queries, it will
|
90
90
|
not attempt to connect to the default server. Sequel may use the default
|
91
91
|
server in queries it generates itself, such as to get column names or table
|
92
|
-
schemas, so
|
92
|
+
schemas, so you should always have a default server that works.
|
93
93
|
|
94
94
|
To set the shard for a given query, you use the Dataset#server method:
|
95
95
|
|
@@ -0,0 +1,65 @@
|
|
1
|
+
= Virtual Row Blocks
|
2
|
+
|
3
|
+
Dataset methods filter, order, and select all take blocks that yield
|
4
|
+
instances of Sequel::SQL::VirtualRow. These are referred to as
|
5
|
+
virtual row blocks. Many other dataset methods pass the blocks
|
6
|
+
they are given into one of those three methods, so there are actually
|
7
|
+
many Sequel methods that take virtual row blocks.
|
8
|
+
|
9
|
+
VirtualRow is a class that returns SQL::Indentifiers,
|
10
|
+
SQL::QualifiedIdentifiers, or SQL::Functions depending on how it is
|
11
|
+
called. This is best shown by example:
|
12
|
+
|
13
|
+
ds = DB[:items]
|
14
|
+
ds.filter{|o| o.column > 1} # column > 1
|
15
|
+
ds.filter{|o| o.table__column > 1} # table.column > 1
|
16
|
+
ds.filter{|o| o.function(1) > 1} # function(1) > 1
|
17
|
+
|
18
|
+
Basically, the rules are:
|
19
|
+
|
20
|
+
* If there are arguments, an SQL::Function is returned with the
|
21
|
+
name of the method used and the arguments given.
|
22
|
+
|
23
|
+
* If there are no arguments and the method contains a double
|
24
|
+
underscore, split on the double underscore and return an
|
25
|
+
SQL::QualifiedIdentifier with the table and column.
|
26
|
+
|
27
|
+
* Otherwise, create an SQL::Identifier with the name of the
|
28
|
+
method.
|
29
|
+
|
30
|
+
One of the consequences of these rules is that you cannot
|
31
|
+
create an SQL::Function that takes no arguments using a VirtualRow
|
32
|
+
instance.
|
33
|
+
|
34
|
+
In Sequel 2.12, the following is deprecated by default, as
|
35
|
+
virtual row blocks are required to accept an argument:
|
36
|
+
|
37
|
+
ds.filter{:column > 1} # column > 1
|
38
|
+
ds.filter{:table__column > 1} # table.column > 1
|
39
|
+
ds.filter{:function.sql_function(1) > 1} # function(1) > 1
|
40
|
+
|
41
|
+
This is to keep backwards compatibility while notifying people
|
42
|
+
to change their code. In Sequel 3.0, you will be able to
|
43
|
+
do:
|
44
|
+
|
45
|
+
ds.filter{column > 1} # column > 1
|
46
|
+
ds.filter{table__column > 1} # table.column > 1
|
47
|
+
ds.filter{function(1) > 1} # function(1) > 1
|
48
|
+
|
49
|
+
Sequel 3.0 will change the virtual row block support to use
|
50
|
+
instance_eval if the block doesn't take an argument. This
|
51
|
+
breaks backward compatibility because instance methods called
|
52
|
+
inside the block will now have a virtual row instance as a
|
53
|
+
receiver instead of the receiver where the block was defined.
|
54
|
+
You can still use local variables in the enclosing scope
|
55
|
+
inside the block, as they take on their usual meaning.
|
56
|
+
|
57
|
+
If you find yourself needing to call instance methods for the
|
58
|
+
current receiver inside a virtual row block, you should change
|
59
|
+
the block to accept an argument, and use that argument whenever
|
60
|
+
you need the virtual row support.
|
61
|
+
|
62
|
+
You can get the Sequel 3.0 behavior in Sequel 2.12 using the
|
63
|
+
following method:
|
64
|
+
|
65
|
+
Sequel.virtual_row_instance_eval = true
|
data/lib/sequel.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require '
|
1
|
+
require 'sequel/model'
|
@@ -1,11 +1,11 @@
|
|
1
|
-
require '
|
1
|
+
Sequel.require 'adapters/utils/date_format'
|
2
2
|
require 'win32ole'
|
3
3
|
|
4
4
|
module Sequel
|
5
5
|
# The ADO adapter provides connectivity to ADO databases in Windows. ADO
|
6
6
|
# databases can be opened using a URL with the ado schema:
|
7
7
|
#
|
8
|
-
# DB = Sequel.
|
8
|
+
# DB = Sequel.connect('ado://mydb')
|
9
9
|
#
|
10
10
|
# or using the Sequel.ado method:
|
11
11
|
#
|
@@ -20,7 +20,7 @@ module Sequel
|
|
20
20
|
opts[:driver] ||= 'SQL Server'
|
21
21
|
case opts[:driver]
|
22
22
|
when 'SQL Server'
|
23
|
-
require '
|
23
|
+
Sequel.require 'adapters/shared/mssql'
|
24
24
|
extend Sequel::MSSQL::DatabaseMethods
|
25
25
|
end
|
26
26
|
end
|
File without changes
|
@@ -44,7 +44,7 @@ module Sequel
|
|
44
44
|
dbname = opts[:database]
|
45
45
|
if dbname !~ /^DBI:/ then
|
46
46
|
dbname = "DBI:#{dbname}"
|
47
|
-
[:host, :port].each{|sym| dbname += ";#{sym}=#{opts[sym]}" unless opts[sym]
|
47
|
+
[:host, :port].each{|sym| dbname += ";#{sym}=#{opts[sym]}" unless blank_object?(opts[sym])}
|
48
48
|
end
|
49
49
|
::DBI.connect(dbname, opts[:user], opts[:password])
|
50
50
|
end
|
@@ -15,19 +15,19 @@ module Sequel
|
|
15
15
|
# given database object so it supports the correct database type.
|
16
16
|
DATABASE_SETUP = {:postgres=>proc do |db|
|
17
17
|
require 'do_postgres'
|
18
|
-
require '
|
18
|
+
Sequel.require 'adapters/do/postgres'
|
19
19
|
db.converted_exceptions << PostgresError
|
20
20
|
db.extend(Sequel::DataObjects::Postgres::DatabaseMethods)
|
21
21
|
end,
|
22
22
|
:mysql=>proc do |db|
|
23
23
|
require 'do_mysql'
|
24
|
-
require '
|
24
|
+
Sequel.require 'adapters/do/mysql'
|
25
25
|
db.converted_exceptions << MysqlError
|
26
26
|
db.extend(Sequel::DataObjects::MySQL::DatabaseMethods)
|
27
27
|
end,
|
28
28
|
:sqlite3=>proc do |db|
|
29
29
|
require 'do_sqlite3'
|
30
|
-
require '
|
30
|
+
Sequel.require 'adapters/do/sqlite'
|
31
31
|
db.converted_exceptions << Sqlite3Error
|
32
32
|
db.extend(Sequel::DataObjects::SQLite::DatabaseMethods)
|
33
33
|
end
|
@@ -120,9 +120,13 @@ module Sequel
|
|
120
120
|
# only supports single level transactions, and it always prepares
|
121
121
|
# transactions and commits them immediately after. It's wasteful,
|
122
122
|
# but required by DataObject's API.
|
123
|
-
def transaction(
|
123
|
+
def transaction(opts={})
|
124
|
+
unless opts.is_a?(Hash)
|
125
|
+
Deprecation.deprecate('Passing an argument other than a Hash to Database#transaction', "Use DB.transaction(:server=>#{opts.inspect})")
|
126
|
+
opts = {:server=>opts}
|
127
|
+
end
|
124
128
|
th = Thread.current
|
125
|
-
synchronize(server) do |conn|
|
129
|
+
synchronize(opts[:server]) do |conn|
|
126
130
|
return yield(conn) if @transactions.include?(th)
|
127
131
|
t = ::DataObjects::Transaction.create_for_uri(uri)
|
128
132
|
t.instance_variable_get(:@connection).close
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'fb'
|
2
|
-
require '
|
2
|
+
Sequel.require 'adapters/utils/unsupported'
|
3
3
|
|
4
4
|
module Sequel
|
5
5
|
# The Sequel Firebird adapter requires the ruby fb driver located at
|
@@ -18,26 +18,6 @@ module Sequel
|
|
18
18
|
@primary_key_sequences = {}
|
19
19
|
end
|
20
20
|
|
21
|
-
# Use Firebird specific syntax for add column
|
22
|
-
def alter_table_sql(table, op)
|
23
|
-
case op[:op]
|
24
|
-
when :add_column
|
25
|
-
"ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op)}"
|
26
|
-
when :drop_column
|
27
|
-
"ALTER TABLE #{quote_schema_table(table)} DROP #{column_definition_sql(op)}"
|
28
|
-
when :rename_column
|
29
|
-
"ALTER TABLE #{quote_schema_table(table)} ALTER #{quote_identifier(op[:name])} TO #{quote_identifier(op[:new_name])}"
|
30
|
-
when :set_column_type
|
31
|
-
"ALTER TABLE #{quote_schema_table(table)} ALTER #{quote_identifier(op[:name])} TYPE #{type_literal(op)}"
|
32
|
-
else
|
33
|
-
super(table, op)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def auto_increment_sql()
|
38
|
-
AUTO_INCREMENT
|
39
|
-
end
|
40
|
-
|
41
21
|
def connect(server)
|
42
22
|
opts = server_opts(server)
|
43
23
|
|
@@ -50,10 +30,6 @@ module Sequel
|
|
50
30
|
conn
|
51
31
|
end
|
52
32
|
|
53
|
-
def create_sequence_sql(name, opts={})
|
54
|
-
"CREATE SEQUENCE #{quote_identifier(name)}"
|
55
|
-
end
|
56
|
-
|
57
33
|
# Creates a table with the columns given in the provided block:
|
58
34
|
#
|
59
35
|
# DB.create_table :posts do
|
@@ -77,52 +53,10 @@ module Sequel
|
|
77
53
|
statements[0].flatten.each {|sql| execute_ddl(sql)}
|
78
54
|
end
|
79
55
|
|
80
|
-
def create_table_sql_list(name, columns, indexes = nil, options={})
|
81
|
-
statements = super
|
82
|
-
drop_seq_statement = nil
|
83
|
-
columns.each do |c|
|
84
|
-
if c[:auto_increment]
|
85
|
-
c[:sequence_name] ||= "seq_#{name}_#{c[:name]}"
|
86
|
-
unless c[:create_sequence] == false
|
87
|
-
drop_seq_statement = drop_sequence_sql(c[:sequence_name])
|
88
|
-
statements << create_sequence_sql(c[:sequence_name])
|
89
|
-
statements << restart_sequence_sql(c[:sequence_name], {:restart_position => c[:sequence_start_position]}) if c[:sequence_start_position]
|
90
|
-
end
|
91
|
-
unless c[:create_trigger] == false
|
92
|
-
c[:trigger_name] ||= "BI_#{name}_#{c[:name]}"
|
93
|
-
c[:quoted_name] = quote_identifier(c[:name])
|
94
|
-
trigger_definition = <<-END
|
95
|
-
begin
|
96
|
-
if ((new.#{c[:quoted_name]} is null) or (new.#{c[:quoted_name]} = 0)) then
|
97
|
-
begin
|
98
|
-
new.#{c[:quoted_name]} = next value for #{c[:sequence_name]};
|
99
|
-
end
|
100
|
-
end
|
101
|
-
END
|
102
|
-
statements << create_trigger_sql(name, c[:trigger_name], trigger_definition, {:events => [:insert]})
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
[statements, drop_seq_statement]
|
107
|
-
end
|
108
|
-
|
109
56
|
def create_trigger(*args)
|
110
57
|
self << create_trigger_sql(*args)
|
111
58
|
end
|
112
59
|
|
113
|
-
def create_trigger_sql(table, name, definition, opts={})
|
114
|
-
events = opts[:events] ? Array(opts[:events]) : [:insert, :update, :delete]
|
115
|
-
whence = opts[:after] ? 'AFTER' : 'BEFORE'
|
116
|
-
inactive = opts[:inactive] ? 'INACTIVE' : 'ACTIVE'
|
117
|
-
position = opts[:position] ? opts[:position] : 0
|
118
|
-
sql = <<-end_sql
|
119
|
-
CREATE TRIGGER #{quote_identifier(name)} for #{quote_identifier(table)}
|
120
|
-
#{inactive} #{whence} #{events.map{|e| e.to_s.upcase}.join(' OR ')} position #{position}
|
121
|
-
as #{definition}
|
122
|
-
end_sql
|
123
|
-
sql
|
124
|
-
end
|
125
|
-
|
126
60
|
def dataset(opts = nil)
|
127
61
|
Firebird::Dataset.new(self, opts)
|
128
62
|
end
|
@@ -131,10 +65,6 @@ module Sequel
|
|
131
65
|
self << drop_sequence_sql(name)
|
132
66
|
end
|
133
67
|
|
134
|
-
def drop_sequence_sql(name)
|
135
|
-
"DROP SEQUENCE #{quote_identifier(name)}"
|
136
|
-
end
|
137
|
-
|
138
68
|
def execute(sql, opts={})
|
139
69
|
log_info(sql)
|
140
70
|
begin
|
@@ -165,11 +95,6 @@ module Sequel
|
|
165
95
|
self << restart_sequence_sql(*args)
|
166
96
|
end
|
167
97
|
|
168
|
-
def restart_sequence_sql(name, opts={})
|
169
|
-
seq_name = quote_identifier(name)
|
170
|
-
"ALTER SEQUENCE #{seq_name} RESTART WITH #{opts[:restart_position]}"
|
171
|
-
end
|
172
|
-
|
173
98
|
def sequences(opts={})
|
174
99
|
ds = self[:"rdb$generators"].server(opts[:server]).filter(:"rdb$system_flag" => 0).select(:"rdb$generator_name")
|
175
100
|
block_given? ? yield(ds) : ds.map{|r| ds.send(:output_identifier, r[:"rdb$generator_name"])}
|
@@ -180,8 +105,12 @@ module Sequel
|
|
180
105
|
block_given? ? yield(ds) : ds.map{|r| ds.send(:output_identifier, r[:"rdb$relation_name"])}
|
181
106
|
end
|
182
107
|
|
183
|
-
def transaction(
|
184
|
-
|
108
|
+
def transaction(opts={})
|
109
|
+
unless opts.is_a?(Hash)
|
110
|
+
Deprecation.deprecate('Passing an argument other than a Hash to Database#transaction', "Use DB.transaction(:server=>#{opts.inspect})")
|
111
|
+
opts = {:server=>opts}
|
112
|
+
end
|
113
|
+
synchronize(opts[:server]) do |conn|
|
185
114
|
return yield(conn) if @transactions.include?(Thread.current)
|
186
115
|
log_info("Transaction.begin")
|
187
116
|
conn.transaction
|
@@ -204,9 +133,84 @@ module Sequel
|
|
204
133
|
|
205
134
|
private
|
206
135
|
|
136
|
+
# Use Firebird specific syntax for add column
|
137
|
+
def alter_table_sql(table, op)
|
138
|
+
case op[:op]
|
139
|
+
when :add_column
|
140
|
+
"ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op)}"
|
141
|
+
when :drop_column
|
142
|
+
"ALTER TABLE #{quote_schema_table(table)} DROP #{column_definition_sql(op)}"
|
143
|
+
when :rename_column
|
144
|
+
"ALTER TABLE #{quote_schema_table(table)} ALTER #{quote_identifier(op[:name])} TO #{quote_identifier(op[:new_name])}"
|
145
|
+
when :set_column_type
|
146
|
+
"ALTER TABLE #{quote_schema_table(table)} ALTER #{quote_identifier(op[:name])} TYPE #{type_literal(op)}"
|
147
|
+
else
|
148
|
+
super(table, op)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def auto_increment_sql()
|
153
|
+
AUTO_INCREMENT
|
154
|
+
end
|
155
|
+
|
156
|
+
def create_sequence_sql(name, opts={})
|
157
|
+
"CREATE SEQUENCE #{quote_identifier(name)}"
|
158
|
+
end
|
159
|
+
|
160
|
+
def create_table_sql_list(name, columns, indexes = nil, options={})
|
161
|
+
statements = super
|
162
|
+
drop_seq_statement = nil
|
163
|
+
columns.each do |c|
|
164
|
+
if c[:auto_increment]
|
165
|
+
c[:sequence_name] ||= "seq_#{name}_#{c[:name]}"
|
166
|
+
unless c[:create_sequence] == false
|
167
|
+
drop_seq_statement = drop_sequence_sql(c[:sequence_name])
|
168
|
+
statements << create_sequence_sql(c[:sequence_name])
|
169
|
+
statements << restart_sequence_sql(c[:sequence_name], {:restart_position => c[:sequence_start_position]}) if c[:sequence_start_position]
|
170
|
+
end
|
171
|
+
unless c[:create_trigger] == false
|
172
|
+
c[:trigger_name] ||= "BI_#{name}_#{c[:name]}"
|
173
|
+
c[:quoted_name] = quote_identifier(c[:name])
|
174
|
+
trigger_definition = <<-END
|
175
|
+
begin
|
176
|
+
if ((new.#{c[:quoted_name]} is null) or (new.#{c[:quoted_name]} = 0)) then
|
177
|
+
begin
|
178
|
+
new.#{c[:quoted_name]} = next value for #{c[:sequence_name]};
|
179
|
+
end
|
180
|
+
end
|
181
|
+
END
|
182
|
+
statements << create_trigger_sql(name, c[:trigger_name], trigger_definition, {:events => [:insert]})
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
[statements, drop_seq_statement]
|
187
|
+
end
|
188
|
+
|
189
|
+
def create_trigger_sql(table, name, definition, opts={})
|
190
|
+
events = opts[:events] ? Array(opts[:events]) : [:insert, :update, :delete]
|
191
|
+
whence = opts[:after] ? 'AFTER' : 'BEFORE'
|
192
|
+
inactive = opts[:inactive] ? 'INACTIVE' : 'ACTIVE'
|
193
|
+
position = opts[:position] ? opts[:position] : 0
|
194
|
+
sql = <<-end_sql
|
195
|
+
CREATE TRIGGER #{quote_identifier(name)} for #{quote_identifier(table)}
|
196
|
+
#{inactive} #{whence} #{events.map{|e| e.to_s.upcase}.join(' OR ')} position #{position}
|
197
|
+
as #{definition}
|
198
|
+
end_sql
|
199
|
+
sql
|
200
|
+
end
|
201
|
+
|
207
202
|
def disconnect_connection(c)
|
208
203
|
c.close
|
209
204
|
end
|
205
|
+
|
206
|
+
def drop_sequence_sql(name)
|
207
|
+
"DROP SEQUENCE #{quote_identifier(name)}"
|
208
|
+
end
|
209
|
+
|
210
|
+
def restart_sequence_sql(name, opts={})
|
211
|
+
seq_name = quote_identifier(name)
|
212
|
+
"ALTER SEQUENCE #{seq_name} RESTART WITH #{opts[:restart_position]}"
|
213
|
+
end
|
210
214
|
end
|
211
215
|
|
212
216
|
# Dataset class for Firebird datasets
|
@@ -241,7 +245,7 @@ module Sequel
|
|
241
245
|
# Insert given values into the database.
|
242
246
|
def insert(*values)
|
243
247
|
if !@opts[:sql]
|
244
|
-
|
248
|
+
clone(default_server_opts(:sql=>insert_returning_pk_sql(*values))).single_value
|
245
249
|
else
|
246
250
|
execute_insert(insert_sql(*values), :table=>opts[:from].first,
|
247
251
|
:values=>values.size == 1 ? values.first : values)
|
@@ -261,7 +265,7 @@ module Sequel
|
|
261
265
|
|
262
266
|
# Insert a record returning the record inserted
|
263
267
|
def insert_select(*values)
|
264
|
-
|
268
|
+
naked.clone(default_server_opts(:sql=>insert_returning_sql(nil, *values))).single_record
|
265
269
|
end
|
266
270
|
|
267
271
|
# The order of clauses in the SELECT SQL statement
|