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
@@ -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
|