sequel 0.4.0 → 0.4.1

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 (48) hide show
  1. data/CHANGELOG +4 -0
  2. data/README +1 -6
  3. data/Rakefile +1 -1
  4. data/bin/sequel +1 -3
  5. data/lib/sequel.rb +18 -1
  6. data/lib/sequel/adapters/ado.rb +104 -0
  7. data/lib/sequel/adapters/db2.rb +160 -0
  8. data/lib/sequel/adapters/dbi.rb +130 -0
  9. data/lib/sequel/adapters/informix.rb +78 -0
  10. data/lib/sequel/adapters/mysql.rb +256 -0
  11. data/lib/sequel/adapters/odbc.rb +144 -0
  12. data/lib/sequel/adapters/oracle.rb +109 -0
  13. data/lib/sequel/adapters/postgres.rb +507 -0
  14. data/lib/sequel/adapters/sqlite.rb +186 -0
  15. data/lib/sequel/ado.rb +2 -104
  16. data/lib/{sequel-core → sequel}/array_keys.rb +0 -0
  17. data/lib/{sequel-core → sequel}/connection_pool.rb +0 -0
  18. data/lib/{sequel-core → sequel}/core_ext.rb +0 -0
  19. data/lib/{sequel-core → sequel}/core_sql.rb +0 -0
  20. data/lib/{sequel-core → sequel}/database.rb +10 -20
  21. data/lib/{sequel-core → sequel}/dataset.rb +0 -0
  22. data/lib/{sequel-core → sequel}/dataset/convenience.rb +0 -0
  23. data/lib/{sequel-core → sequel}/dataset/sequelizer.rb +0 -0
  24. data/lib/{sequel-core → sequel}/dataset/sql.rb +0 -0
  25. data/lib/sequel/db2.rb +2 -160
  26. data/lib/sequel/dbi.rb +2 -130
  27. data/lib/{sequel-core → sequel}/error.rb +0 -0
  28. data/lib/sequel/informix.rb +2 -78
  29. data/lib/{sequel-core → sequel}/migration.rb +0 -0
  30. data/lib/{sequel-core → sequel}/model.rb +0 -0
  31. data/lib/{sequel-core → sequel}/model/base.rb +0 -0
  32. data/lib/{sequel-core → sequel}/model/caching.rb +0 -0
  33. data/lib/{sequel-core → sequel}/model/hooks.rb +0 -0
  34. data/lib/{sequel-core → sequel}/model/record.rb +0 -0
  35. data/lib/{sequel-core → sequel}/model/relations.rb +0 -0
  36. data/lib/{sequel-core → sequel}/model/schema.rb +0 -0
  37. data/lib/sequel/mysql.rb +2 -256
  38. data/lib/sequel/odbc.rb +2 -144
  39. data/lib/sequel/oracle.rb +2 -109
  40. data/lib/sequel/postgres.rb +2 -507
  41. data/lib/{sequel-core → sequel}/pretty_table.rb +0 -0
  42. data/lib/{sequel-core → sequel}/schema.rb +0 -0
  43. data/lib/{sequel-core → sequel}/schema/schema_generator.rb +0 -0
  44. data/lib/{sequel-core → sequel}/schema/schema_sql.rb +0 -0
  45. data/lib/sequel/sqlite.rb +2 -186
  46. data/lib/{sequel-core → sequel}/worker.rb +0 -0
  47. data/spec/database_spec.rb +7 -9
  48. metadata +39 -29
