sequel_core 2.2.0 → 3.8.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 (66) hide show
  1. metadata +30 -101
  2. data/CHANGELOG +0 -1519
  3. data/COPYING +0 -19
  4. data/README +0 -313
  5. data/Rakefile +0 -158
  6. data/bin/sequel +0 -117
  7. data/doc/cheat_sheet.rdoc +0 -225
  8. data/doc/dataset_filtering.rdoc +0 -182
  9. data/lib/sequel_core.rb +0 -136
  10. data/lib/sequel_core/adapters/adapter_skeleton.rb +0 -68
  11. data/lib/sequel_core/adapters/ado.rb +0 -90
  12. data/lib/sequel_core/adapters/db2.rb +0 -160
  13. data/lib/sequel_core/adapters/dbi.rb +0 -127
  14. data/lib/sequel_core/adapters/informix.rb +0 -89
  15. data/lib/sequel_core/adapters/jdbc.rb +0 -110
  16. data/lib/sequel_core/adapters/mysql.rb +0 -486
  17. data/lib/sequel_core/adapters/odbc.rb +0 -167
  18. data/lib/sequel_core/adapters/odbc_mssql.rb +0 -106
  19. data/lib/sequel_core/adapters/openbase.rb +0 -76
  20. data/lib/sequel_core/adapters/oracle.rb +0 -182
  21. data/lib/sequel_core/adapters/postgres.rb +0 -560
  22. data/lib/sequel_core/adapters/sqlite.rb +0 -270
  23. data/lib/sequel_core/connection_pool.rb +0 -194
  24. data/lib/sequel_core/core_ext.rb +0 -197
  25. data/lib/sequel_core/core_sql.rb +0 -184
  26. data/lib/sequel_core/database.rb +0 -462
  27. data/lib/sequel_core/database/schema.rb +0 -156
  28. data/lib/sequel_core/dataset.rb +0 -457
  29. data/lib/sequel_core/dataset/callback.rb +0 -13
  30. data/lib/sequel_core/dataset/convenience.rb +0 -245
  31. data/lib/sequel_core/dataset/pagination.rb +0 -96
  32. data/lib/sequel_core/dataset/query.rb +0 -41
  33. data/lib/sequel_core/dataset/schema.rb +0 -15
  34. data/lib/sequel_core/dataset/sql.rb +0 -889
  35. data/lib/sequel_core/deprecated.rb +0 -26
  36. data/lib/sequel_core/exceptions.rb +0 -42
  37. data/lib/sequel_core/migration.rb +0 -187
  38. data/lib/sequel_core/object_graph.rb +0 -216
  39. data/lib/sequel_core/pretty_table.rb +0 -71
  40. data/lib/sequel_core/schema.rb +0 -2
  41. data/lib/sequel_core/schema/generator.rb +0 -239
  42. data/lib/sequel_core/schema/sql.rb +0 -326
  43. data/lib/sequel_core/sql.rb +0 -812
  44. data/lib/sequel_core/worker.rb +0 -68
  45. data/spec/adapters/informix_spec.rb +0 -96
  46. data/spec/adapters/mysql_spec.rb +0 -765
  47. data/spec/adapters/oracle_spec.rb +0 -222
  48. data/spec/adapters/postgres_spec.rb +0 -441
  49. data/spec/adapters/sqlite_spec.rb +0 -413
  50. data/spec/connection_pool_spec.rb +0 -363
  51. data/spec/core_ext_spec.rb +0 -156
  52. data/spec/core_sql_spec.rb +0 -427
  53. data/spec/database_spec.rb +0 -963
  54. data/spec/dataset_spec.rb +0 -2933
  55. data/spec/expression_filters_spec.rb +0 -316
  56. data/spec/migration_spec.rb +0 -261
  57. data/spec/object_graph_spec.rb +0 -230
  58. data/spec/pretty_table_spec.rb +0 -58
  59. data/spec/rcov.opts +0 -6
  60. data/spec/schema_generator_spec.rb +0 -122
  61. data/spec/schema_spec.rb +0 -422
  62. data/spec/spec.opts +0 -0
  63. data/spec/spec_config.rb +0 -7
  64. data/spec/spec_config.rb.example +0 -8
  65. data/spec/spec_helper.rb +0 -55
  66. data/spec/worker_spec.rb +0 -96
