epugh-sequel 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. data/README.rdoc +652 -0
  2. data/VERSION.yml +4 -0
  3. data/bin/sequel +104 -0
  4. data/lib/sequel.rb +1 -0
  5. data/lib/sequel/adapters/ado.rb +85 -0
  6. data/lib/sequel/adapters/db2.rb +132 -0
  7. data/lib/sequel/adapters/dbi.rb +101 -0
  8. data/lib/sequel/adapters/do.rb +197 -0
  9. data/lib/sequel/adapters/do/mysql.rb +38 -0
  10. data/lib/sequel/adapters/do/postgres.rb +92 -0
  11. data/lib/sequel/adapters/do/sqlite.rb +31 -0
  12. data/lib/sequel/adapters/firebird.rb +307 -0
  13. data/lib/sequel/adapters/informix.rb +75 -0
  14. data/lib/sequel/adapters/jdbc.rb +485 -0
  15. data/lib/sequel/adapters/jdbc/h2.rb +62 -0
  16. data/lib/sequel/adapters/jdbc/mysql.rb +56 -0
  17. data/lib/sequel/adapters/jdbc/oracle.rb +23 -0
  18. data/lib/sequel/adapters/jdbc/postgresql.rb +101 -0
  19. data/lib/sequel/adapters/jdbc/sqlite.rb +43 -0
  20. data/lib/sequel/adapters/mysql.rb +370 -0
  21. data/lib/sequel/adapters/odbc.rb +184 -0
  22. data/lib/sequel/adapters/openbase.rb +57 -0
  23. data/lib/sequel/adapters/oracle.rb +140 -0
  24. data/lib/sequel/adapters/postgres.rb +453 -0
  25. data/lib/sequel/adapters/shared/mssql.rb +93 -0
  26. data/lib/sequel/adapters/shared/mysql.rb +341 -0
  27. data/lib/sequel/adapters/shared/oracle.rb +62 -0
  28. data/lib/sequel/adapters/shared/postgres.rb +743 -0
  29. data/lib/sequel/adapters/shared/progress.rb +34 -0
  30. data/lib/sequel/adapters/shared/sqlite.rb +263 -0
  31. data/lib/sequel/adapters/sqlite.rb +243 -0
  32. data/lib/sequel/adapters/utils/date_format.rb +21 -0
  33. data/lib/sequel/adapters/utils/stored_procedures.rb +75 -0
  34. data/lib/sequel/adapters/utils/unsupported.rb +62 -0
  35. data/lib/sequel/connection_pool.rb +258 -0
  36. data/lib/sequel/core.rb +204 -0
  37. data/lib/sequel/core_sql.rb +185 -0
  38. data/lib/sequel/database.rb +687 -0
  39. data/lib/sequel/database/schema_generator.rb +324 -0
  40. data/lib/sequel/database/schema_methods.rb +164 -0
  41. data/lib/sequel/database/schema_sql.rb +324 -0
  42. data/lib/sequel/dataset.rb +422 -0
  43. data/lib/sequel/dataset/convenience.rb +237 -0
  44. data/lib/sequel/dataset/prepared_statements.rb +220 -0
  45. data/lib/sequel/dataset/sql.rb +1105 -0
  46. data/lib/sequel/deprecated.rb +529 -0
  47. data/lib/sequel/exceptions.rb +44 -0
  48. data/lib/sequel/extensions/blank.rb +42 -0
  49. data/lib/sequel/extensions/inflector.rb +288 -0
  50. data/lib/sequel/extensions/pagination.rb +96 -0
  51. data/lib/sequel/extensions/pretty_table.rb +78 -0
  52. data/lib/sequel/extensions/query.rb +48 -0
  53. data/lib/sequel/extensions/string_date_time.rb +47 -0
  54. data/lib/sequel/metaprogramming.rb +44 -0
  55. data/lib/sequel/migration.rb +212 -0
  56. data/lib/sequel/model.rb +142 -0
  57. data/lib/sequel/model/association_reflection.rb +263 -0
  58. data/lib/sequel/model/associations.rb +1024 -0
  59. data/lib/sequel/model/base.rb +911 -0
  60. data/lib/sequel/model/deprecated.rb +188 -0
  61. data/lib/sequel/model/deprecated_hooks.rb +103 -0
  62. data/lib/sequel/model/deprecated_inflector.rb +335 -0
  63. data/lib/sequel/model/deprecated_validations.rb +384 -0
  64. data/lib/sequel/model/errors.rb +37 -0
  65. data/lib/sequel/model/exceptions.rb +7 -0
  66. data/lib/sequel/model/inflections.rb +230 -0
  67. data/lib/sequel/model/plugins.rb +74 -0
  68. data/lib/sequel/object_graph.rb +230 -0
  69. data/lib/sequel/plugins/caching.rb +122 -0
  70. data/lib/sequel/plugins/hook_class_methods.rb +122 -0
  71. data/lib/sequel/plugins/schema.rb +53 -0
  72. data/lib/sequel/plugins/single_table_inheritance.rb +63 -0
  73. data/lib/sequel/plugins/validation_class_methods.rb +373 -0
  74. data/lib/sequel/sql.rb +854 -0
  75. data/lib/sequel/version.rb +11 -0
  76. data/lib/sequel_core.rb +1 -0
  77. data/lib/sequel_model.rb +1 -0
  78. data/spec/adapters/ado_spec.rb +46 -0
  79. data/spec/adapters/firebird_spec.rb +376 -0
  80. data/spec/adapters/informix_spec.rb +96 -0
  81. data/spec/adapters/mysql_spec.rb +875 -0
  82. data/spec/adapters/oracle_spec.rb +272 -0
  83. data/spec/adapters/postgres_spec.rb +692 -0
  84. data/spec/adapters/spec_helper.rb +10 -0
  85. data/spec/adapters/sqlite_spec.rb +550 -0
  86. data/spec/core/connection_pool_spec.rb +526 -0
  87. data/spec/core/core_ext_spec.rb +156 -0
  88. data/spec/core/core_sql_spec.rb +528 -0
  89. data/spec/core/database_spec.rb +1214 -0
  90. data/spec/core/dataset_spec.rb +3513 -0
  91. data/spec/core/expression_filters_spec.rb +363 -0
  92. data/spec/core/migration_spec.rb +261 -0
  93. data/spec/core/object_graph_spec.rb +280 -0
  94. data/spec/core/pretty_table_spec.rb +58 -0
  95. data/spec/core/schema_generator_spec.rb +167 -0
  96. data/spec/core/schema_spec.rb +778 -0
  97. data/spec/core/spec_helper.rb +82 -0
  98. data/spec/core/version_spec.rb +7 -0
  99. data/spec/extensions/blank_spec.rb +67 -0
  100. data/spec/extensions/caching_spec.rb +201 -0
  101. data/spec/extensions/hook_class_methods_spec.rb +470 -0
  102. data/spec/extensions/inflector_spec.rb +122 -0
  103. data/spec/extensions/pagination_spec.rb +99 -0
  104. data/spec/extensions/pretty_table_spec.rb +91 -0
  105. data/spec/extensions/query_spec.rb +85 -0
  106. data/spec/extensions/schema_spec.rb +111 -0
  107. data/spec/extensions/single_table_inheritance_spec.rb +53 -0
  108. data/spec/extensions/spec_helper.rb +90 -0
  109. data/spec/extensions/string_date_time_spec.rb +93 -0
  110. data/spec/extensions/validation_class_methods_spec.rb +1054 -0
  111. data/spec/integration/dataset_test.rb +160 -0
  112. data/spec/integration/eager_loader_test.rb +683 -0
  113. data/spec/integration/prepared_statement_test.rb +130 -0
  114. data/spec/integration/schema_test.rb +183 -0
  115. data/spec/integration/spec_helper.rb +75 -0
  116. data/spec/integration/type_test.rb +96 -0
  117. data/spec/model/association_reflection_spec.rb +93 -0
  118. data/spec/model/associations_spec.rb +1780 -0
  119. data/spec/model/base_spec.rb +494 -0
  120. data/spec/model/caching_spec.rb +217 -0
  121. data/spec/model/dataset_methods_spec.rb +78 -0
  122. data/spec/model/eager_loading_spec.rb +1165 -0
  123. data/spec/model/hooks_spec.rb +472 -0
  124. data/spec/model/inflector_spec.rb +126 -0
  125. data/spec/model/model_spec.rb +588 -0
  126. data/spec/model/plugins_spec.rb +142 -0
  127. data/spec/model/record_spec.rb +1243 -0
  128. data/spec/model/schema_spec.rb +92 -0
  129. data/spec/model/spec_helper.rb +124 -0
  130. data/spec/model/validations_spec.rb +1080 -0
  131. data/spec/rcov.opts +6 -0
  132. data/spec/spec.opts +0 -0
  133. data/spec/spec_config.rb.example +10 -0
  134. metadata +202 -0
