sequel 0.4.0 → 0.4.1

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