sequel_core 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/CHANGELOG +1003 -0
  2. data/COPYING +18 -0
  3. data/README +81 -0
  4. data/Rakefile +176 -0
  5. data/bin/sequel +41 -0
  6. data/lib/sequel_core.rb +59 -0
  7. data/lib/sequel_core/adapters/adapter_skeleton.rb +68 -0
  8. data/lib/sequel_core/adapters/ado.rb +100 -0
  9. data/lib/sequel_core/adapters/db2.rb +158 -0
  10. data/lib/sequel_core/adapters/dbi.rb +126 -0
  11. data/lib/sequel_core/adapters/informix.rb +87 -0
  12. data/lib/sequel_core/adapters/jdbc.rb +108 -0
  13. data/lib/sequel_core/adapters/mysql.rb +269 -0
  14. data/lib/sequel_core/adapters/odbc.rb +145 -0
  15. data/lib/sequel_core/adapters/odbc_mssql.rb +93 -0
  16. data/lib/sequel_core/adapters/openbase.rb +90 -0
  17. data/lib/sequel_core/adapters/oracle.rb +99 -0
  18. data/lib/sequel_core/adapters/postgres.rb +519 -0
  19. data/lib/sequel_core/adapters/sqlite.rb +192 -0
  20. data/lib/sequel_core/array_keys.rb +296 -0
  21. data/lib/sequel_core/connection_pool.rb +152 -0
  22. data/lib/sequel_core/core_ext.rb +59 -0
  23. data/lib/sequel_core/core_sql.rb +191 -0
  24. data/lib/sequel_core/database.rb +433 -0
  25. data/lib/sequel_core/dataset.rb +409 -0
  26. data/lib/sequel_core/dataset/convenience.rb +321 -0
  27. data/lib/sequel_core/dataset/sequelizer.rb +354 -0
  28. data/lib/sequel_core/dataset/sql.rb +586 -0
  29. data/lib/sequel_core/exceptions.rb +45 -0
  30. data/lib/sequel_core/migration.rb +191 -0
  31. data/lib/sequel_core/model.rb +8 -0
  32. data/lib/sequel_core/pretty_table.rb +73 -0
  33. data/lib/sequel_core/schema.rb +8 -0
  34. data/lib/sequel_core/schema/schema_generator.rb +131 -0
  35. data/lib/sequel_core/schema/schema_sql.rb +131 -0
  36. data/lib/sequel_core/worker.rb +58 -0
  37. data/spec/adapters/informix_spec.rb +139 -0
  38. data/spec/adapters/mysql_spec.rb +330 -0
  39. data/spec/adapters/oracle_spec.rb +130 -0
  40. data/spec/adapters/postgres_spec.rb +189 -0
  41. data/spec/adapters/sqlite_spec.rb +345 -0
  42. data/spec/array_keys_spec.rb +679 -0
  43. data/spec/connection_pool_spec.rb +356 -0
  44. data/spec/core_ext_spec.rb +67 -0
  45. data/spec/core_sql_spec.rb +301 -0
  46. data/spec/database_spec.rb +812 -0
  47. data/spec/dataset_spec.rb +2381 -0
  48. data/spec/migration_spec.rb +261 -0
  49. data/spec/pretty_table_spec.rb +66 -0
  50. data/spec/rcov.opts +4 -0
  51. data/spec/schema_generator_spec.rb +86 -0
  52. data/spec/schema_spec.rb +230 -0
  53. data/spec/sequelizer_spec.rb +448 -0
  54. data/spec/spec.opts +5 -0
  55. data/spec/spec_helper.rb +44 -0
  56. data/spec/worker_spec.rb +96 -0
  57. metadata +162 -0