@@ -0,0 +1,186 @@
1
+ if !Object.const_defined?('Sequel')
2
+ require File.join(File.dirname(__FILE__), '../../sequel')
3
+ end
4
+
5
+ require 'sqlite3'
6
+
7
+ module Sequel
8
+ module SQLite
9
+ class Database < Sequel::Database
10
+ set_adapter_scheme :sqlite
11
+
12
+ def serial_primary_key_options
13
+ {:primary_key => true, :type => :integer, :auto_increment => true}
14
+ end
15
+
16
+ def connect
17
+ if @opts[:database].nil? || @opts[:database].empty?
18
+ @opts[:database] = ':memory:'
19
+ end
20
+ db = ::SQLite3::Database.new(@opts[:database])
21
+ db.type_translation = true
22
+ # fix for timestamp translation
23
+ db.translator.add_translator("timestamp") do |t, v|
24
+ v =~ /^\d+$/ ? Time.at(v.to_i) : Time.parse(v)
25
+ end
26
+ db
27
+ end
28
+
29
+ def disconnect
30
+ @pool.disconnect {|c| c.close}
31
+ end
32
+
33
+ def dataset(opts = nil)
34
+ SQLite::Dataset.new(self, opts)
35
+ end
36
+
37
+ TABLES_FILTER = "type = 'table' AND NOT name = 'sqlite_sequence'"
38
+
39
+ def tables
40
+ self[:sqlite_master].filter(TABLES_FILTER).map {|r| r[:name].to_sym}
41
+ end
42
+
43
+ def execute(sql)
44
+ @logger.info(sql) if @logger
45
+ @pool.hold {|conn| conn.execute_batch(sql); conn.changes}
46
+ end
47
+
48
+ def execute_insert(sql)
49
+ @logger.info(sql) if @logger
50
+ @pool.hold {|conn| conn.execute(sql); conn.last_insert_row_id}
51
+ end
52
+
53
+ def single_value(sql)
54
+ @logger.info(sql) if @logger
55
+ @pool.hold {|conn| conn.get_first_value(sql)}
56
+ end
57
+
58
+ def execute_select(sql, &block)
59
+ @logger.info(sql) if @logger
60
+ @pool.hold {|conn| conn.query(sql, &block)}
61
+ end
62
+
63
+ def pragma_get(name)
64
+ single_value("PRAGMA #{name}")
65
+ end
66
+
67
+ def pragma_set(name, value)
68
+ execute("PRAGMA #{name} = #{value}")
69
+ end
70
+
71
+ AUTO_VACUUM = {'0' => :none, '1' => :full, '2' => :incremental}.freeze
72
+
73
+ def auto_vacuum
74
+ AUTO_VACUUM[pragma_get(:auto_vacuum)]
75
+ end
76
+
77
+ def auto_vacuum=(value)
78
+ value = AUTO_VACUUM.index(value) || (raise SequelError, "Invalid value for auto_vacuum option. Please specify one of :none, :full, :incremental.")
79
+ pragma_set(:auto_vacuum, value)
80
+ end
81
+
82
+ SYNCHRONOUS = {'0' => :off, '1' => :normal, '2' => :full}.freeze
83
+
84
+ def synchronous
85
+ SYNCHRONOUS[pragma_get(:synchronous)]
86
+ end
87
+
88
+ def synchronous=(value)
89
+ value = SYNCHRONOUS.index(value) || (raise SequelError, "Invalid value for synchronous option. Please specify one of :off, :normal, :full.")
90
+ pragma_set(:synchronous, value)
91
+ end
92
+
93
+ TEMP_STORE = {'0' => :default, '1' => :file, '2' => :memory}.freeze
94
+
95
+ def temp_store
96
+ TEMP_STORE[pragma_get(:temp_store)]
97
+ end
98
+
99
+ def temp_store=(value)
100
+ value = TEMP_STORE.index(value) || (raise SequelError, "Invalid value for temp_store option. Please specify one of :default, :file, :memory.")
101
+ pragma_set(:temp_store, value)
102
+ end
103
+
104
+ def transaction(&block)
105
+ @pool.hold do |conn|
106
+ if conn.transaction_active?
107
+ return yield(conn)
108
+ end
109
+ begin
110
+ result = nil
111
+ conn.transaction {result = yield(conn)}
112
+ result
113
+ rescue => e
114
+ raise e unless SequelRollbackError === e
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ class Dataset < Sequel::Dataset
121
+ def literal(v)
122
+ case v
123
+ when Time: literal(v.iso8601)
124
+ else
125
+ super
126
+ end
127
+ end
128
+
129
+ def insert_sql(*values)
130
+ if (values.size == 1) && values.first.is_a?(Sequel::Dataset)
131
+ "INSERT INTO #{@opts[:from]} #{values.first.sql};"
132
+ else
133
+ super(*values)
134
+ end
135
+ end
136
+
137
+ def fetch_rows(sql, &block)
138
+ @db.execute_select(sql) do |result|
139
+ @columns = result.columns.map {|c| c.to_sym}
140
+ column_count = @columns.size
141
+ result.each do |values|
142
+ row = {}
143
+ column_count.times {|i| row[@columns[i]] = values[i]}
144
+ block.call(row)
145
+ end
146
+ end
147
+ end
148
+
149
+ def array_tuples_fetch_rows(sql, &block)
150
+ @db.execute_select(sql) do |result|
151
+ @columns = result.columns.map {|c| c.to_sym}
152
+ result.each {|r| r.keys = @columns; block[r]}
153
+ end
154
+ end
155
+
156
+ def insert(*values)
157
+ @db.execute_insert insert_sql(*values)
158
+ end
159
+
160
+ def update(values, opts = nil)
161
+ @db.execute update_sql(values, opts)
162
+ end
163
+
164
+ def delete(opts = nil)
165
+ # check if no filter is specified
166
+ unless (opts && opts[:where]) || @opts[:where]
167
+ @db.transaction do
168
+ unfiltered_count = count
169
+ @db.execute delete_sql(opts)
170
+ unfiltered_count
171
+ end
172
+ else
173
+ @db.execute delete_sql(opts)
174
+ end
175
+ end
176
+
177
+ EXPLAIN = 'EXPLAIN %s'.freeze
178
+
179
+ def explain
180
+ res = []
181
+ @db.result_set(EXPLAIN % select_sql(opts), nil) {|r| res << r}
182
+ res
183
+ end
184
+ end
185
+ end
186
+ end
data/lib/sequel/ado.rb CHANGED
@@ -1,104 +1,2 @@
1
- if !Object.const_defined?('Sequel')
2
- require File.join(File.dirname(__FILE__), '../sequel')
3
- end
4
-
5
- require 'win32ole'
6
-
7
- module Sequel
8
- # The ADO adapter provides connectivity to ADO databases in Windows. ADO
9
- # databases can be opened using a URL with the ado schema:
10
- #
11
- # DB = Sequel.open('ado://mydb')
12
- #
13
- # or using the Sequel.ado method:
14
- #
15
- # DB = Sequel.ado('mydb')
16
- #
17
- module ADO
18
- class Database < Sequel::Database
19
- set_adapter_scheme :ado
20
-
21
- AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
22
-
23
- def auto_increment_sql
24
- AUTO_INCREMENT
25
- end
26
-
27
- def connect
28
- dbname = @opts[:database]
29
- handle = WIN32OLE.new('ADODB.Connection')
30
- handle.Open(dbname)
31
- handle
32
- end
33
-
34
- def disconnect
35
- # how do we disconnect? couldn't find anything in the docs
36
- end
37
-
38
- def dataset(opts = nil)
39
- ADO::Dataset.new(self, opts)
40
- end
41
-
42
- def execute(sql)
43
- @logger.info(sql) if @logger
44
- @pool.hold {|conn| conn.Execute(sql)}
45
- end
46
-
47
- alias_method :do, :execute
48
- end
49
-
50
- class Dataset < Sequel::Dataset
51
- def literal(v)
52
- case v
53
- when Time: literal(v.iso8601)
54
- else
55
- super
56
- end
57
- end
58
-
59
- def fetch_rows(sql, &block)
60
- @db.synchronize do
61
- s = @db.execute sql
62
-
63
- @columns = s.Fields.extend(Enumerable).map {|x| x.Name.to_sym}
64
-
65
- s.moveFirst
66
- s.getRows.transpose.each {|r| yield hash_row(r)}
67
- end
68
- self
69
- end
70
-
71
- def hash_row(row)
72
- @columns.inject({}) do |m, c|
73
- m[c] = row.shift
74
- m
75
- end
76
- end
77
-
78
- def array_tuples_fetch_rows(sql, &block)
79
- @db.synchronize do
80
- s = @db.execute sql
81
-
82
- @columns = s.Fields.extend(Enumerable).map {|x| x.Name.to_sym}
83
-
84
- s.moveFirst
85
- s.getRows.transpose.each {|r| r.keys = @columns; yield r}
86
- end
87
- self
88
- end
89
-
90
- def insert(*values)
91
- @db.do insert_sql(*values)
92
- end
93
-
94
- def update(values, opts = nil)
95
- @db.do update_sql(values, opts)
96
- self
97
- end
98
-
99
- def delete(opts = nil)
100
- @db.do delete_sql(opts)
101
- end
102
- end
103
- end
104
- end
1
+ warn "Requiring 'sequel/ado' is deprecated. Please modify your code to only require 'sequel' instead."
2
+ require File.join(File.dirname(__FILE__), 'adapters/ado')
File without changes
File without changes
File without changes
File without changes
@@ -237,24 +237,6 @@ module Sequel
237
237
  def self.set_adapter_scheme(scheme)
