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.
- metadata +30 -101
- data/CHANGELOG +0 -1519
- data/COPYING +0 -19
- data/README +0 -313
- data/Rakefile +0 -158
- data/bin/sequel +0 -117
- data/doc/cheat_sheet.rdoc +0 -225
- data/doc/dataset_filtering.rdoc +0 -182
- data/lib/sequel_core.rb +0 -136
- data/lib/sequel_core/adapters/adapter_skeleton.rb +0 -68
- data/lib/sequel_core/adapters/ado.rb +0 -90
- data/lib/sequel_core/adapters/db2.rb +0 -160
- data/lib/sequel_core/adapters/dbi.rb +0 -127
- data/lib/sequel_core/adapters/informix.rb +0 -89
- data/lib/sequel_core/adapters/jdbc.rb +0 -110
- data/lib/sequel_core/adapters/mysql.rb +0 -486
- data/lib/sequel_core/adapters/odbc.rb +0 -167
- data/lib/sequel_core/adapters/odbc_mssql.rb +0 -106
- data/lib/sequel_core/adapters/openbase.rb +0 -76
- data/lib/sequel_core/adapters/oracle.rb +0 -182
- data/lib/sequel_core/adapters/postgres.rb +0 -560
- data/lib/sequel_core/adapters/sqlite.rb +0 -270
- data/lib/sequel_core/connection_pool.rb +0 -194
- data/lib/sequel_core/core_ext.rb +0 -197
- data/lib/sequel_core/core_sql.rb +0 -184
- data/lib/sequel_core/database.rb +0 -462
- data/lib/sequel_core/database/schema.rb +0 -156
- data/lib/sequel_core/dataset.rb +0 -457
- data/lib/sequel_core/dataset/callback.rb +0 -13
- data/lib/sequel_core/dataset/convenience.rb +0 -245
- data/lib/sequel_core/dataset/pagination.rb +0 -96
- data/lib/sequel_core/dataset/query.rb +0 -41
- data/lib/sequel_core/dataset/schema.rb +0 -15
- data/lib/sequel_core/dataset/sql.rb +0 -889
- data/lib/sequel_core/deprecated.rb +0 -26
- data/lib/sequel_core/exceptions.rb +0 -42
- data/lib/sequel_core/migration.rb +0 -187
- data/lib/sequel_core/object_graph.rb +0 -216
- data/lib/sequel_core/pretty_table.rb +0 -71
- data/lib/sequel_core/schema.rb +0 -2
- data/lib/sequel_core/schema/generator.rb +0 -239
- data/lib/sequel_core/schema/sql.rb +0 -326
- data/lib/sequel_core/sql.rb +0 -812
- data/lib/sequel_core/worker.rb +0 -68
- data/spec/adapters/informix_spec.rb +0 -96
- data/spec/adapters/mysql_spec.rb +0 -765
- data/spec/adapters/oracle_spec.rb +0 -222
- data/spec/adapters/postgres_spec.rb +0 -441
- data/spec/adapters/sqlite_spec.rb +0 -413
- data/spec/connection_pool_spec.rb +0 -363
- data/spec/core_ext_spec.rb +0 -156
- data/spec/core_sql_spec.rb +0 -427
- data/spec/database_spec.rb +0 -963
- data/spec/dataset_spec.rb +0 -2933
- data/spec/expression_filters_spec.rb +0 -316
- data/spec/migration_spec.rb +0 -261
- data/spec/object_graph_spec.rb +0 -230
- data/spec/pretty_table_spec.rb +0 -58
- data/spec/rcov.opts +0 -6
- data/spec/schema_generator_spec.rb +0 -122
- data/spec/schema_spec.rb +0 -422
- data/spec/spec.opts +0 -0
- data/spec/spec_config.rb +0 -7
- data/spec/spec_config.rb.example +0 -8
- data/spec/spec_helper.rb +0 -55
- 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
|
data/doc/cheat_sheet.rdoc
DELETED
@@ -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
|
data/doc/dataset_filtering.rdoc
DELETED
@@ -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.
|