epugh-sequel 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
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