@@ -0,0 +1,100 @@
1
+ require 'win32ole'
2
+
3
+ module Sequel
4
+ # The ADO adapter provides connectivity to ADO databases in Windows. ADO
5
+ # databases can be opened using a URL with the ado schema:
6
+ #
7
+ # DB = Sequel.open('ado://mydb')
8
+ #
9
+ # or using the Sequel.ado method:
10
+ #
11
+ # DB = Sequel.ado('mydb')
12
+ #
13
+ module ADO
14
+ class Database < Sequel::Database
15
+ set_adapter_scheme :ado
16
+
17
+ AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
18
+
19
+ def auto_increment_sql
20
+ AUTO_INCREMENT
21
+ end
22
+
23
+ def connect
24
+ dbname = @opts[:database]
25
+ handle = WIN32OLE.new('ADODB.Connection')
26
+ handle.Open(dbname)
27
+ handle
28
+ end
29
+
30
+ def disconnect
31
+ # how do we disconnect? couldn't find anything in the docs
32
+ end
33
+
34
+ def dataset(opts = nil)
35
+ ADO::Dataset.new(self, opts)
36
+ end
37
+
38
+ def execute(sql)
39
+ @logger.info(sql) if @logger
40
+ @pool.hold {|conn| conn.Execute(sql)}
41
+ end
42
+
43
+ alias_method :do, :execute
44
+ end
45
+
46
+ class Dataset < Sequel::Dataset
47
+ def literal(v)
48
+ case v
49
+ when Time
50
+ literal(v.iso8601)
51
+ else
52
+ super
53
+ end
54
+ end
55
+
56
+ def fetch_rows(sql, &block)
57
+ @db.synchronize do
58
+ s = @db.execute sql
59
+
60
+ @columns = s.Fields.extend(Enumerable).map {|x| x.Name.to_sym}
61
+
62
+ s.moveFirst
63
+ s.getRows.transpose.each {|r| yield hash_row(r)}
64
+ end
65
+ self
66
+ end
67
+
68
+ def hash_row(row)
69
+ @columns.inject({}) do |m, c|
70
+ m[c] = row.shift
71
+ m
72
+ end
73
+ end
74
+
75
+ def array_tuples_fetch_rows(sql, &block)
76
+ @db.synchronize do
77
+ s = @db.execute sql
78
+
79
+ @columns = s.Fields.extend(Enumerable).map {|x| x.Name.to_sym}
80
+
81
+ s.moveFirst
82
+ s.getRows.transpose.each {|r| r.keys = @columns; yield r}
83
+ end
84
+ self
85
+ end
86
+
87
+ def insert(*values)
88
+ @db.do insert_sql(*values)
89
+ end
90
+
91
+ def update(*args, &block)
92
+ @db.do update_sql(*args, &block)
93
+ end
94
+
95
+ def delete(opts = nil)
96
+ @db.do delete_sql(opts)
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,158 @@
1
+ require 'db2/db2cli'
2
+
3
+ module Sequel
4
+ module DB2
5
+ class Database < Sequel::Database
6
+ set_adapter_scheme :db2
7
+ include DB2CLI
8
+
9
+ # AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
10
+ #
11
+ # def auto_increment_sql
12
+ # AUTO_INCREMENT
13
+ # end
14
+
15
+ def check_error(rc, msg)
16
+ case rc
17
+ when SQL_SUCCESS, SQL_SUCCESS_WITH_INFO
18
+ nil
19
+ else
20
+ raise Error, msg
21
+ end
22
+ end
23
+
24
+ rc, @@env = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE)
25
+ check_error(rc, "Could not allocate DB2 environment")
26
+
27
+ def connect
28
+ rc, dbc = SQLAllocHandle(SQL_HANDLE_DBC, @@env)
29
+ check_error(rc, "Could not allocate database connection")
30
+
31
+ rc = SQLConnect(dbc, @opts[:database], @opts[:user], @opts[:password])
32
+ check_error(rc, "Could not connect to database")
33
+
34
+ dbc
35
+ end
36
+
37
+ def disconnect
38
+ @pool.disconnect do |conn|
39
+ rc = SQLDisconnect(conn)
40
+ check_error(rc, "Could not disconnect from database")
41
+
42
+ rc = SQLFreeHandle(SQL_HANDLE_DBC, conn)
43
+ check_error(rc, "Could not free Database handle")
44
+ end
45
+ end
46
+
47
+ def test_connection
48
+ @pool.hold {|conn|}
49
+ true
50
+ end
51
+
52
+ def dataset(opts = nil)
53
+ DB2::Dataset.new(self, opts)
54
+ end
55
+
56
+ def execute(sql, &block)
57
+ @logger.info(sql) if @logger
58
+ @pool.hold do |conn|
59
+ rc, sth = SQLAllocHandle(SQL_HANDLE_STMT, @handle)
60
+ check_error(rc, "Could not allocate statement")
61
+
62
+ begin
63
+ rc = SQLExecDirect(sth, sql)
64
+ check_error(rc, "Could not execute statement")
65
+
66
+ block[sth] if block
67
+
68
+ rc, rpc = SQLRowCount(sth)
69
+ check_error(rc, "Could not get RPC")
70
+ rpc
71
+ ensure
72
+ rc = SQLFreeHandle(SQL_HANDLE_STMT, sth)
73
+ check_error(rc, "Could not free statement")
74
+ end
75
+ end
76
+ end
77
+ alias_method :do, :execute
78
+ end
79
+
80
+ class Dataset < Sequel::Dataset
81
+ def literal(v)
82
+ case v
83
+ when Time
84
+ literal(v.iso8601)
85
+ else
86
+ super
87
+ end
88
+ end
89
+
90
+ def fetch_rows(sql, &block)
91
+ @db.synchronize do
92
+ @db.execute(sql) do |sth|
93
+ @column_info = get_column_info(sth)
94
+ @columns = @column_info.map {|c| c[:name]}
95
+ while (rc = SQLFetch(@handle)) != SQL_NO_DATA_FOUND
96
+ @db.check_error(rc, "Could not fetch row")
97
+ yield hash_row(sth)
98
+ end
99
+ end
100
+ end
101
+ self
102
+ end
103
+
104
+ MAX_COL_SIZE = 256
105
+
106
+ def get_column_info(sth)
107
+ rc, column_count = SQLNumResultCols(sth)
108
+ @db.check_error(rc, "Could not get number of result columns")
109
+
110
+ (1..column_count).map do |i|
111
+ rc, name, buflen, datatype, size, digits, nullable = SQLDescribeCol(sth, i, MAX_COL_SIZE)
112
+ @b.check_error(rc, "Could not describe column")
113
+
114
+ {:name => name, :db2_type => datatype, :precision => size}
115
+ end
116
+ end
117
+
118
+ def hash_row(sth)
119
+ row = {}
120
+ @column_info.each_with_index do |c, i|
121
+ rc, v = SQLGetData(sth, i+1, c[:db2_type], c[:precision])
122
+ @db.check_error(rc, "Could not get data")
123
+
124
+ @row[c[:name]] = convert_type(v)
125
+ end
126
+ row
127
+ end
128
+
129
+ def convert_type(v)
130
+ case v
131
+ when DB2CLI::Date
132
+ DBI::Date.new(v.year, v.month, v.day)
133
+ when DB2CLI::Time
134
+ DBI::Time.new(v.hour, v.minute, v.second)
135
+ when DB2CLI::Timestamp
136
+ DBI::Timestamp.new(v.year, v.month, v.day,
137
+ v.hour, v.minute, v.second, v.fraction)
138
+ when DB2CLI::Null
139
+ nil
140
+ else
141
+ v
142
+ end
143
+ end
144
+
145
+ def insert(*values)
146
+ @db.do insert_sql(*values)
147
+ end
148
+
149
+ def update(*args, &block)
150
+ @db.do update_sql(*args, &block)
151
+ end
152
+
153
+ def delete(opts = nil)
154
+ @db.do delete_sql(opts)
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,126 @@
1
+ require 'dbi'
2
+
3
+ module Sequel
4
+ module DBI
5
+ class Database < Sequel::Database
6
+ set_adapter_scheme :dbi
7
+
8
+ DBI_ADAPTERS = {
9
+ :ado => "ADO",
10
+ :db2 => "DB2",
11
+ :frontbase => "FrontBase",
12
+ :interbase => "InterBase",
13
+ :msql => "Msql",
14
+ :mysql => "Mysql",
15
+ :odbc => "ODBC",
16
+ :oracle => "Oracle",
17
+ :pg => "Pg",
18
+ :proxy => "Proxy",
19
+ :sqlite => "SQLite",
20
+ :sqlrelay => "SQLRelay"
21
+ }
22
+
23
+ # Converts a uri to an options hash. These options are then passed
24
+ # to a newly created database object.
25
+ def self.uri_to_options(uri)
26
+ database = (uri.path =~ /\/(.*)/) && ($1)
27
+ if uri.scheme =~ /dbi-(.+)/
28
+ adapter = DBI_ADAPTERS[$1.to_sym] || $1
29
+ database = "#{adapter}:#{database}"
30
+ end
31
+ {
32
+ :user => uri.user,
33
+ :password => uri.password,
34
+ :host => uri.host,
35
+ :port => uri.port,
36
+ :database => database
37
+ }
38
+ end
39
+
40
+
41
+ def connect
42
+ dbname = @opts[:database]
43
+ dbname = 'DBI:' + dbname unless dbname =~ /^DBI:/
44
+ ::DBI.connect(dbname, @opts[:user], @opts[:password])
45
+ end
46
+
47
+ def disconnect
48
+ @pool.disconnect {|c| c.disconnect}
49
+ end
50
+
51
+ def dataset(opts = nil)
52
+ DBI::Dataset.new(self, opts)
53
+ end
54
+
55
+ def execute(sql)
56
+ @logger.info(sql) if @logger
57
+ @pool.hold do |conn|
58
+ conn.execute(sql)
59
+ end
60
+ end
61
+
62
+ def do(sql)
63
+ @logger.info(sql) if @logger
64
+ @pool.hold do |conn|
65
+ conn.do(sql)
66
+ end
67
+ end
68
+ end
69
+
70
+ class Dataset < Sequel::Dataset
71
+ def literal(v)
72
+ case v
73
+ when Time
74
+ literal(v.iso8601)
75
+ else
76
+ super
77
+ end
78
+ end
79
+
80
+ def fetch_rows(sql, &block)
81
+ @db.synchronize do
82
+ s = @db.execute sql
83
+ begin
84
+ @columns = s.column_names.map {|c| c.to_sym}
85
+ s.fetch {|r| yield hash_row(s, r)}
86
+ ensure
87
+ s.finish rescue nil
88
+ end
89
+ end
90
+ self
91
+ end
92
+
93
+ def array_tuples_fetch_rows(sql, &block)
94
+ @db.synchronize do
95
+ s = @db.execute sql
96
+ begin
97
+ @columns = s.column_names.map {|c| c.to_sym}
98
+ s.fetch {|r| r.keys = @columns; yield r}
99
+ ensure
100
+ s.finish rescue nil
101
+ end
102
+ end
103
+ self
104
+ end
105
+
106
+ def hash_row(stmt, row)
107
+ @columns.inject({}) do |m, c|
108
+ m[c] = row.shift
109
+ m
110
+ end
111
+ end
112
+
113
+ def insert(*values)
114
+ @db.do insert_sql(*values)
115
+ end
116
+
117
+ def update(*args, &block)
118
+ @db.do update_sql(*args, &block)
119
+ end
120
+
121
+ def delete(opts = nil)
122
+ @db.do delete_sql(opts)
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,87 @@
1
+ require 'informix'
2
+
3
+ module Sequel
4
+ module Informix
5
+ class Database < Sequel::Database
6
+ set_adapter_scheme :informix
7
+
8
+ # AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
9
+ #
10
+ # def auto_increment_sql
11
+ # AUTO_INCREMENT
12
+ # end
13
+
14
+ def connect
15
+ ::Informix.connect(@opts[:database], @opts[:user], @opts[:password])
16
+ end
17
+
18
+ def disconnect
19
+ @pool.disconnect {|c| c.close}
20
+ end
21
+
22
+ def dataset(opts = nil)
23
+ Sequel::Informix::Dataset.new(self, opts)
24
+ end
25
+
26
+ # Returns number of rows affected
27
+ def execute(sql)
28
+ @logger.info(sql) if @logger
29
+ @pool.hold {|c| c.do(sql)}
30
+ end
31
+ alias_method :do, :execute
32
+
33
+ def query(sql, &block)
34
+ @logger.info(sql) if @logger
35
+ @pool.hold {|c| block[c.cursor(sql)]}
36
+ end
37
+ end
38
+
39
+ class Dataset < Sequel::Dataset
40
+ def literal(v)
41
+ case v
42
+ when Time
43
+ literal(v.iso8601)
44
+ else
45
+ super
46
+ end
47
+ end
48
+
49
+ def select_sql(opts = nil)
50
+ limit = opts.delete(:limit)
51
+ offset = opts.delete(:offset)
52
+ sql = super
53
+ if limit
54
+ limit = "FIRST #{limit}"
55
+ offset = offset ? "SKIP #{offset}" : ""
56
+ sql.sub!(/^select /i,"SELECT #{offset} #{limit} ")
57
+ end
58
+ sql
59
+ end
60
+
61
+ def fetch_rows(sql, &block)
62
+ @db.synchronize do
63
+ @db.query(sql) do |cursor|
64
+ begin
65
+ cursor.open.each_hash {|r| block[r]}
66
+ ensure
67
+ cursor.drop
68
+ end
69
+ end
70
+ end
71
+ self
72
+ end
73
+
74
+ def insert(*values)
75
+ @db.do insert_sql(*values)
76
+ end
77
+
78
+ def update(*args, &block)
79
+ @db.do update_sql(*args, &block)
80
+ end
81
+
82
+ def delete(opts = nil)
83
+ @db.do delete_sql(opts)
84
+ end
85
+ end
86
+ end
87
+ end