sequel 2.11.0 → 2.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. data/CHANGELOG +168 -0
  2. data/README.rdoc +77 -95
  3. data/Rakefile +100 -80
  4. data/bin/sequel +2 -1
  5. data/doc/advanced_associations.rdoc +23 -32
  6. data/doc/cheat_sheet.rdoc +23 -40
  7. data/doc/dataset_filtering.rdoc +6 -6
  8. data/doc/prepared_statements.rdoc +22 -22
  9. data/doc/release_notes/2.12.0.txt +534 -0
  10. data/doc/schema.rdoc +3 -1
  11. data/doc/sharding.rdoc +8 -8
  12. data/doc/virtual_rows.rdoc +65 -0
  13. data/lib/sequel.rb +1 -1
  14. data/lib/{sequel_core → sequel}/adapters/ado.rb +3 -3
  15. data/lib/{sequel_core → sequel}/adapters/db2.rb +0 -0
  16. data/lib/{sequel_core → sequel}/adapters/dbi.rb +1 -1
  17. data/lib/{sequel_core → sequel}/adapters/do.rb +9 -5
  18. data/lib/{sequel_core → sequel}/adapters/do/mysql.rb +1 -1
  19. data/lib/{sequel_core → sequel}/adapters/do/postgres.rb +1 -1
  20. data/lib/{sequel_core → sequel}/adapters/do/sqlite.rb +1 -1
  21. data/lib/{sequel_core → sequel}/adapters/firebird.rb +84 -80
  22. data/lib/{sequel_core → sequel}/adapters/informix.rb +1 -1
  23. data/lib/{sequel_core → sequel}/adapters/jdbc.rb +21 -14
  24. data/lib/{sequel_core → sequel}/adapters/jdbc/h2.rb +14 -13
  25. data/lib/{sequel_core → sequel}/adapters/jdbc/mysql.rb +1 -1
  26. data/lib/{sequel_core → sequel}/adapters/jdbc/oracle.rb +1 -1
  27. data/lib/{sequel_core → sequel}/adapters/jdbc/postgresql.rb +1 -1
  28. data/lib/{sequel_core → sequel}/adapters/jdbc/sqlite.rb +1 -1
  29. data/lib/{sequel_core → sequel}/adapters/mysql.rb +60 -39
  30. data/lib/{sequel_core → sequel}/adapters/odbc.rb +8 -4
  31. data/lib/{sequel_core → sequel}/adapters/openbase.rb +0 -0
  32. data/lib/{sequel_core → sequel}/adapters/oracle.rb +38 -7
  33. data/lib/{sequel_core → sequel}/adapters/postgres.rb +24 -24
  34. data/lib/{sequel_core → sequel}/adapters/shared/mssql.rb +5 -5
  35. data/lib/{sequel_core → sequel}/adapters/shared/mysql.rb +126 -71
  36. data/lib/{sequel_core → sequel}/adapters/shared/oracle.rb +7 -10
  37. data/lib/{sequel_core → sequel}/adapters/shared/postgres.rb +159 -125
  38. data/lib/{sequel_core → sequel}/adapters/shared/progress.rb +1 -2
  39. data/lib/{sequel_core → sequel}/adapters/shared/sqlite.rb +72 -67
  40. data/lib/{sequel_core → sequel}/adapters/sqlite.rb +11 -7
  41. data/lib/{sequel_core → sequel}/adapters/utils/date_format.rb +0 -0
  42. data/lib/{sequel_core → sequel}/adapters/utils/stored_procedures.rb +0 -0
  43. data/lib/{sequel_core → sequel}/adapters/utils/unsupported.rb +19 -0
  44. data/lib/{sequel_core → sequel}/connection_pool.rb +7 -5
  45. data/lib/sequel/core.rb +221 -0
  46. data/lib/{sequel_core → sequel}/core_sql.rb +91 -49
  47. data/lib/{sequel_core → sequel}/database.rb +264 -149
  48. data/lib/{sequel_core/schema/generator.rb → sequel/database/schema_generator.rb} +6 -2
  49. data/lib/{sequel_core/database/schema.rb → sequel/database/schema_methods.rb} +12 -12
  50. data/lib/sequel/database/schema_sql.rb +224 -0
  51. data/lib/{sequel_core → sequel}/dataset.rb +78 -236
  52. data/lib/{sequel_core → sequel}/dataset/convenience.rb +99 -61
  53. data/lib/{sequel_core/object_graph.rb → sequel/dataset/graph.rb} +16 -14
  54. data/lib/{sequel_core → sequel}/dataset/prepared_statements.rb +1 -1
  55. data/lib/{sequel_core → sequel}/dataset/sql.rb +150 -99
  56. data/lib/sequel/deprecated.rb +593 -0
  57. data/lib/sequel/deprecated_migration.rb +91 -0
  58. data/lib/sequel/exceptions.rb +48 -0
  59. data/lib/sequel/extensions/blank.rb +42 -0
  60. data/lib/{sequel_model → sequel/extensions}/inflector.rb +8 -1
  61. data/lib/{sequel_core → sequel/extensions}/migration.rb +1 -1
  62. data/lib/{sequel_core/dataset → sequel/extensions}/pagination.rb +0 -0
  63. data/lib/{sequel_core → sequel/extensions}/pretty_table.rb +7 -0
  64. data/lib/{sequel_core/dataset → sequel/extensions}/query.rb +7 -0
  65. data/lib/sequel/extensions/string_date_time.rb +47 -0
  66. data/lib/sequel/metaprogramming.rb +43 -0
  67. data/lib/sequel/model.rb +110 -0
  68. data/lib/sequel/model/associations.rb +1300 -0
  69. data/lib/sequel/model/base.rb +937 -0
  70. data/lib/sequel/model/deprecated.rb +204 -0
  71. data/lib/sequel/model/deprecated_hooks.rb +103 -0
  72. data/lib/sequel/model/deprecated_inflector.rb +335 -0
  73. data/lib/sequel/model/deprecated_validations.rb +388 -0
  74. data/lib/sequel/model/errors.rb +39 -0
  75. data/lib/{sequel_model → sequel/model}/exceptions.rb +4 -4
  76. data/lib/sequel/model/inflections.rb +208 -0
  77. data/lib/sequel/model/plugins.rb +76 -0
  78. data/lib/sequel/plugins/caching.rb +122 -0
  79. data/lib/sequel/plugins/hook_class_methods.rb +122 -0
  80. data/lib/sequel/plugins/schema.rb +53 -0
  81. data/lib/sequel/plugins/serialization.rb +117 -0
  82. data/lib/sequel/plugins/single_table_inheritance.rb +63 -0
  83. data/lib/sequel/plugins/validation_class_methods.rb +384 -0
  84. data/lib/sequel/plugins/validation_helpers.rb +150 -0
  85. data/lib/{sequel_core → sequel}/sql.rb +125 -190
  86. data/lib/{sequel_core → sequel}/version.rb +2 -1
  87. data/lib/sequel_core.rb +1 -172
  88. data/lib/sequel_model.rb +1 -91
  89. data/spec/adapters/firebird_spec.rb +5 -5
  90. data/spec/adapters/informix_spec.rb +1 -1
  91. data/spec/adapters/mysql_spec.rb +128 -42
  92. data/spec/adapters/oracle_spec.rb +47 -19
  93. data/spec/adapters/postgres_spec.rb +64 -52
  94. data/spec/adapters/spec_helper.rb +1 -1
  95. data/spec/adapters/sqlite_spec.rb +12 -17
  96. data/spec/{sequel_core → core}/connection_pool_spec.rb +10 -10
  97. data/spec/{sequel_core → core}/core_ext_spec.rb +19 -19
  98. data/spec/{sequel_core → core}/core_sql_spec.rb +68 -71
  99. data/spec/{sequel_core → core}/database_spec.rb +135 -99
  100. data/spec/{sequel_core → core}/dataset_spec.rb +398 -242
  101. data/spec/{sequel_core → core}/expression_filters_spec.rb +13 -13
  102. data/spec/core/migration_spec.rb +263 -0
  103. data/spec/{sequel_core → core}/object_graph_spec.rb +10 -10
  104. data/spec/{sequel_core → core}/pretty_table_spec.rb +2 -2
  105. data/spec/{sequel_core → core}/schema_generator_spec.rb +0 -0
  106. data/spec/{sequel_core → core}/schema_spec.rb +8 -10
  107. data/spec/{sequel_core → core}/spec_helper.rb +29 -2
  108. data/spec/{sequel_core → core}/version_spec.rb +0 -0
  109. data/spec/extensions/blank_spec.rb +67 -0
  110. data/spec/extensions/caching_spec.rb +201 -0
  111. data/spec/{sequel_model/hooks_spec.rb → extensions/hook_class_methods_spec.rb} +8 -23
  112. data/spec/{sequel_model → extensions}/inflector_spec.rb +3 -0
  113. data/spec/{sequel_core → extensions}/migration_spec.rb +4 -4
  114. data/spec/extensions/pagination_spec.rb +99 -0
  115. data/spec/extensions/pretty_table_spec.rb +91 -0
  116. data/spec/extensions/query_spec.rb +85 -0
  117. data/spec/{sequel_model → extensions}/schema_spec.rb +22 -1
  118. data/spec/extensions/serialization_spec.rb +109 -0
  119. data/spec/extensions/single_table_inheritance_spec.rb +53 -0
  120. data/spec/{sequel_model → extensions}/spec_helper.rb +13 -4
  121. data/spec/extensions/string_date_time_spec.rb +93 -0
  122. data/spec/{sequel_model/validations_spec.rb → extensions/validation_class_methods_spec.rb} +15 -103
  123. data/spec/extensions/validation_helpers_spec.rb +291 -0
  124. data/spec/integration/dataset_test.rb +31 -0
  125. data/spec/integration/eager_loader_test.rb +17 -30
  126. data/spec/integration/schema_test.rb +8 -5
  127. data/spec/integration/spec_helper.rb +17 -0
  128. data/spec/integration/transaction_test.rb +68 -0
  129. data/spec/{sequel_model → model}/association_reflection_spec.rb +0 -0
  130. data/spec/{sequel_model → model}/associations_spec.rb +23 -10
  131. data/spec/{sequel_model → model}/base_spec.rb +29 -20
  132. data/spec/{sequel_model → model}/caching_spec.rb +16 -14
  133. data/spec/{sequel_model → model}/dataset_methods_spec.rb +0 -0
  134. data/spec/{sequel_model → model}/eager_loading_spec.rb +8 -8
  135. data/spec/model/hooks_spec.rb +472 -0
  136. data/spec/model/inflector_spec.rb +126 -0
  137. data/spec/{sequel_model → model}/model_spec.rb +25 -20
  138. data/spec/model/plugins_spec.rb +142 -0
  139. data/spec/{sequel_model → model}/record_spec.rb +121 -62
  140. data/spec/model/schema_spec.rb +92 -0
  141. data/spec/model/spec_helper.rb +124 -0
  142. data/spec/model/validations_spec.rb +1080 -0
  143. metadata +136 -107
  144. data/lib/sequel_core/core_ext.rb +0 -217
  145. data/lib/sequel_core/dataset/callback.rb +0 -13
  146. data/lib/sequel_core/dataset/schema.rb +0 -15
  147. data/lib/sequel_core/deprecated.rb +0 -26
  148. data/lib/sequel_core/exceptions.rb +0 -44
  149. data/lib/sequel_core/schema.rb +0 -2
  150. data/lib/sequel_core/schema/sql.rb +0 -325
  151. data/lib/sequel_model/association_reflection.rb +0 -267
  152. data/lib/sequel_model/associations.rb +0 -499
  153. data/lib/sequel_model/base.rb +0 -539
  154. data/lib/sequel_model/caching.rb +0 -82
  155. data/lib/sequel_model/dataset_methods.rb +0 -26
  156. data/lib/sequel_model/eager_loading.rb +0 -370
  157. data/lib/sequel_model/hooks.rb +0 -101
  158. data/lib/sequel_model/plugins.rb +0 -62
  159. data/lib/sequel_model/record.rb +0 -568
  160. data/lib/sequel_model/schema.rb +0 -49
  161. data/lib/sequel_model/validations.rb +0 -429
  162. 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
