sequel_core 2.2.0 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
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
data/bin/sequel DELETED
@@ -1,117 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- require 'optparse'
5
- require 'sequel_core'
6
-
7
- begin
8
- require 'sequel'
9
- sequel_loaded = true
10
- rescue LoadError
11
- end
12
-
13
- db_opts = {}
14
- echo = nil
15
- env = nil
16
- logfile = nil
17
- migrate_dir = nil
18
- migrate_ver = nil
19
-
20
- opts = OptionParser.new do |opts|
21
- opts.banner = "Sequel: The Database Toolkit for Ruby"
22
- opts.define_head "Usage: sequel <uri|path> [options]"
23
- opts.separator ""
24
- opts.separator "Examples:"
25
- opts.separator " sequel sqlite://blog.db"
26
- opts.separator " sequel postgres://localhost/my_blog"
27
- opts.separator " sequel config/database.yml"
28
- opts.separator ""
29
- opts.separator "For more information see http://sequel.rubyforge.org"
30
- opts.separator ""
31
- opts.separator "Options:"
32
-
33
- opts.on_tail("-?", "--help", "Show this message") do
34
- puts opts
35
- exit
36
- end
37
-
38
- opts.on("-l", "--log logfile", "log SQL statements to log file") do |v|
39
- logfile = v
40
- end
41
-
42
- opts.on("-e", "--env ENV", "use environment config for database") do |v|
43
- env = v
44
- end
45
-
46
- opts.on("-E", "--echo", "echo SQL statements") do
47
- echo = true
48
- end
49
-
50
- opts.on("-m", "--migrate-directory DIR", "run the migrations in directory") do |v|
51
- migrate_dir = v
52
- end
53
-
54
- opts.on("-M", "--migrate-version VER", "migrate the database to version given") do |v|
55
- migrate_ver = Integer(v)
56
- end
57
-
58
- opts.on_tail("-v", "--version", "Show version") do
59
- class << Gem; attr_accessor :loaded_specs; end
60
- begin
61
- specs = Gem.loaded_specs['sequel_core']
62
- puts "sequel_core #{specs.version} (#{specs.date.strftime '%Y-%m-%d'})"
63
- if sequel_loaded
64
- specs = Gem.loaded_specs['sequel']
65
- puts "sequel #{specs.version} (#{specs.date.strftime '%Y-%m-%d'})"
66
- end
67
- rescue
68
- puts "No gem version found"
69
- end
70
- exit
71
- end
72
- end
73
- opts.parse!
74
-
75
- db = ARGV.shift
76
-
77
- if db.blank?
78
- puts opts
79
- exit 1
80
- end
81
-
82
- if logfile || echo
83
- require 'logger'
84
- db_opts[:loggers] = []
85
- db_opts[:loggers] << Logger.new(logfile) if logfile
86
- db_opts[:loggers] << Logger.new($stdout) if echo
87
- end
88
-
89
- if File.exist?(db)
90
- require 'yaml'
91
- db_config = YAML.load_file(db)[env || "development"]
92
- db_config.each {|(k,v)| db_config[k.to_sym] = db_config.delete(k)}
93
- db_config.merge!(db_opts)
94
- end
95
-
96
- begin
97
- if db_config
98
- opts = [db_config]
99
- else
100
- opts = [db, db_opts]
101
- end
102
- DB = Sequel.connect(*opts)
103
- DB.test_connection
104
- if migrate_dir
105
- Sequel::Migrator.apply(DB, migrate_dir, migrate_ver)
106
- exit
107
- end
108
- rescue => e
109
- puts e.message
110
- puts e.backtrace.first
111
- exit 1
112
- end
113
-
114
-
115
- require 'irb'
116
- puts "Your database is stored in DB..."
117
- IRB.start
@@ -1,225 +0,0 @@
1
- = Cheat Sheet
2
-
3
- == Open a database
4
-
5
- require 'rubygems'
6
- require 'sequel'
7
-
8
- DB = Sequel.sqlite 'my_blog.db'
9
- DB = Sequel('postgres://user:password@localhost/my_db')
10
- DB = Sequel.mysql 'my_db', :user => 'user', :password => 'password', :host => 'localhost'
11
- DB = Sequel.ado 'mydb'
12
-
13
- == Open an SQLite memory database
14
-
15
- Without a filename argument, the sqlite adapter will setup a new sqlite database in RAM.
16
-
17
- DB = Sequel.sqlite
18
-
19
- == Logging SQL statements
20
-
21
- require 'logger'
22
- DB = Sequel.sqlite '', :loggers => [Logger.new($stdout)]
23
- # or
24
- DB.loggers << Logger.new(...)
25
-
26
- == Using raw SQL
27
-
28
- DB << "CREATE TABLE users (name VARCHAR(255) NOT NULL, age INT(3) NOT NULL)"
29
- DB.fetch("SELECT name FROM users") do |row|
30
- p r[:name]
31
- end
32
- dataset = DB["SELECT age FROM users"]
33
- dataset.print
34
- dataset.map(:age)
35
-
36
- == Create a dataset
37
-
38
- dataset = DB[:items]
39
- dataset = DB.dataset.from(:items)
40
-
41
- == Most dataset methods are chainable
42
-
43
- dataset = DB[:managers].where(:salary => 5000..10000).order(:name, :department)
44
- # or
45
- dataset = DB.query do
46
- from :managers
47
- where :salary => 5000..10000
48
- order :name, :department
49
- end
50
-
51
- == Insert rows
52
-
53
- dataset.insert(:name => 'Sharon', :grade => 50)
54
- dataset << {:name => 'Sharon', :grade => 50} # same effect as above
55
-
56
- == Retrieve rows
57
-
58
- dataset.each {|r| p r}
59
- dataset.all #=> [{...}, {...}, ...]
60
- dataset.first
61
- dataset.order(:name).last # works only for ordered datasets
62
-
63
- == Update/Delete rows
64
-
65
- dataset.filter(:active => false).delete
66
- dataset.filter('price < ?', 100).update(:active => true)
67
-
68
- == Datasets are Enumerable
69
-
70
- dataset.map {|r| r[:name]}
71
- dataset.map(:name) # same effect as above
72
-
73
- dataset.inject {|sum, r| sum + r[:value]}
74
-
75
- == Filtering (see also doc/dataset_filtering.rdoc)
76
-
77
- dataset.filter(:name => 'abc')
78
- dataset.filter('name = ?', 'abc')
79
- dataset.filter(:value > 100)
80
- dataset.exclude(:value <= 100)
81
-
82
- dataset.filter(:value => 50..100)
83
- dataset.where((:value >= 50) & (:value <= 100))
84
-
85
- dataset.where('value IN ?', [50,75,100])
86
-
87
- # Get the first record that matches a condition
88
- dataset[:name => 'abc'] # Same as:
89
- dataset.filter(:name => 'abc').first
90
-
91
- # Filter using a subquery
92
- dataset.filter('price > ?', dataset.select('AVG(price) + 100'))
93
-
94
- === Advanced filtering using ruby expressions without blocks
95
-
96
- Available as of Sequel 2.0:
97
-
98
- DB[:items].filter(:price < 100).sql
99
- #=> "SELECT * FROM items WHERE (price < 100)"
100
-
101
- DB[:items].filter(:name.like('AL%')).sql
102
- #=> "SELECT * FROM items WHERE (name LIKE 'AL%')"
103
-
104
- There's support for nested expressions with AND, OR and NOT:
105
-
106
- DB[:items].filter((:x > 5) & (:y > 10)).sql
107
- #=> "SELECT * FROM items WHERE ((x > 5) AND (y > 10))"
108
-
109
- DB[:items].filter({:x => 1, :y => 2}.sql_or & ~{:z => 3}).sql
110
- #=> "SELECT * FROM items WHERE (((x = 1) OR (y = 2)) AND (z != 3))"
111
-
112
- You can use arithmetic operators and specify SQL functions:
113
-
114
- DB[:items].filter((:x + :y) > :z).sql
115
- #=> "SELECT * FROM items WHERE ((x + y) > z)"
116
-
117
- DB[:items].filter(:price < :AVG[:price] + 100).sql
118
- #=> "SELECT * FROM items WHERE (price < (AVG(price) + 100))"
119
-
120
- == Ordering
121
-
122
- dataset.order(:kind)
123
- dataset.reverse_order(:kind)
124
- dataset.order(:kind.desc, :name)
125
-
126
- == Row ranges
127
-
128
- dataset.limit(30) # LIMIT 30
129
- dataset.limit(30, 10) # LIMIT 30 OFFSET 10
130
-
131
- == Pagination
132
-
133
- paginated = dataset.paginate(1, 10) # first page, 10 rows per page
134
- paginated.page_count #=> number of pages in dataset
135
- paginated.current_page #=> 1
136
- paginated.next_page #=> next page number or nil
137
- paginated.prev_page #=> previous page number or nil
138
- paginated.first_page? #=> true if page number = 1
139
- paginated.last_page? #=> true if page number = page_count
140
-
141
- == Joins
142
-
143
- DB[:items].left_outer_join(:categories, :id => :category_id).sql #=>
144
- "SELECT * FROM items LEFT OUTER JOIN categories ON categories.id = items.category_id"
145
-
146
- == Summarizing
147
-
148
- dataset.count #=> record count
149
- dataset.max(:price)
150
- dataset.min(:price)
151
- dataset.avg(:price)
152
- dataset.sum(:stock)
153
-
154
- dataset.group(:category).select(:category, :AVG[:price])
155
-
156
- == SQL Functions / Literals
157
-
158
- dataset.update(:updated_at => :NOW[])
159
- dataset.update(:updated_at => 'NOW()'.lit)
160
-
161
- dataset.update(:updated_at => "DateValue('1/1/2001')".lit)
162
- dataset.update(:updated_at => :DateValue['1/1/2001'])
163
-
164
- == Schema Manipulation
165
-
166
- DB.create_table :items do
167
- primary_key :id
168
- text :name, :unique => true, :null => false
169
- boolean :active, :default => true
170
- foreign_key :category_id, :categories
171
-
172
- index :grade
173
- end
174
-
175
- DB.drop_table :items
176
-
177
- DB.create_table :test do
178
- varchar :zipcode, :size => 10
179
- enum :system, :elements => ['mac', 'linux', 'windows']
180
- end
181
-
182
- == Aliasing
183
-
184
- DB[:items].select(:name.as(:item_name))
185
- DB[:items].select(:name => :item_name)
186
- DB[:items].select(:name___item_name)
187
- DB[:items___items_table].select(:items_table__name___item_name)
188
- # => "SELECT items_table.name AS item_name FROM items AS items_table"
189
-
190
- == Transactions
191
-
192
- DB.transaction do
193
- dataset << {:first_name => 'Inigo', :last_name => 'Montoya'}
194
- dataset << {:first_name => 'Farm', :last_name => 'Boy'}
195
- end # Either both are inserted or neither are inserted
196
-
197
- Database#transaction is re-entrant:
198
-
199
- DB.transaction do # BEGIN issued only here
200
- DB.transaction
201
- dataset << {:first_name => 'Inigo', :last_name => 'Montoya'}
202
- end
203
- end # COMMIT issued only here
204
-
205
- Transactions are aborted if an error is raised:
206
-
207
- DB.transaction do
208
- raise "some error occurred"
209
- end # ROLLBACK issued and the error is re-raised
210
-
211
- Transactions can also be aborted by raising Sequel::Error::Rollback:
212
-
213
- DB.transaction do
214
- raise(Sequel::Error::Rollback) if something_bad_happened
215
- end # ROLLBACK issued and no error raised
216
-
217
- Miscellaneous:
218
-
219
- dataset.sql #=> "SELECT * FROM items"
220
- dataset.delete_sql #=> "DELETE FROM items"
221
- dataset.where(:name => 'sequel').exists #=> "EXISTS ( SELECT 1 FROM items WHERE name = 'sequel' )"
222
- dataset.print #=> pretty table print to $stdout
223
- dataset.columns #=> array of columns in the result set, does a SELECT
224
- DB.schema_for_table(:items) => [[:id, {:type=>:integer, ...}], [:name, {:type=>:string, ...}], ...]
225
- # Works on PostgreSQL, MySQL, SQLite, and possibly elsewhere
@@ -1,182 +0,0 @@
1
- = Dataset Filtering
2
-
3
- Sequel offers unparalleled flexibility when it comes to filtering records. You can specify your conditions as a custom string, as a string with parameters, as a hash of values to compare against, or as ruby code that Sequel translates into SQL expressions.
4
-
5
- == Filtering using a custom filter string
6
-
7
- If you do not wish to lose control over your SQL WHERE clauses, you can just supply it to the dataset's #filter method:
8
-
9
- items.filter('x < 10').sql
10
- #=> "SELECT * FROM items WHERE x < 10"
11
-
12
- In order to prevent SQL injection, you can replace literal values with question marks and supply the values as additional arguments:
13
-
14
- items.filter('category = ?', 'ruby').sql
15
- #=> "SELECT * FROM items WHERE category = 'ruby'"
16
-
17
- == An aside: column references in Sequel
18
-
19
- Sequel expects column names to be specified using symbols. In addition, tuples always use symbols as their keys. This allows you to freely mix literal values and column references. For example, the two following lines produce equivalent SQL:
20
-
21
- items.filter(:x => 1) #=> "SELECT * FROM items WHERE (x = 1)"
22
- items.filter(1 => :x) #=> "SELECT * FROM items WHERE (1 = x)"
23
-
24
- === Qualifying column names
25
-
26
- Column references can be qualified by using the double underscore special notation :table__column:
27
-
28
- items.literal(:items__price) #=> "items.price"
29
-
30
- === Column aliases
31
-
32
- You can also alias columns by using the triple undersecore special notation :column___alias or :table__column___alias:
33
-
34
- items.literal(:price___p) #=> "price AS p"
35
- items.literal(:items__price___p) #=> "items.price AS p"
36
-
37
- Another way to alias columns is to use the #AS method:
38
-
39
- items.literal(:price.as(:p)) #=> "price AS p"
40
-
41
- === Specifying SQL functions
42
-
43
- Sequel also allows you to specify functions by using the Symbol#[] method:
44
-
45
- items.literal(:avg[:price]) #=> "avg(price)"
46
-
47
- == Filtering using a hash
48
-
49
- If you just need to compare records against values, you can supply a hash:
50
-
51
- items.filter(:category => 'ruby').sql
52
- #=> "SELECT * FROM items WHERE (category = 'ruby')"
53
-
54
- Sequel can check for null values:
55
-
56
- items.filter(:category => nil).sql
57
- #=> "SELECT * FROM items WHERE (category IS NULL)"
58
-
59
- Or compare two columns:
60
-
61
- items.filter(:x => :some_table__y).sql
62
- #=> "SELECT * FROM items WHERE (x = some_table.y)"
63
-
64
- And also compare against multiple values:
65
-
66
- items.filter(:category => ['ruby', 'perl']).sql
67
- #=> "SELECT * FROM items WHERE (category IN ('ruby', 'perl'))"
68
-
69
- Ranges (both inclusive and exclusive) can also be used:
70
-
71
- items.filter(:price => 100..200).sql
72
- #=> "SELECT * FROM items WHERE (price >= 100 AND price <= 200)"
73
-
74
- items.filter(:price => 100...200).sql
75
- #=> "SELECT * FROM items WHERE (price >= 100 AND price < 200)"
76
-
77
- == Filtering using expressions
78
-
79
- New in Sequel 2.0 is the ability to use ruby expressions directly in the call to filter, without using a block:
80
-
81
- items.filter(:price < 100).sql
82
- #=> "SELECT * FROM items WHERE (price < 100)
83
-
84
- This works for the standard inequality and arithmetic operators:
85
-
86
- items.filter(:price + 100 < 200).sql
87
- #=> "SELECT * FROM items WHERE ((price + 100) < 200)
88
-
89
- items.filter(:price - 100 > 200).sql
90
- #=> "SELECT * FROM items WHERE ((price - 100) > 200)
91
-
92
- items.filter(:price * 100 <= 200).sql
93
- #=> "SELECT * FROM items WHERE ((price * 100) <= 200)
94
-
95
- items.filter(:price / 100 >= 200).sql
96
- #=> "SELECT * FROM items WHERE ((price / 100) >= 200)
97
-
98
- You use the overloaded bitwise and (&) and or (|) operators to combine expressions:
99
-
100
- items.filter((:price + 100 < 200) & (:price * 100 <= 200)).sql
101
- #=> "SELECT * FROM items WHERE (((price + 100) < 200) AND ((price * 100) <= 200))
102
-
103
- items.filter((:price - 100 > 200) | (:price / 100 >= 200)).sql
104
- #=> "SELECT * FROM items WHERE (((price - 100) > 200) OR ((price / 100) >= 200))
105
-
106
- To filter by equality, you use the standard hash, which can be combined with other operators:
107
-
108
- items.filter({:category => 'ruby'} & (:price + 100 < 200)).sql
109
- #=> "SELECT * FROM items WHERE ((category = 'ruby') AND ((price + 100) < 200))"
110
-
111
- This works with other hash values, such as arrays and ranges:
112
-
113
- items.filter({:category => ['ruby', 'other']} | (:price - 100 > 200)).sql
114
- #=> "SELECT * FROM items WHERE ((category IN ('ruby', 'other')) OR ((price - 100) <= 200))"
115
-
116
- items.filter({:price => (100..200)} & :active).sql
117
- #=> "SELECT * FROM items WHERE ((price >= 100 AND price <= 200) AND active)"
118
-
119
- === Negating conditions
120
-
121
- You can use the negation operator (~) in most cases:
122
-
123
- items.filter(~{:category => 'ruby'}).sql
124
- #=> "SELECT * FROM items WHERE (category != 'ruby')"
125
-
126
- items.filter {~:active}.sql
127
- #=> "SELECT * FROM items WHERE NOT active"
128
-
129
- items.filter(~(:price / 100 >= 200)).sql
130
- #=> "SELECT * FROM items WHERE ((price / 100) < 200)
131
-
132
- === Comparing against column references
133
-
134
- You can also compare against other columns:
135
-
136
- items.filter(:credit > :debit).sql
137
- #=> "SELECT * FROM items WHERE (credit > debit)
138
-
139
- Or against SQL functions:
140
-
141
- items.filter(:price < :max[:price] + 100).sql
142
- #=> "SELECT * FROM items WHERE (price < (max(price) + 100))"
143
-
144
- == String search functions
145
-
146
- You can search SQL strings using the #like method:
147
-
148
- items.filter(:name.like('Acme%')).sql
149
- #=> "SELECT * FROM items WHERE (name LIKE 'Acme%')"
150
-
151
- You can specify a Regexp as a like argument, but this will probably only work
152
- on PostgreSQL and MySQL:
153
-
154
- items.filter(:name.like(/Acme.*/)).sql
155
- #=> "SELECT * FROM items WHERE (name ~ 'Acme.*')"
156
-
157
- Like can also take more than one argument:
158
-
159
- items.filter(:name.like('Acme%', /Beta.*/)).sql
160
- #=> "SELECT * FROM items WHERE ((name LIKE 'Acme%') OR (name ~ 'Beta.*'))"
161
-
162
- == String concatenation
163
-
164
- You can concatenate SQL strings using Array#sql_string_join:
165
-
166
- items.filter([:name, :comment].sql_string_join.like('%acme%')).sql
167
- #=> "SELECT * FROM items WHERE ((name || comment) LIKE 'Acme%')"
168
-
169
- Array#sql_string_join also takes a join argument:
170
-
171
- items.filter([:name, :comment].sql_string_join(' ').like('%acme%')).sql
172
- #=> "SELECT * FROM items WHERE ((name || ' ' || comment) LIKE 'Acme%')"
173
-
174
- == Filtering using sub-queries
175
-
176
- One of the best features of Sequel is the ability to use datasets as sub-queries. Sub-queries can be very useful for filtering records, and many times provide a simpler alternative to table joins. Sub-queries can be used in all forms of filters:
177
-
178
- refs = consumer_refs.filter(:logged_in => true).select(:consumer_id)
179
- consumers.filter(:id => refs).sql
180
- #=> "SELECT * FROM consumers WHERE (id IN (SELECT consumer_id FROM consumer_refs WHERE (logged_in = 't')))"
181
-
182
- Note that if you compare against a sub-query, you must select a single column in the sub-query.