sequel_core 2.2.0 → 3.8.0
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.
- 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
@@ -1,167 +0,0 @@
|
|
1
|
-
require 'odbc'
|
2
|
-
|
3
|
-
module Sequel
|
4
|
-
module ODBC
|
5
|
-
class Database < Sequel::Database
|
6
|
-
set_adapter_scheme :odbc
|
7
|
-
|
8
|
-
# def connect
|
9
|
-
# conn = ::ODBC::connect(@opts[:database], @opts[:user], @opts[:password])
|
10
|
-
# conn.autocommit = true
|
11
|
-
# conn
|
12
|
-
# end
|
13
|
-
|
14
|
-
GUARDED_DRV_NAME = /^\{.+\}$/.freeze
|
15
|
-
DRV_NAME_GUARDS = '{%s}'.freeze
|
16
|
-
|
17
|
-
def connect
|
18
|
-
if @opts.include? :driver
|
19
|
-
drv = ::ODBC::Driver.new
|
20
|
-
drv.name = 'Sequel ODBC Driver130'
|
21
|
-
@opts.each do |param, value|
|
22
|
-
if :driver == param and not (value =~ GUARDED_DRV_NAME)
|
23
|
-
value = DRV_NAME_GUARDS % value
|
24
|
-
end
|
25
|
-
drv.attrs[param.to_s.capitalize] = value
|
26
|
-
end
|
27
|
-
db = ::ODBC::Database.new
|
28
|
-
conn = db.drvconnect(drv)
|
29
|
-
else
|
30
|
-
conn = ::ODBC::connect(@opts[:database], @opts[:user], @opts[:password])
|
31
|
-
end
|
32
|
-
conn.autocommit = true
|
33
|
-
conn
|
34
|
-
end
|
35
|
-
|
36
|
-
def disconnect
|
37
|
-
@pool.disconnect {|c| c.disconnect}
|
38
|
-
end
|
39
|
-
|
40
|
-
def dataset(opts = nil)
|
41
|
-
ODBC::Dataset.new(self, opts)
|
42
|
-
end
|
43
|
-
|
44
|
-
# ODBC returns native statement objects, which must be dropped if
|
45
|
-
# you call execute manually, or you will get warnings. See the
|
46
|
-
# fetch_rows method source code for an example of how to drop
|
47
|
-
# the statements.
|
48
|
-
def execute(sql)
|
49
|
-
log_info(sql)
|
50
|
-
@pool.hold do |conn|
|
51
|
-
conn.run(sql)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def do(sql)
|
56
|
-
log_info(sql)
|
57
|
-
@pool.hold do |conn|
|
58
|
-
conn.do(sql)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
class Dataset < Sequel::Dataset
|
64
|
-
BOOL_TRUE = '1'.freeze
|
65
|
-
BOOL_FALSE = '0'.freeze
|
66
|
-
ODBC_TIMESTAMP_FORMAT = "{ts '%Y-%m-%d %H:%M:%S'}".freeze
|
67
|
-
ODBC_TIMESTAMP_AFTER_SECONDS =
|
68
|
-
ODBC_TIMESTAMP_FORMAT.index( '%S' ).succ - ODBC_TIMESTAMP_FORMAT.length
|
69
|
-
ODBC_DATE_FORMAT = "{d '%Y-%m-%d'}".freeze
|
70
|
-
|
71
|
-
def literal(v)
|
72
|
-
case v
|
73
|
-
when true
|
74
|
-
BOOL_TRUE
|
75
|
-
when false
|
76
|
-
BOOL_FALSE
|
77
|
-
when Time, DateTime
|
78
|
-
formatted = v.strftime(ODBC_TIMESTAMP_FORMAT)
|
79
|
-
usec = (Time === v ? v.usec : (v.sec_fraction * 86400000000))
|
80
|
-
formatted.insert(ODBC_TIMESTAMP_AFTER_SECONDS, ".#{(usec.to_f/1000).round}") if usec >= 1000
|
81
|
-
formatted
|
82
|
-
when Date
|
83
|
-
v.strftime(ODBC_DATE_FORMAT)
|
84
|
-
else
|
85
|
-
super
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
UNTITLED_COLUMN = 'untitled_%d'.freeze
|
90
|
-
|
91
|
-
def fetch_rows(sql, &block)
|
92
|
-
@db.synchronize do
|
93
|
-
s = @db.execute sql
|
94
|
-
begin
|
95
|
-
untitled_count = 0
|
96
|
-
@columns = s.columns(true).map do |c|
|
97
|
-
if (n = c.name).empty?
|
98
|
-
n = UNTITLED_COLUMN % (untitled_count += 1)
|
99
|
-
end
|
100
|
-
n.to_sym
|
101
|
-
end
|
102
|
-
rows = s.fetch_all
|
103
|
-
rows.each {|row| yield hash_row(row)} if rows
|
104
|
-
ensure
|
105
|
-
s.drop unless s.nil? rescue nil
|
106
|
-
end
|
107
|
-
end
|
108
|
-
self
|
109
|
-
end
|
110
|
-
|
111
|
-
# def fetch_rows(sql, &block)
|
112
|
-
# @db.synchronize do
|
113
|
-
# s = @db.execute sql
|
114
|
-
# begin
|
115
|
-
# @columns = s.columns(true).map {|c| c.name.to_sym}
|
116
|
-
# rows = s.fetch_all
|
117
|
-
# rows.each {|row| yield hash_row(row)}
|
118
|
-
# ensure
|
119
|
-
# s.drop unless s.nil? rescue nil
|
120
|
-
# end
|
121
|
-
# end
|
122
|
-
# self
|
123
|
-
# end
|
124
|
-
|
125
|
-
def hash_row(row)
|
126
|
-
hash = {}
|
127
|
-
row.each_with_index do |v, idx|
|
128
|
-
hash[@columns[idx]] = convert_odbc_value(v)
|
129
|
-
end
|
130
|
-
hash
|
131
|
-
end
|
132
|
-
|
133
|
-
def convert_odbc_value(v)
|
134
|
-
# When fetching a result set, the Ruby ODBC driver converts all ODBC
|
135
|
-
# SQL types to an equivalent Ruby type; with the exception of
|
136
|
-
# SQL_TYPE_DATE, SQL_TYPE_TIME and SQL_TYPE_TIMESTAMP.
|
137
|
-
#
|
138
|
-
# The conversions below are consistent with the mappings in
|
139
|
-
# ODBCColumn#mapSqlTypeToGenericType and Column#klass.
|
140
|
-
case v
|
141
|
-
when ::ODBC::TimeStamp
|
142
|
-
DateTime.new(v.year, v.month, v.day, v.hour, v.minute, v.second)
|
143
|
-
when ::ODBC::Time
|
144
|
-
DateTime.now
|
145
|
-
Time.gm(now.year, now.month, now.day, v.hour, v.minute, v.second)
|
146
|
-
when ::ODBC::Date
|
147
|
-
Date.new(v.year, v.month, v.day)
|
148
|
-
else
|
149
|
-
v
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def insert(*values)
|
154
|
-
@db.do insert_sql(*values)
|
155
|
-
end
|
156
|
-
|
157
|
-
def update(*args, &block)
|
158
|
-
@db.do update_sql(*args, &block)
|
159
|
-
self
|
160
|
-
end
|
161
|
-
|
162
|
-
def delete(opts = nil)
|
163
|
-
@db.do delete_sql(opts)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
@@ -1,106 +0,0 @@
|
|
1
|
-
if !Sequel.const_defined?('ODBC')
|
2
|
-
require File.join(File.dirname(__FILE__), 'odbc')
|
3
|
-
end
|
4
|
-
|
5
|
-
module Sequel
|
6
|
-
module ODBC
|
7
|
-
module MSSQL
|
8
|
-
class Database < ODBC::Database
|
9
|
-
set_adapter_scheme :odbc_mssql
|
10
|
-
|
11
|
-
def dataset(opts = nil)
|
12
|
-
MSSQL::Dataset.new(self, opts)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class Dataset < ODBC::Dataset
|
17
|
-
# Allows you to do .nolock on a query
|
18
|
-
def nolock
|
19
|
-
clone(:with => "(NOLOCK)")
|
20
|
-
end
|
21
|
-
|
22
|
-
# Formats a SELECT statement using the given options and the dataset
|
23
|
-
# options.
|
24
|
-
def select_sql(opts = nil)
|
25
|
-
opts = opts ? @opts.merge(opts) : @opts
|
26
|
-
|
27
|
-
if sql = opts[:sql]
|
28
|
-
return sql
|
29
|
-
end
|
30
|
-
|
31
|
-
# ADD TOP to SELECT string for LIMITS
|
32
|
-
if limit = opts[:limit]
|
33
|
-
top = "TOP #{limit} "
|
34
|
-
raise Error, "Offset not supported" if opts[:offset]
|
35
|
-
end
|
36
|
-
|
37
|
-
columns = opts[:select]
|
38
|
-
select_columns = columns ? column_list(columns) : WILDCARD
|
39
|
-
|
40
|
-
if distinct = opts[:distinct]
|
41
|
-
distinct_clause = distinct.empty? ? "DISTINCT" : "DISTINCT ON (#{expression_list(distinct)})"
|
42
|
-
sql = "SELECT #{top}#{distinct_clause} #{select_columns}"
|
43
|
-
else
|
44
|
-
sql = "SELECT #{top}#{select_columns}"
|
45
|
-
end
|
46
|
-
|
47
|
-
if opts[:from]
|
48
|
-
sql << " FROM #{source_list(opts[:from])}"
|
49
|
-
end
|
50
|
-
|
51
|
-
# ADD WITH to SELECT string for NOLOCK
|
52
|
-
if with = opts[:with]
|
53
|
-
sql << " WITH #{with}"
|
54
|
-
end
|
55
|
-
|
56
|
-
if join = opts[:join]
|
57
|
-
join.each{|j| sql << literal(j)}
|
58
|
-
end
|
59
|
-
|
60
|
-
if where = opts[:where]
|
61
|
-
sql << " WHERE #{literal(where)}"
|
62
|
-
end
|
63
|
-
|
64
|
-
if group = opts[:group]
|
65
|
-
sql << " GROUP BY #{expression_list(group)}"
|
66
|
-
end
|
67
|
-
|
68
|
-
if order = opts[:order]
|
69
|
-
sql << " ORDER BY #{expression_list(order)}"
|
70
|
-
end
|
71
|
-
|
72
|
-
if having = opts[:having]
|
73
|
-
sql << " HAVING #{literal(having)}"
|
74
|
-
end
|
75
|
-
|
76
|
-
if union = opts[:union]
|
77
|
-
sql << (opts[:union_all] ? \
|
78
|
-
" UNION ALL #{union.sql}" : " UNION #{union.sql}")
|
79
|
-
elsif intersect = opts[:intersect]
|
80
|
-
sql << (opts[:intersect_all] ? \
|
81
|
-
" INTERSECT ALL #{intersect.sql}" : " INTERSECT #{intersect.sql}")
|
82
|
-
elsif except = opts[:except]
|
83
|
-
sql << (opts[:except_all] ? \
|
84
|
-
" EXCEPT ALL #{except.sql}" : " EXCEPT #{except.sql}")
|
85
|
-
end
|
86
|
-
|
87
|
-
sql
|
88
|
-
end
|
89
|
-
alias_method :sql, :select_sql
|
90
|
-
|
91
|
-
def full_text_search(cols, terms, opts = {})
|
92
|
-
filter("CONTAINS (#{literal(cols)}, #{literal(terms)})")
|
93
|
-
end
|
94
|
-
|
95
|
-
def complex_expression_sql(op, args)
|
96
|
-
case op
|
97
|
-
when :'||'
|
98
|
-
super(:+, args)
|
99
|
-
else
|
100
|
-
super(op, args)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
require 'openbase'
|
2
|
-
|
3
|
-
module Sequel
|
4
|
-
module OpenBase
|
5
|
-
class Database < Sequel::Database
|
6
|
-
set_adapter_scheme :openbase
|
7
|
-
|
8
|
-
def connect
|
9
|
-
OpenBase.new(
|
10
|
-
opts[:database],
|
11
|
-
opts[:host] || 'localhost',
|
12
|
-
opts[:user],
|
13
|
-
opts[:password]
|
14
|
-
)
|
15
|
-
end
|
16
|
-
|
17
|
-
def disconnect
|
18
|
-
# would this work?
|
19
|
-
@pool.disconnect {|c| c.disconnect}
|
20
|
-
end
|
21
|
-
|
22
|
-
def dataset(opts = nil)
|
23
|
-
OpenBase::Dataset.new(self, opts)
|
24
|
-
end
|
25
|
-
|
26
|
-
def execute(sql)
|
27
|
-
log_info(sql)
|
28
|
-
@pool.hold {|conn| conn.execute(sql)}
|
29
|
-
end
|
30
|
-
|
31
|
-
alias_method :do, :execute
|
32
|
-
end
|
33
|
-
|
34
|
-
class Dataset < Sequel::Dataset
|
35
|
-
def literal(v)
|
36
|
-
case v
|
37
|
-
when Time
|
38
|
-
literal(v.iso8601)
|
39
|
-
when Date, DateTime
|
40
|
-
literal(v.to_s)
|
41
|
-
else
|
42
|
-
super
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def fetch_rows(sql, &block)
|
47
|
-
@db.synchronize do
|
48
|
-
result = @db.execute sql
|
49
|
-
begin
|
50
|
-
@columns = result.column_infos.map {|c| c.name.to_sym}
|
51
|
-
result.each do |r|
|
52
|
-
row = {}
|
53
|
-
r.each_with_index {|v, i| row[@columns[i]] = v}
|
54
|
-
yield row
|
55
|
-
end
|
56
|
-
ensure
|
57
|
-
# result.close
|
58
|
-
end
|
59
|
-
end
|
60
|
-
self
|
61
|
-
end
|
62
|
-
|
63
|
-
def insert(*values)
|
64
|
-
@db.do insert_sql(*values)
|
65
|
-
end
|
66
|
-
|
67
|
-
def update(*args, &block)
|
68
|
-
@db.do update_sql(*args, &block)
|
69
|
-
end
|
70
|
-
|
71
|
-
def delete(opts = nil)
|
72
|
-
@db.do delete_sql(opts)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
@@ -1,182 +0,0 @@
|
|
1
|
-
require 'oci8'
|
2
|
-
|
3
|
-
module Sequel
|
4
|
-
module Oracle
|
5
|
-
class Database < Sequel::Database
|
6
|
-
set_adapter_scheme :oracle
|
7
|
-
|
8
|
-
# AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
|
9
|
-
#
|
10
|
-
# def auto_increment_sql
|
11
|
-
# AUTO_INCREMENT
|
12
|
-
# end
|
13
|
-
|
14
|
-
def connect
|
15
|
-
if @opts[:database]
|
16
|
-
dbname = @opts[:host] ? \
|
17
|
-
"//#{@opts[:host]}/#{@opts[:database]}" : @opts[:database]
|
18
|
-
else
|
19
|
-
dbname = @opts[:host]
|
20
|
-
end
|
21
|
-
conn = OCI8.new(@opts[:user], @opts[:password], dbname, @opts[:privilege])
|
22
|
-
conn.autocommit = true
|
23
|
-
conn.non_blocking = true
|
24
|
-
conn
|
25
|
-
end
|
26
|
-
|
27
|
-
def disconnect
|
28
|
-
@pool.disconnect {|c| c.logoff}
|
29
|
-
end
|
30
|
-
|
31
|
-
def dataset(opts = nil)
|
32
|
-
Oracle::Dataset.new(self, opts)
|
33
|
-
end
|
34
|
-
|
35
|
-
def execute(sql)
|
36
|
-
log_info(sql)
|
37
|
-
@pool.hold {|conn| conn.exec(sql)}
|
38
|
-
end
|
39
|
-
|
40
|
-
alias_method :do, :execute
|
41
|
-
|
42
|
-
def tables
|
43
|
-
from(:tab).select(:tname).filter(:tabtype => 'TABLE').map do |r|
|
44
|
-
r[:tname].downcase.to_sym
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def table_exists?(name)
|
49
|
-
from(:tab).filter(:tname => name.to_s.upcase, :tabtype => 'TABLE').count > 0
|
50
|
-
end
|
51
|
-
|
52
|
-
def transaction
|
53
|
-
@pool.hold do |conn|
|
54
|
-
@transactions ||= []
|
55
|
-
if @transactions.include? Thread.current
|
56
|
-
return yield(conn)
|
57
|
-
end
|
58
|
-
|
59
|
-
conn.autocommit = false
|
60
|
-
begin
|
61
|
-
@transactions << Thread.current
|
62
|
-
yield(conn)
|
63
|
-
rescue => e
|
64
|
-
conn.rollback
|
65
|
-
raise e unless Error::Rollback === e
|
66
|
-
ensure
|
67
|
-
conn.commit unless e
|
68
|
-
conn.autocommit = true
|
69
|
-
@transactions.delete(Thread.current)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
class Dataset < Sequel::Dataset
|
76
|
-
def literal(v)
|
77
|
-
case v
|
78
|
-
when OraDate
|
79
|
-
literal(Time.local(*v.to_a))
|
80
|
-
else
|
81
|
-
super
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def fetch_rows(sql, &block)
|
86
|
-
@db.synchronize do
|
87
|
-
cursor = @db.execute sql
|
88
|
-
begin
|
89
|
-
@columns = cursor.get_col_names.map {|c| c.downcase.to_sym}
|
90
|
-
while r = cursor.fetch
|
91
|
-
row = {}
|
92
|
-
r.each_with_index {|v, i| row[columns[i]] = v unless columns[i] == :raw_rnum_}
|
93
|
-
yield row
|
94
|
-
end
|
95
|
-
ensure
|
96
|
-
cursor.close
|
97
|
-
end
|
98
|
-
end
|
99
|
-
self
|
100
|
-
end
|
101
|
-
|
102
|
-
def insert(*values)
|
103
|
-
@db.do insert_sql(*values)
|
104
|
-
end
|
105
|
-
|
106
|
-
def update(*args, &block)
|
107
|
-
@db.do update_sql(*args, &block)
|
108
|
-
end
|
109
|
-
|
110
|
-
def delete(opts = nil)
|
111
|
-
@db.do delete_sql(opts)
|
112
|
-
end
|
113
|
-
|
114
|
-
def empty?
|
115
|
-
db[:dual].where(exists).get(1) == nil
|
116
|
-
end
|
117
|
-
|
118
|
-
# Formats a SELECT statement using the given options and the dataset
|
119
|
-
# options.
|
120
|
-
def select_sql(opts = nil)
|
121
|
-
opts = opts ? @opts.merge(opts) : @opts
|
122
|
-
|
123
|
-
if sql = opts[:sql]
|
124
|
-
return sql
|
125
|
-
end
|
126
|
-
|
127
|
-
columns = opts[:select]
|
128
|
-
select_columns = columns ? column_list(columns) : WILDCARD
|
129
|
-
sql = opts[:distinct] ? \
|
130
|
-
"SELECT DISTINCT #{select_columns}" : \
|
131
|
-
"SELECT #{select_columns}"
|
132
|
-
|
133
|
-
if opts[:from]
|
134
|
-
sql << " FROM #{source_list(opts[:from])}"
|
135
|
-
end
|
136
|
-
|
137
|
-
if join = opts[:join]
|
138
|
-
join.each{|j| sql << literal(j)}
|
139
|
-
end
|
140
|
-
|
141
|
-
if where = opts[:where]
|
142
|
-
sql << " WHERE #{literal(where)}"
|
143
|
-
end
|
144
|
-
|
145
|
-
if group = opts[:group]
|
146
|
-
sql << " GROUP BY #{expression_list(group)}"
|
147
|
-
end
|
148
|
-
|
149
|
-
if having = opts[:having]
|
150
|
-
sql << " HAVING #{literal(having)}"
|
151
|
-
end
|
152
|
-
|
153
|
-
if union = opts[:union]
|
154
|
-
sql << (opts[:union_all] ? \
|
155
|
-
" UNION ALL #{union.sql}" : " UNION #{union.sql}")
|
156
|
-
elsif intersect = opts[:intersect]
|
157
|
-
sql << (opts[:intersect_all] ? \
|
158
|
-
" INTERSECT ALL #{intersect.sql}" : " INTERSECT #{intersect.sql}")
|
159
|
-
elsif except = opts[:except]
|
160
|
-
sql << (opts[:except_all] ? \
|
161
|
-
" EXCEPT ALL #{except.sql}" : " EXCEPT #{except.sql}")
|
162
|
-
end
|
163
|
-
|
164
|
-
if order = opts[:order]
|
165
|
-
sql << " ORDER BY #{expression_list(order)}"
|
166
|
-
end
|
167
|
-
|
168
|
-
if limit = opts[:limit]
|
169
|
-
if (offset = opts[:offset]) && (offset > 0)
|
170
|
-
sql = "SELECT * FROM (SELECT raw_sql_.*, ROWNUM raw_rnum_ FROM(#{sql}) raw_sql_ WHERE ROWNUM <= #{limit + offset}) WHERE raw_rnum_ > #{offset}"
|
171
|
-
else
|
172
|
-
sql = "SELECT * FROM (#{sql}) WHERE ROWNUM <= #{limit}"
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
sql
|
177
|
-
end
|
178
|
-
|
179
|
-
alias sql select_sql
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|