@@ -1,270 +0,0 @@
1
- require 'sqlite3'
2
-
3
- module Sequel
4
- module SQLite
5
- class Database < Sequel::Database
6
- set_adapter_scheme :sqlite
7
-
8
- def serial_primary_key_options
9
- {:primary_key => true, :type => :integer, :auto_increment => true}
10
- end
11
-
12
- def connect
13
- @opts[:database] = ':memory:' if @opts[:database].blank?
14
- db = ::SQLite3::Database.new(@opts[:database])
15
- db.busy_timeout(@opts.fetch(:timeout, 5000))
16
- db.type_translation = true
17
- # fix for timestamp translation
18
- db.translator.add_translator("timestamp") do |t, v|
19
- v =~ /^\d+$/ ? Time.at(v.to_i) : Time.parse(v)
20
- end
21
- db
22
- end
23
-
24
- def disconnect
25
- @pool.disconnect {|c| c.close}
26
- end
27
-
28
- def dataset(opts = nil)
29
- SQLite::Dataset.new(self, opts)
30
- end
31
-
32
- TABLES_FILTER = "type = 'table' AND NOT name = 'sqlite_sequence'"
33
-
34
- def tables
35
- self[:sqlite_master].filter(TABLES_FILTER).map {|r| r[:name].to_sym}
36
- end
37
-
38
- def execute(sql)
39
- begin
40
- log_info(sql)
41
- @pool.hold {|conn| conn.execute_batch(sql); conn.changes}
42
- rescue SQLite3::Exception => e
43
- raise Error::InvalidStatement, "#{sql}\r\n#{e.message}"
44
- end
45
- end
46
-
47
- def execute_insert(sql)
48
- begin
49
- log_info(sql)
50
- @pool.hold {|conn| conn.execute(sql); conn.last_insert_row_id}
51
- rescue SQLite3::Exception => e
52
- raise Error::InvalidStatement, "#{sql}\r\n#{e.message}"
53
- end
54
- end
55
-
56
- def single_value(sql)
57
- begin
58
- log_info(sql)
59
- @pool.hold {|conn| conn.get_first_value(sql)}
60
- rescue SQLite3::Exception => e
61
- raise Error::InvalidStatement, "#{sql}\r\n#{e.message}"
62
- end
63
- end
64
-
65
- def execute_select(sql, &block)
66
- begin
67
- log_info(sql)
68
- @pool.hold {|conn| conn.query(sql, &block)}
69
- rescue SQLite3::Exception => e
70
- raise Error::InvalidStatement, "#{sql}\r\n#{e.message}"
71
- end
72
- end
73
-
74
- def pragma_get(name)
75
- single_value("PRAGMA #{name}")
76
- end
77
-
78
- def pragma_set(name, value)
79
- execute("PRAGMA #{name} = #{value}")
80
- end
81
-
82
- AUTO_VACUUM = {'0' => :none, '1' => :full, '2' => :incremental}.freeze
83
-
84
- def auto_vacuum
85
- AUTO_VACUUM[pragma_get(:auto_vacuum)]
86
- end
87
-
88
- def auto_vacuum=(value)
89
- value = AUTO_VACUUM.index(value) || (raise Error, "Invalid value for auto_vacuum option. Please specify one of :none, :full, :incremental.")
90
- pragma_set(:auto_vacuum, value)
91
- end
92
-
93
- SYNCHRONOUS = {'0' => :off, '1' => :normal, '2' => :full}.freeze
94
-
95
- def synchronous
96
- SYNCHRONOUS[pragma_get(:synchronous)]
97
- end
98
-
99
- def synchronous=(value)
100
- value = SYNCHRONOUS.index(value) || (raise Error, "Invalid value for synchronous option. Please specify one of :off, :normal, :full.")
101
- pragma_set(:synchronous, value)
102
- end
103
-
104
- TEMP_STORE = {'0' => :default, '1' => :file, '2' => :memory}.freeze
105
-
106
- def temp_store
107
- TEMP_STORE[pragma_get(:temp_store)]
108
- end
109
-
110
- def temp_store=(value)
111
- value = TEMP_STORE.index(value) || (raise Error, "Invalid value for temp_store option. Please specify one of :default, :file, :memory.")
112
- pragma_set(:temp_store, value)
113
- end
114
-
115
- def alter_table_sql(table, op)
116
- case op[:op]
117
- when :add_column
118
- "ALTER TABLE #{table} ADD #{column_definition_sql(op)}"
119
- when :add_index
120
- index_definition_sql(table, op)
121
- when :drop_column
122
- columns_str = (schema_parse_table(table, {}).map {|c| c[0] } - (Array === op[:name] ? op[:name] : [op[:name]])).join(",")
123
- sql = "BEGIN TRANSACTION;\n"
124
- sql += "CREATE TEMPORARY TABLE #{table}_backup(#{columns_str});\n"
125
- sql += "INSERT INTO #{table}_backup SELECT #{columns_str} FROM #{table};\n"
126
- sql += "DROP TABLE #{table};\n"
127
- sql += "CREATE TABLE #{table}(#{columns_str});\n"
128
- sql += "INSERT INTO #{table} SELECT #{columns_str} FROM #{table}_backup;\n"
129
- sql += "DROP TABLE #{table}_backup;\n"
130
- sql += "COMMIT;\n"
131
- else
132
- raise Error, "Unsupported ALTER TABLE operation"
133
- end
134
- end
135
-
136
- def transaction(&block)
137
- @pool.hold do |conn|
138
- if conn.transaction_active?
139
- return yield(conn)
140
- end
141
- begin
142
- result = nil
143
- conn.transaction {result = yield(conn)}
144
- result
145
- rescue ::Exception => e
146
- raise (SQLite3::Exception === e ? Error.new(e.message) : e) unless Error::Rollback === e
147
- end
148
- end
149
- end
150
-
151
- private
152
- def connection_pool_default_options
153
- o = super.merge(:pool_convert_exceptions=>false)
154
- # Default to only a single connection if a memory database is used,
155
- # because otherwise each connection will get a separate database
156
- o[:max_connections] = 1 if @opts[:database] == ':memory:' || @opts[:database].blank?
157
- o
158
- end
159
-
160
- SCHEMA_TYPE_RE = /\A(\w+)\((\d+)\)\z/
161
- def schema_parse_table(table_name, opts)
162
- rows = self["PRAGMA table_info('#{::SQLite3::Database.quote(table_name.to_s)}')"].collect do |row|
163
- row.delete(:cid)
164
- row[:column] = row.delete(:name)
165
- row[:allow_null] = row.delete(:notnull).to_i == 0 ? 'YES' : 'NO'
166
- row[:default] = row.delete(:dflt_value)
167
- row[:primary_key] = row.delete(:pk).to_i == 1 ? true : false
168
- row[:db_type] = row.delete(:type)
169
- if m = SCHEMA_TYPE_RE.match(row[:db_type])
170
- row[:db_type] = m[1]
171
- row[:max_chars] = m[2].to_i
172
- else
173
- row[:max_chars] = nil
174
- end
175
- row[:numeric_precision] = nil
176
- row
177
- end
178
- schema_parse_rows(rows)
179
- end
180
-
181
- def schema_parse_tables(opts)
182
- schemas = {}
183
- tables.each{|table| schemas[table] = schema_parse_table(table, opts)}
184
- schemas
185
- end
186
- end
187
-
188
- class Dataset < Sequel::Dataset
189
- def quoted_identifier(c)
190
- "`#{c}`"
191
- end
192
-
193
- def literal(v)
194
- case v
195
- when LiteralString
196
- v
197
- when String
198
- "'#{::SQLite3::Database.quote(v)}'"
199
- when Time
200
- literal(v.iso8601)
201
- when Date, DateTime
202
- literal(v.to_s)
203
- else
204
- super
205
- end
206
- end
207
-
208
- def complex_expression_sql(op, args)
209
- case op
210
- when :~, :'!~', :'~*', :'!~*'
211
- raise Error, "SQLite does not support pattern matching via regular expressions"
212
- when :LIKE, :'NOT LIKE', :ILIKE, :'NOT ILIKE'
213
- # SQLite is case insensitive for ASCII, and non case sensitive for other character sets
214
- "#{'NOT ' if [:'NOT LIKE', :'NOT ILIKE'].include?(op)}(#{literal(args.at(0))} LIKE #{literal(args.at(1))})"
215
- else
216
- super(op, args)
217
- end
218
- end
219
-
220
- def insert_sql(*values)
221
- if (values.size == 1) && values.first.is_a?(Sequel::Dataset)
222
- "INSERT INTO #{source_list(@opts[:from])} #{values.first.sql};"
223
- else
224
- super(*values)
225
- end
226
- end
227
-
228
- def fetch_rows(sql, &block)
229
- @db.execute_select(sql) do |result|
230
- @columns = result.columns.map {|c| c.to_sym}
231
- column_count = @columns.size
232
- result.each do |values|
233
- row = {}
234
- column_count.times {|i| row[@columns[i]] = values[i]}
235
- block.call(row)
236
- end
237
- end
238
- end
239
-
240
- def insert(*values)
241
- @db.execute_insert insert_sql(*values)
242
- end
243
-
244
- def update(*args, &block)
245
- @db.execute update_sql(*args, &block)
246
- end
247
-
248
- def delete(opts = nil)
249
- # check if no filter is specified
250
- unless (opts && opts[:where]) || @opts[:where]
251
- @db.transaction do
252
- unfiltered_count = count
253
- @db.execute delete_sql(opts)
254
- unfiltered_count
255
- end
256
- else
257
- @db.execute delete_sql(opts)
258
- end
259
- end
260
-
261
- EXPLAIN = 'EXPLAIN %s'.freeze
262
-
263
- def explain
264
- res = []
265
- @db.result_set(EXPLAIN % select_sql(opts), nil) {|r| res << r}
266
- res
267
- end
268
- end
269
- end
270
- end
@@ -1,194 +0,0 @@
1
- # A ConnectionPool manages access to database connections by keeping
2
- # multiple connections and giving threads exclusive access to each
3
- # connection.
4
- class Sequel::ConnectionPool
5
- # A hash of connections currently being used, key is the Thread,
6
- # value is the connection.
7
- attr_reader :allocated
8
-
9
- # An array of connections opened but not currently used
10
- attr_reader :available_connections
11
-
12
- # The proc used to create a new database connection.
13
- attr_accessor :connection_proc
14
-
15
- # The total number of connections opened, should
16
- # be equal to available_connections.length +
17
- # allocated.length
18
- attr_reader :created_count
19
- alias_method :size, :created_count
20
-
21
- # The maximum number of connections.
22
- attr_reader :max_size
23
-
24
- # The mutex that protects access to the other internal vairables. You must use
25
- # this if you want to manipulate the variables safely.
26
- attr_reader :mutex
27
-
28
-
29
- # Constructs a new pool with a maximum size. If a block is supplied, it
30
- # is used to create new connections as they are needed.
31
- #
32
- # pool = ConnectionPool.new(:max_connections=>10) {MyConnection.new(opts)}
33
- #
34
- # The connection creation proc can be changed at any time by assigning a
35
- # Proc to pool#connection_proc.
36
- #
37
- # pool = ConnectionPool.new(:max_connections=>10)
38
- # pool.connection_proc = proc {MyConnection.new(opts)}
39
- #
40
- # The connection pool takes the following options:
41
- #
42
- # * :max_connections - The maximum number of connections the connection pool
43
- # will open (default 4)
44
- # * :pool_convert_exceptions - Whether to convert non-StandardError based exceptions
45
- # to RuntimeError exceptions (default true)
46
- # * :pool_sleep_time - The amount of time to sleep before attempting to acquire
47
- # a connection again (default 0.001)
48
- # * :pool_timeout - The amount of seconds to wait to acquire a connection
49
- # before raising a PoolTimeoutError (default 5)
50
- def initialize(opts = {}, &block)
51
- @max_size = opts[:max_connections] || 4
52
- @mutex = Mutex.new
53
- @connection_proc = block
54
-
55
- @available_connections = []
56
- @allocated = {}
57
- @created_count = 0
58
- @timeout = opts[:pool_timeout] || 5
59
- @sleep_time = opts[:pool_sleep_time] || 0.001
60
- @convert_exceptions = opts.include?(:pool_convert_exceptions) ? opts[:pool_convert_exceptions] : true
61
- end
62
-
63
- # Chooses the first available connection, or if none are available,
64
- # creates a new connection. Passes the connection to the supplied block:
65
- #
66
- # pool.hold {|conn| conn.execute('DROP TABLE posts')}
67
- #
68
- # Pool#hold is re-entrant, meaning it can be called recursively in
69
- # the same thread without blocking.
70
- #
71
- # If no connection is immediately available and the pool is already using the maximum
72
- # number of connections, Pool#hold will block until a connection
73
- # is available or the timeout expires. If the timeout expires before a
74
- # connection can be acquired, a Sequel::Error::PoolTimeoutError is
75
- # raised.
76
- def hold
77
- begin
78
- t = Thread.current
79
- time = Time.new
80
- timeout = time + @timeout
81
- sleep_time = @sleep_time
82
- if conn = owned_connection(t)
83
- return yield(conn)
84
- end
85
- until conn = acquire(t)
86
- raise(::Sequel::Error::PoolTimeoutError) if Time.new > timeout
87
- sleep sleep_time
88
- end
89
- begin
90
- yield conn
91
- ensure
92
- release(t, conn)
93
- end
94
- rescue Exception => e
95
- raise(@convert_exceptions && !e.is_a?(StandardError) ? RuntimeError.new(e.message) : e)
96
- end
97
- end
98
-
99
- # Removes all connection currently available, optionally yielding each
100
- # connection to the given block. This method has the effect of
101
- # disconnecting from the database. Once a connection is requested using
102
- # #hold, the connection pool creates new connections to the database.
103
- def disconnect(&block)
104
- @mutex.synchronize do
105
- @available_connections.each {|c| block[c]} if block
106
- @available_connections = []
107
- @created_count = @allocated.size
108
- end
109
- end
110
-
111
- private
112
-
113
- # Returns the connection owned by the supplied thread, if any.
114
- def owned_connection(thread)
115
- @mutex.synchronize{@allocated[thread]}
116
- end
117
-
118
- # Assigns a connection to the supplied thread, if one is available.
119
- def acquire(thread)
120
- @mutex.synchronize do
121
- if conn = available
122
- @allocated[thread] = conn
123
- end
124
- end
125
- end
126
-
127
- # Returns an available connection. If no connection is available,
128
- # tries to create a new connection.
129
- def available
130
- @available_connections.pop || make_new
131
- end
132
-
133
- # Creates a new connection if the size of the pool is less than the
134
- # maximum size.
135
- def make_new
136
- if @created_count < @max_size
137
- @created_count += 1
138
- @connection_proc ? @connection_proc.call : \
139
- (raise Error, "No connection proc specified")
140
- end
141
- end
142
-
143
- # Releases the connection assigned to the supplied thread.
144
- def release(thread, conn)
145
- @mutex.synchronize do
146
- @allocated.delete(thread)
147
- @available_connections << conn
148
- end
149
- end
150
- end
151
-
152
- # A SingleThreadedPool acts as a replacement for a ConnectionPool for use
153
- # in single-threaded applications. ConnectionPool imposes a substantial
154
- # performance penalty, so SingleThreadedPool is used to gain some speed.
155
- #
156
- # Note that using a single threaded pool with some adapters can cause
157
- # errors in certain cases, see Sequel.single_threaded=.
158
- class Sequel::SingleThreadedPool
159
- # The single database connection for the pool
160
- attr_reader :conn
161
-
162
- # The proc used to create a new database connection
163
- attr_writer :connection_proc
164
-
165
- # Initializes the instance with the supplied block as the connection_proc.
166
- #
167
- # The single threaded pool takes the following options:
168
- #
169
- # * :pool_convert_exceptions - Whether to convert non-StandardError based exceptions
170
- # to RuntimeError exceptions (default true)
171
- def initialize(opts={}, &block)
172
- @connection_proc = block
173
- @convert_exceptions = opts.include?(:pool_convert_exceptions) ? opts[:pool_convert_exceptions] : true
174
- end
175
-
176
- # Yields the connection to the supplied block. This method simulates the
177
- # ConnectionPool#hold API.
178
- def hold
179
- begin
180
- @conn ||= @connection_proc.call
181
- yield @conn
182
- rescue Exception => e
183
- # if the error is not a StandardError it is converted into RuntimeError.
184
- raise(@convert_exceptions && !e.is_a?(StandardError) ? RuntimeError.new(e.message) : e)
185
- end
186
- end
187
-
188
- # Disconnects from the database. Once a connection is requested using
189
- # #hold, the connection is reestablished.
190
- def disconnect(&block)
191
- block[@conn] if block && @conn
192
- @conn = nil
193
- end
194
- end