238
238
  @scheme = scheme
239
239
  @@adapters[scheme.to_sym] = self
240
-
241
- # Define convenience method for this database class
242
- db_class = self
243
- Sequel.meta_def(scheme) do |*args|
244
- begin
245
- case args.size
246
- when 1: # Sequel.dbi(db_name)
247
- opts = {:database => args[0]}
248
- when 0 # Sequel.dbi
249
- opts = {}
250
- else # Sequel.dbi(db_name, opts)
251
- opts = args[1].merge(:database => args[0])
252
- end
253
- rescue
254
- raise SequelError, "Invalid parameters specified"
255
- end
256
- db_class.new(opts)
257
- end
258
240
  end
259
241
 
260
242
  # Returns the scheme for the Database class.
@@ -274,6 +256,15 @@ module Sequel
274
256
  }
275
257
  end
276
258
 
259
+ def self.adapter_class(scheme)
260
+ unless c = @@adapters[scheme.to_sym]
261
+ require File.join(File.dirname(__FILE__), "adapters/#{scheme}")
262
+ c = @@adapters[scheme.to_sym]
263
+ end
264
+ raise SequelError, "Invalid database scheme" unless c
265
+ c
266
+ end
267
+
277
268
  # call-seq:
278
269
  # Sequel::Database.connect(conn_string)