@@ -0,0 +1,38 @@
1
+ Sequel.require 'adapters/shared/mysql'
2
+
3
+ module Sequel
4
+ module DataObjects
5
+ # Database and Dataset instance methods for MySQL specific
6
+ # support via DataObjects.
7
+ module MySQL
8
+ # Database instance methods for MySQL databases accessed via DataObjects.
9
+ module DatabaseMethods
10
+ include Sequel::MySQL::DatabaseMethods
11
+
12
+ # Return instance of Sequel::DataObjects::MySQL::Dataset with the given opts.
13
+ def dataset(opts=nil)
14
+ Sequel::DataObjects::MySQL::Dataset.new(self, opts)
15
+ end
16
+
17
+ private
18
+
19
+ # The database name for the given database. Need to parse it out
20
+ # of the connection string, since the DataObjects does no parsing on the
21
+ # given connection string by default.
22
+ def database_name
23
+ (m = /\/(.*)/.match(URI.parse(uri).path)) && m[1]
24
+ end
25
+ end
26
+
27
+ # Dataset class for MySQL datasets accessed via DataObjects.
28
+ class Dataset < DataObjects::Dataset
29
+ include Sequel::MySQL::DatasetMethods
30
+
31
+ # Use execute_insert to execute the replace_sql.
32
+ def replace(*args)
33
+ execute_insert(replace_sql(*args))
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,92 @@
1
+ Sequel.require 'adapters/shared/postgres'
2
+
3
+ module Sequel
4
+ Postgres::CONVERTED_EXCEPTIONS << PostgresError
5
+
6
+ module DataObjects
7
+ # Adapter, Database, and Dataset support for accessing a PostgreSQL
8
+ # database via DataObjects.
9
+ module Postgres
10
+ # Methods to add to the DataObjects adapter/connection to allow it to work
11
+ # with the shared PostgreSQL code.
12
+ module AdapterMethods
13
+ include Sequel::Postgres::AdapterMethods
14
+
15
+ # Give the DataObjects adapter a direct execute method, which creates
16
+ # a statement with the given sql and executes it.
17
+ def execute(sql, args=nil)
18
+ command = create_command(sql)
19
+ begin
20
+ if block_given?
21
+ begin
22
+ reader = command.execute_reader
23
+ yield(reader)
24
+ ensure
25
+ reader.close if reader
26
+ end
27
+ else
28
+ command.execute_non_query
29
+ end
30
+ rescue PostgresError => e
31
+ raise_error(e)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ # DataObjects specific method of getting specific values from a result set.
38
+ def single_value(reader)
39
+ while(reader.next!) do
40
+ return reader.values.at(0)
41
+ end
42
+ end
43
+ end
44
+
45
+ # Methods to add to Database instances that access PostgreSQL via
46
+ # DataObjects.
47
+ module DatabaseMethods
48
+ include Sequel::Postgres::DatabaseMethods
49
+
50
+ # Add the primary_keys and primary_key_sequences instance variables,
51
+ # so we can get the correct return values for inserted rows.
52
+ def self.extended(db)
53
+ db.instance_eval do
54
+ @primary_keys = {}
55
+ @primary_key_sequences = {}
56
+ end
57
+ end
58
+
59
+ # Return instance of Sequel::DataObjects::Postgres::Dataset with the given opts.
60
+ def dataset(opts=nil)
61
+ Sequel::DataObjects::Postgres::Dataset.new(self, opts)
62
+ end
63
+
64
+ # Run the INSERT sql on the database and return the primary key
65
+ # for the record.
66
+ def execute_insert(sql, opts={})
67
+ log_info(sql)
68
+ synchronize(opts[:server]) do |conn|
69
+ conn.create_command(sql).execute_non_query
70
+ insert_result(conn, opts[:table], opts[:values])
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ # Extend the adapter with the DataObjects PostgreSQL AdapterMethods
77
+ def setup_connection(conn)
78
+ conn = super(conn)
79
+ conn.extend(Sequel::DataObjects::Postgres::AdapterMethods)
80
+ conn.db = self
81
+ conn.apply_connection_settings
82
+ conn
83
+ end
84
+ end
85
+
86
+ # Dataset subclass used for datasets that connect to PostgreSQL via DataObjects.
87
+ class Dataset < DataObjects::Dataset
88
+ include Sequel::Postgres::DatasetMethods
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,31 @@
1
+ Sequel.require 'adapters/shared/sqlite'
2
+
3
+ module Sequel
4
+ module DataObjects
5
+ # Database and Dataset support for SQLite databases accessed via DataObjects.
6
+ module SQLite
7
+ # Instance methods for SQLite Database objects accessed via DataObjects.
8
+ module DatabaseMethods
9
+ include Sequel::SQLite::DatabaseMethods
10
+
11
+ # Return Sequel::DataObjects::SQLite::Dataset object with the given opts.
12
+ def dataset(opts=nil)
13
+ Sequel::DataObjects::SQLite::Dataset.new(self, opts)
14
+ end
15
+
16
+ private
17
+
18
+ # Default to a single connection for a memory database.
19
+ def connection_pool_default_options
20
+ o = super
21
+ uri == 'sqlite3::memory:' ? o.merge(:max_connections=>1) : o
22
+ end
23
+ end
24
+
25
+ # Dataset class for SQLite datasets accessed via DataObjects.
26
+ class Dataset < DataObjects::Dataset
27
+ include Sequel::SQLite::DatasetMethods
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,307 @@
1
+ require 'fb'
2
+ Sequel.require 'adapters/utils/unsupported'
3
+
4
+ module Sequel
5
+ # The Sequel Firebird adapter requires the ruby fb driver located at
6
+ # http://github.com/wishdev/fb.
7
+ module Firebird
8
+ class Database < Sequel::Database
9
+ set_adapter_scheme :firebird
10
+
11
+ AUTO_INCREMENT = ''.freeze
12
+
13
+ # Add the primary_keys and primary_key_sequences instance variables,
14
+ # so we can get the correct return values for inserted rows.
15
+ def initialize(*args)
16
+ super
17
+ @primary_keys = {}
18
+ @primary_key_sequences = {}
19
+ end
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
+ def connect(server)
42
+ opts = server_opts(server)
43
+
44
+ db = Fb::Database.new(
45
+ :database => "#{opts[:host]}:#{opts[:database]}",
46
+ :username => opts[:user],
47
+ :password => opts[:password])
48
+ conn = db.connect
49
+ conn.downcase_names = true
50
+ conn
51
+ end
52
+
53
+ def create_sequence_sql(name, opts={})
54
+ "CREATE SEQUENCE #{quote_identifier(name)}"
55
+ end
56
+
57
+ # Creates a table with the columns given in the provided block:
58
+ #
59
+ # DB.create_table :posts do
60
+ # primary_key :id, :serial
61
+ # column :title, :text
62
+ # column :content, :text
63
+ # index :title
64
+ # end
65
+ #
66
+ # See Schema::Generator.
67
+ # Firebird gets an override because of the mess of creating a
68
+ # generator for auto-incrementing primary keys.
69
+ def create_table(name, options={}, &block)
70
+ options = {:generator=>options} if options.is_a?(Schema::Generator)
71
+ statements = create_table_sql_list(name, *((options[:generator] ||= Schema::Generator.new(self, &block)).create_info << options))
72
+ begin
73
+ execute_ddl(statements[1])
74
+ rescue
75
+ nil
76
+ end if statements[1]
77
+ statements[0].flatten.each {|sql| execute_ddl(sql)}
78
+ end
79
+
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
+ def create_trigger(*args)
110
+ self << create_trigger_sql(*args)
111
+ end
112
+
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
+ def dataset(opts = nil)
127
+ Firebird::Dataset.new(self, opts)
128
+ end
129
+
130
+ def drop_sequence(name)
131
+ self << drop_sequence_sql(name)
132
+ end
133
+
134
+ def drop_sequence_sql(name)
135
+ "DROP SEQUENCE #{quote_identifier(name)}"
136
+ end
137
+
138
+ def execute(sql, opts={})
139
+ log_info(sql)
140
+ begin
141
+ synchronize(opts[:server]) do |conn|
142
+ r = conn.execute(sql)
143
+ yield(r) if block_given?
144
+ r
145
+ end
146
+ rescue => e
147
+ log_info(e.message)
148
+ raise_error(e, :classes=>[Fb::Error])
149
+ end
150
+ end
151
+
152
+ # Return primary key for the given table.
153
+ def primary_key(table, server=nil)
154
+ synchronize(server){|conn| primary_key_for_table(conn, table)}
155
+ end
156
+
157
+ # Returns primary key for the given table. This information is
158
+ # cached, and if the primary key for a table is changed, the
159
+ # @primary_keys instance variable should be reset manually.
160
+ def primary_key_for_table(conn, table)
161
+ @primary_keys[quote_identifier(table)] ||= conn.table_primary_key(quote_identifier(table))
162
+ end
163
+
164
+ def restart_sequence(*args)
165
+ self << restart_sequence_sql(*args)
166
+ end
167
+
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
+ def sequences(opts={})
174
+ ds = self[:"rdb$generators"].server(opts[:server]).filter(:"rdb$system_flag" => 0).select(:"rdb$generator_name")
175
+ block_given? ? yield(ds) : ds.map{|r| ds.send(:output_identifier, r[:"rdb$generator_name"])}
176
+ end
177
+
178
+ def tables(opts={})
179
+ ds = self[:"rdb$relations"].server(opts[:server]).filter(:"rdb$view_blr" => nil, Sequel::SQL::Function.new(:COALESCE, :"rdb$system_flag", 0) => 0).select(:"rdb$relation_name")
180
+ block_given? ? yield(ds) : ds.map{|r| ds.send(:output_identifier, r[:"rdb$relation_name"])}
181
+ end
182
+
183
+ def transaction(opts={})
184
+ unless opts.is_a?(Hash)
185
+ Deprecation.deprecate('Passing an argument other than a Hash to Database#transaction', "Use DB.transaction(:server=>#{opts.inspect})")
186
+ opts = {:server=>opts}
187
+ end
188
+ synchronize(opts[:server]) do |conn|
189
+ return yield(conn) if @transactions.include?(Thread.current)
190
+ log_info("Transaction.begin")
191
+ conn.transaction
192
+ begin
193
+ @transactions << Thread.current
194
+ yield(conn)
195
+ rescue ::Exception => e
196
+ log_info("Transaction.rollback")
197
+ conn.rollback
198
+ transaction_error(e, Fb::Error)
199
+ ensure
200
+ unless e
201
+ log_info("Transaction.commit")
202
+ conn.commit
203
+ end
204
+ @transactions.delete(Thread.current)
205
+ end
206
+ end
207
+ end
208
+
209
+ private
210
+
211
+ def disconnect_connection(c)
212
+ c.close
213
+ end
214
+ end
215
+
216
+ # Dataset class for Firebird datasets
217
+ class Dataset < Sequel::Dataset
218
+ include UnsupportedIntersectExcept
219
+
220
+ BOOL_TRUE = '1'.freeze
221
+ BOOL_FALSE = '0'.freeze
222
+ NULL = LiteralString.new('NULL').freeze
223
+ COMMA_SEPARATOR = ', '.freeze
224
+ FIREBIRD_TIMESTAMP_FORMAT = "TIMESTAMP '%Y-%m-%d %H:%M:%S".freeze
225
+ SELECT_CLAUSE_ORDER = %w'distinct limit columns from join where group having compounds order'.freeze
226
+
227
+ # Yield all rows returned by executing the given SQL and converting
228
+ # the types.
229
+ def fetch_rows(sql, &block)
230
+ execute(sql) do |s|
231
+ begin
232
+ @columns = s.fields.map{|c| output_identifier(c.name)}
233
+ s.fetchall(:symbols_hash).each do |r|
234
+ h = {}
235
+ r.each{|k,v| h[output_identifier(k)] = v}
236
+ yield h
237
+ end
238
+ ensure
239
+ s.close
240
+ end
241
+ end
242
+ self
243
+ end
244
+
245
+ # Insert given values into the database.
246
+ def insert(*values)
247
+ if !@opts[:sql]
248
+ clone(default_server_opts(:sql=>insert_returning_pk_sql(*values))).single_value
249
+ else
250
+ execute_insert(insert_sql(*values), :table=>opts[:from].first,
251
+ :values=>values.size == 1 ? values.first : values)
252
+ end
253
+ end
254
+
255
+ # Use the RETURNING clause to return the primary key of the inserted record, if it exists
256
+ def insert_returning_pk_sql(*values)
257
+ pk = db.primary_key(opts[:from].first)
258
+ insert_returning_sql(pk ? Sequel::SQL::Identifier.new(pk) : NULL, *values)
259
+ end
260
+
261
+ # Use the RETURNING clause to return the columns listed in returning.
262
+ def insert_returning_sql(returning, *values)
263
+ "#{insert_sql(*values)} RETURNING #{column_list(Array(returning))}"
264
+ end
265
+
266
+ # Insert a record returning the record inserted
267
+ def insert_select(*values)
268
+ naked.clone(default_server_opts(:sql=>insert_returning_sql(nil, *values))).single_record
269
+ end
270
+
271
+ # The order of clauses in the SELECT SQL statement
272
+ def select_clause_order
273
+ SELECT_CLAUSE_ORDER
274
+ end
275
+
276
+ def select_limit_sql(sql, opts)
277
+ sql << " FIRST #{opts[:limit]}" if opts[:limit]
278
+ sql << " SKIP #{opts[:offset]}" if opts[:offset]
279
+ end
280
+
281
+ private
282
+
283
+ def hash_row(stmt, row)
284
+ @columns.inject({}) do |m, c|
285
+ m[c] = row.shift
286
+ m
287
+ end
288
+ end
289
+
290
+ def literal_datetime(v)
291
+ "#{v.strftime(FIREBIRD_TIMESTAMP_FORMAT)}.#{sprintf("%04d",(v.sec_fraction * 864000000))}'"
292
+ end
293
+
294
+ def literal_false
295
+ BOOL_FALSE
296
+ end
297
+
298
+ def literal_time(v)
299
+ "#{v.strftime(FIREBIRD_TIMESTAMP_FORMAT)}.#{sprintf("%04d",v.usec / 100)}'"
300
+ end
301
+
302
+ def literal_true
303
+ BOOL_TRUE
304
+ end
305
+ end
306
+ end
307
+ end