- Also, new in Sequel 2.10 is 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:
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
- Starting with version 2.4.0, Sequel has support for read only slave databases
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 database connection to use for a given dataset). Support for both
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 new :servers Database option. The :servers option should
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, unless you
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 host slave_server for SELECT queries and master_server for
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 the simple scenario, a distributed rainbow
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 it is always good to have a default server that works.
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 'sequel_model'
1
+ require 'sequel/model'
@@ -1,11 +1,11 @@
1
- require 'sequel_core/adapters/utils/date_format'
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.open('ado://mydb')
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 'sequel_core/adapters/shared/mssql'
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].blank?}
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 'sequel_core/adapters/do/postgres'
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 'sequel_core/adapters/do/mysql'
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 'sequel_core/adapters/do/sqlite'
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(server=nil)
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,4 +1,4 @@
1
- require 'sequel_core/adapters/shared/mysql'
1
+ Sequel.require 'adapters/shared/mysql'
2
2
 
3
3
  module Sequel
4
4
  module DataObjects
@@ -1,4 +1,4 @@
1
- require 'sequel_core/adapters/shared/postgres'
1
+ Sequel.require 'adapters/shared/postgres'
2
2
 
3
3
  module Sequel
4
4
  Postgres::CONVERTED_EXCEPTIONS << PostgresError
@@ -1,4 +1,4 @@
1
- require 'sequel_core/adapters/shared/sqlite'
1
+ Sequel.require 'adapters/shared/sqlite'
2
2
 
3
3
  module Sequel
4
4
  module DataObjects
@@ -1,5 +1,5 @@
1
1
  require 'fb'
2
- require 'sequel_core/adapters/utils/unsupported'
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(server=nil)
184
- synchronize(server) do |conn|
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
- single_value(default_server_opts(:sql=>insert_returning_pk_sql(*values)))
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
- single_record(default_server_opts(:naked=>true, :sql=>insert_returning_sql(nil, *values)))
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