279
270
  # Sequel.connect(conn_string)
@@ -287,8 +278,7 @@ module Sequel
287
278
  uri = URI.parse(conn_string)
288
279
  scheme = uri.scheme
289
280
  scheme = :dbi if scheme =~ /^dbi-(.+)/
290
- c = @@adapters[scheme.to_sym]
291
- raise SequelError, "Invalid database scheme" unless c
281
+ c = adapter_class(scheme)
292
282
  c.new(c.uri_to_options(uri).merge(more_opts || {}))
293
283
  end
294
284
 
File without changes
File without changes
File without changes
File without changes
data/lib/sequel/db2.rb CHANGED
@@ -1,160 +1,2 @@
1
- if !Object.const_defined?('Sequel')
2
- require File.join(File.dirname(__FILE__), '../sequel')
3
- end
4
-
5
- require 'db2/db2cli'
6
-
7
- module Sequel
8
- module DB2
9
- class Database < Sequel::Database
10
- set_adapter_scheme :db2
11
- include DB2CLI
12
-
13
- # AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
14
- #
15
- # def auto_increment_sql
16
- # AUTO_INCREMENT
17
- # end
18
-
19
- def check_error(rc, msg)
20
- case rc
21
- when SQL_SUCCESS, SQL_SUCCESS_WITH_INFO: nil
22
- else
23
- raise SequelError, msg
24
- end
25
- end
26
-
27
- rc, @@env = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE)
28
- check_error(rc, "Could not allocate DB2 environment")
29
-
30
- def connect
31
- rc, dbc = SQLAllocHandle(SQL_HANDLE_DBC, @@env)
32
- check_error(rc, "Could not allocate database connection")
33
-
34
- rc = SQLConnect(dbc, @opts[:database], @opts[:user], @opts[:password])
35
- check_error(rc, "Could not connect to database")
36
-
37
- dbc
38
- end
39
-
40
- def disconnect
41
- @pool.disconnect do |conn|
42
- rc = SQLDisconnect(conn)
43
- check_error(rc, "Could not disconnect from database")
44
-
45
- rc = SQLFreeHandle(SQL_HANDLE_DBC, conn)
46
- check_error(rc, "Could not free Database handle")
47
- end
48
- end
49
-
50
- def test_connection
51
- @pool.hold {|conn|}
52
- true
53
- end
54
-
55
- def dataset(opts = nil)
56
- DB2::Dataset.new(self, opts)
57
- end
58
-
59
- def execute(sql, &block)
60
- @logger.info(sql) if @logger
61
- @pool.hold do |conn|
62
- rc, sth = SQLAllocHandle(SQL_HANDLE_STMT, @handle)
63
- check_error(rc, "Could not allocate statement")
64
-
65
- begin
66
- rc = SQLExecDirect(sth, sql)
67
- check_error(rc, "Could not execute statement")
68
-
69
- block[sth] if block
70
-
71
- rc, rpc = SQLRowCount(sth)
72
- check_error(rc, "Could not get RPC")
73
- rpc
74
- ensure
75
- rc = SQLFreeHandle(SQL_HANDLE_STMT, sth)
76
- check_error(rc, "Could not free statement")
77
- end
78
- end
79
- end
80
- alias_method :do, :execute
81
- end
82
-
83
- class Dataset < Sequel::Dataset
84
- def literal(v)
85
- case v
86
- when Time: literal(v.iso8601)
87
- else
88
- super
89
- end
90
- end
91
-
92
- def fetch_rows(sql, &block)
93
- @db.synchronize do
94
- @db.execute(sql) do |sth|
95
- @column_info = get_column_info(sth)
96
- @columns = @column_info.map {|c| c[:name]}
97
- while (rc = SQLFetch(@handle)) != SQL_NO_DATA_FOUND
98
- @db.check_error(rc, "Could not fetch row")
99
- yield hash_row(sth)
100
- end
101
- end
102
- end
103
- self
104
- end
105
-
106
- MAX_COL_SIZE = 256
107
-
108
- def get_column_info(sth)
109
- rc, column_count = SQLNumResultCols(sth)
110
- @db.check_error(rc, "Could not get number of result columns")
111
-
112
- (1..column_count).map do |i|
113
- rc, name, buflen, datatype, size, digits, nullable = SQLDescribeCol(sth, i, MAX_COL_SIZE)
114
- @b.check_error(rc, "Could not describe column")
115
-
116
- {:name => name, :db2_type => datatype, :precision => size}
117
- end
118
- end
119
-
120
- def hash_row(sth)
121
- row = {}
122
- @column_info.each_with_index do |c, i|
123
- rc, v = SQLGetData(sth, i+1, c[:db2_type], c[:precision])
124
- @db.check_error(rc, "Could not get data")
125
-
126
- @row[c[:name]] = convert_type(v)
127
- end
128
- row
129
- end
130
-
131
- def convert_type(v)
132
- case v
133
- when DB2CLI::Date
134
- DBI::Date.new(v.year, v.month, v.day)
135
- when DB2CLI::Time
136
- DBI::Time.new(v.hour, v.minute, v.second)
137
- when DB2CLI::Timestamp
138
- DBI::Timestamp.new(v.year, v.month, v.day,
139
- v.hour, v.minute, v.second, v.fraction)
140
- when DB2CLI::Null
141
- nil
142
- else
143
- v
144
- end
145
- end
146
-
147
- def insert(*values)
148
- @db.do insert_sql(*values)
149
- end
150
-
151
- def update(values, opts = nil)
152
- @db.do update_sql(values, opts)
153
- end
154
-
155
- def delete(opts = nil)
156
- @db.do delete_sql(opts)
157
- end
158
- end
159
- end
160
- end
1
+ warn "Requiring 'sequel/db2' is deprecated. Please modify your code to require 'sequel' instead."
2
+ require File.join(File.dirname(__FILE__), 'adapters/db2')