simple-sql 0.5.4 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/simple/sql.rb +1 -1
- data/lib/simple/sql/connection.rb +1 -0
- data/lib/simple/sql/{scope.rb → connection/scope.rb} +23 -14
- data/lib/simple/sql/connection/scope/count.rb +35 -0
- data/lib/simple/sql/{scope → connection/scope}/count_by_groups.rb +8 -8
- data/lib/simple/sql/{scope → connection/scope}/filters.rb +1 -1
- data/lib/simple/sql/{scope → connection/scope}/order.rb +1 -1
- data/lib/simple/sql/{scope → connection/scope}/pagination.rb +1 -1
- data/lib/simple/sql/connection_adapter.rb +3 -3
- data/lib/simple/sql/result/association_loader.rb +7 -7
- data/lib/simple/sql/scope/count.rb +6 -4
- data/lib/simple/sql/version.rb +1 -1
- data/spec/simple/sql/count_by_groups_spec.rb +2 -2
- data/spec/simple/sql/count_spec.rb +2 -2
- data/spec/simple/sql/result_count_spec.rb +2 -2
- data/spec/simple/sql/scope_spec.rb +17 -17
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ddf6a7cc39facc48d8f9ec3f14d94dc614261d23617f44ea2b604f06b94ae90b
|
4
|
+
data.tar.gz: f8eb847b80866ae0001c2517e11764a86f12bd6f4b0a3a33f489b37a78919484
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4632a04f05ff2d698b3c925ef63a2267b6bd0d57145d94b94a2010d439193fb1e9ab8eeaa0dd55d1b2bc3b74a2398117fb2648058eda3470d96b27b9cf7ac203
|
7
|
+
data.tar.gz: 67262d0c42c46142d919455fecafc4f3a24a0a375008d1d6f318934ce876e7ecdedaf29c5c6c87757d06fcb0a0467bd2f93cc5cdc4882af4ed0955ece13fcb95
|
data/lib/simple/sql.rb
CHANGED
@@ -8,7 +8,6 @@ require_relative "sql/helpers"
|
|
8
8
|
require_relative "sql/result"
|
9
9
|
require_relative "sql/config"
|
10
10
|
require_relative "sql/logging"
|
11
|
-
require_relative "sql/scope"
|
12
11
|
require_relative "sql/connection_adapter"
|
13
12
|
require_relative "sql/connection"
|
14
13
|
|
@@ -22,6 +21,7 @@ module Simple
|
|
22
21
|
delegate [:reflection] => :default_connection
|
23
22
|
delegate [:duplicate] => :default_connection
|
24
23
|
delegate [:insert] => :default_connection
|
24
|
+
delegate [:scope] => :default_connection
|
25
25
|
|
26
26
|
delegate [:logger, :logger=] => ::Simple::SQL::Logging
|
27
27
|
|
@@ -4,6 +4,7 @@ end
|
|
4
4
|
require_relative "connection/raw_connection"
|
5
5
|
require_relative "connection/active_record_connection"
|
6
6
|
|
7
|
+
require_relative "connection/scope"
|
7
8
|
require_relative "connection/reflection"
|
8
9
|
require_relative "connection/insert"
|
9
10
|
require_relative "connection/duplicate"
|
@@ -6,29 +6,38 @@ require_relative "scope/pagination.rb"
|
|
6
6
|
require_relative "scope/count.rb"
|
7
7
|
require_relative "scope/count_by_groups.rb"
|
8
8
|
|
9
|
-
|
10
|
-
# that start as a quite basic SQL query, and allow one to add
|
11
|
-
# sql_fragments as where conditions.
|
12
|
-
class Simple::SQL::Scope
|
13
|
-
SELF = self
|
14
|
-
|
15
|
-
attr_reader :args
|
16
|
-
attr_reader :per, :page
|
17
|
-
|
9
|
+
class Simple::SQL::Connection
|
18
10
|
# Build a scope object
|
19
11
|
#
|
20
12
|
# This call supports a few variants:
|
21
13
|
#
|
22
|
-
# Simple::SQL
|
23
|
-
# Simple::SQL
|
14
|
+
# Simple::SQL.scope("SELECT * FROM mytable")
|
15
|
+
# Simple::SQL.scope(table: "mytable", select: "*")
|
24
16
|
#
|
25
17
|
# The second option also allows one to pass in more options, like the following:
|
26
18
|
#
|
27
|
-
# Simple::SQL
|
19
|
+
# Simple::SQL.scope(table: "mytable", select: "*", where: { id: 1, foo: "bar" }, order_by: "id desc")
|
28
20
|
#
|
29
|
-
def
|
21
|
+
def scope(sql, args = [])
|
22
|
+
::Simple::SQL::Connection::Scope.new sql, args, connection: self
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# The Simple::SQL::Connection::Scope class helps building scopes; i.e. objects
|
27
|
+
# that start as a quite basic SQL query, and allow one to add
|
28
|
+
# sql_fragments as where conditions.
|
29
|
+
class Simple::SQL::Connection::Scope
|
30
|
+
SELF = self
|
31
|
+
|
32
|
+
attr_reader :connection
|
33
|
+
attr_reader :args
|
34
|
+
attr_reader :per, :page
|
35
|
+
|
36
|
+
def initialize(sql, args = [], connection:) # :nodoc:
|
30
37
|
expect! sql => [String, Hash]
|
31
38
|
|
39
|
+
@connection = connection
|
40
|
+
|
32
41
|
@sql = nil
|
33
42
|
@args = args
|
34
43
|
@filters = []
|
@@ -62,7 +71,7 @@ class Simple::SQL::Scope
|
|
62
71
|
end
|
63
72
|
|
64
73
|
def duplicate
|
65
|
-
dupe = SELF.new(@sql)
|
74
|
+
dupe = SELF.new(@sql, connection: @connection)
|
66
75
|
dupe.instance_variable_set :@args, @args.dup
|
67
76
|
dupe.instance_variable_set :@filters, @filters.dup
|
68
77
|
dupe.instance_variable_set :@per, @per
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Simple::SQL::Connection::Scope
|
2
|
+
EXACT_COUNT_THRESHOLD = 10_000
|
3
|
+
|
4
|
+
# Returns the exact count of matching records
|
5
|
+
def count
|
6
|
+
sql = order_by(nil).to_sql(pagination: false)
|
7
|
+
|
8
|
+
@connection.ask("SELECT COUNT(*) FROM (#{sql}) _total_count", *args)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns the fast count of matching records
|
12
|
+
#
|
13
|
+
# For counts larger than EXACT_COUNT_THRESHOLD this returns an estimate
|
14
|
+
def fast_count
|
15
|
+
estimate = estimated_count
|
16
|
+
return estimate if estimate > EXACT_COUNT_THRESHOLD
|
17
|
+
|
18
|
+
sql = order_by(nil).to_sql(pagination: false)
|
19
|
+
@connection.ask("SELECT COUNT(*) FROM (#{sql}) _total_count", *args)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def estimated_count
|
25
|
+
sql = order_by(nil).to_sql(pagination: false)
|
26
|
+
lines = @connection.all("EXPLAIN #{sql}", *args)
|
27
|
+
lines.each do |line|
|
28
|
+
next unless line =~ /\brows=(\d+)/
|
29
|
+
|
30
|
+
return Integer($1)
|
31
|
+
end
|
32
|
+
|
33
|
+
-1
|
34
|
+
end
|
35
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# rubocop:disable Metrics/AbcSize
|
2
2
|
# rubocop:disable Metrics/MethodLength
|
3
3
|
|
4
|
-
class Simple::SQL::Scope
|
4
|
+
class Simple::SQL::Connection::Scope
|
5
5
|
# Potentially fast implementation of returning all different values for a specific group.
|
6
6
|
#
|
7
7
|
# For example:
|
@@ -20,16 +20,16 @@ class Simple::SQL::Scope
|
|
20
20
|
def enumerate_groups(sql_fragment)
|
21
21
|
sql = order_by(nil).to_sql(pagination: false)
|
22
22
|
|
23
|
-
_, max_cost =
|
23
|
+
_, max_cost = @connection.costs "SELECT MIN(#{sql_fragment}) FROM (#{sql}) sq", *args
|
24
24
|
raise "enumerate_groups: takes too much time. Make sure to create a suitable index" if max_cost > 10_000
|
25
25
|
|
26
26
|
groups = []
|
27
27
|
var_name = "$#{@args.count + 1}"
|
28
|
-
cur =
|
28
|
+
cur = @connection.ask "SELECT MIN(#{sql_fragment}) FROM (#{sql}) sq", *args
|
29
29
|
|
30
30
|
while cur
|
31
31
|
groups << cur
|
32
|
-
cur =
|
32
|
+
cur = @connection.ask "SELECT MIN(#{sql_fragment}) FROM (#{sql}) sq"" WHERE #{sql_fragment} > #{var_name}", *args, cur
|
33
33
|
end
|
34
34
|
|
35
35
|
groups
|
@@ -38,14 +38,14 @@ class Simple::SQL::Scope
|
|
38
38
|
def count_by(sql_fragment)
|
39
39
|
sql = order_by(nil).to_sql(pagination: false)
|
40
40
|
|
41
|
-
recs =
|
41
|
+
recs = @connection.all "SELECT #{sql_fragment} AS group, COUNT(*) AS count FROM (#{sql}) sq GROUP BY #{sql_fragment}", *args
|
42
42
|
Hash[recs]
|
43
43
|
end
|
44
44
|
|
45
45
|
def fast_count_by(sql_fragment)
|
46
46
|
sql = order_by(nil).to_sql(pagination: false)
|
47
47
|
|
48
|
-
_, max_cost =
|
48
|
+
_, max_cost = @connection.costs "SELECT COUNT(*) FROM (#{sql}) sq GROUP BY #{sql_fragment}", *args
|
49
49
|
|
50
50
|
return count_by(sql_fragment) if max_cost < 10_000
|
51
51
|
|
@@ -57,14 +57,14 @@ class Simple::SQL::Scope
|
|
57
57
|
counts = {}
|
58
58
|
sparse_groups = []
|
59
59
|
enumerate_groups(sql_fragment).each do |group|
|
60
|
-
scope =
|
60
|
+
scope = @connection.scope("SELECT * FROM (#{sql}) sq WHERE #{sql_fragment}=#{var_name}", *args, group)
|
61
61
|
counts[group] = scope.send(:estimated_count)
|
62
62
|
sparse_groups << group if estimated_count < EXACT_COUNT_THRESHOLD
|
63
63
|
end
|
64
64
|
|
65
65
|
# fetch exact counts in all sparse_groups
|
66
66
|
unless sparse_groups.empty?
|
67
|
-
sparse_counts =
|
67
|
+
sparse_counts = @connection.all <<~SQL, *args, sparse_groups
|
68
68
|
SELECT #{sql_fragment} AS group, COUNT(*) AS count
|
69
69
|
FROM (#{sql}) sq
|
70
70
|
WHERE #{sql_fragment} = ANY(#{var_name})
|
@@ -6,7 +6,6 @@
|
|
6
6
|
|
7
7
|
module Simple::SQL::ConnectionAdapter
|
8
8
|
Logging = ::Simple::SQL::Logging
|
9
|
-
Scope = ::Simple::SQL::Scope
|
10
9
|
|
11
10
|
# execute one or more sql statements. This method does not allow to pass in
|
12
11
|
# arguments - since the pg client does not support this - but it allows to
|
@@ -47,7 +46,7 @@ module Simple::SQL::ConnectionAdapter
|
|
47
46
|
# [TODO] - resolve associations. Note that this is only possible if the type
|
48
47
|
# is not an Array (i.e. into is nil)
|
49
48
|
|
50
|
-
if sql.is_a?(Scope) && sql.paginated?
|
49
|
+
if sql.is_a?(::Simple::SQL::Connection::Scope) && sql.paginated?
|
51
50
|
record_set.send(:set_pagination_info, sql)
|
52
51
|
end
|
53
52
|
|
@@ -120,8 +119,9 @@ module Simple::SQL::ConnectionAdapter
|
|
120
119
|
Encoder = ::Simple::SQL::Helpers::Encoder
|
121
120
|
|
122
121
|
def exec_logged(sql_or_scope, *args)
|
123
|
-
if sql_or_scope.is_a?(Scope)
|
122
|
+
if sql_or_scope.is_a?(::Simple::SQL::Connection::Scope)
|
124
123
|
raise ArgumentError, "You cannot call .all with a scope and additional arguments" unless args.empty?
|
124
|
+
raise ArgumentError, "You cannot execute a scope on a different connection" unless self == sql_or_scope.connection
|
125
125
|
|
126
126
|
sql = sql_or_scope.to_sql
|
127
127
|
args = sql_or_scope.args
|
@@ -86,16 +86,16 @@ module ::Simple::SQL::Result::AssociationLoader # :nodoc:
|
|
86
86
|
end
|
87
87
|
|
88
88
|
# preloads a belongs_to association.
|
89
|
-
def preload_belongs_to(records, relation, as:)
|
89
|
+
def preload_belongs_to(connection, records, relation, as:)
|
90
90
|
belonging_column = relation.belonging_column.to_sym
|
91
91
|
having_column = relation.having_column.to_sym
|
92
92
|
|
93
93
|
foreign_ids = H.pluck(records, belonging_column).uniq.compact
|
94
94
|
|
95
|
-
scope =
|
95
|
+
scope = connection.scope(table: relation.having_table)
|
96
96
|
scope = scope.where(having_column => foreign_ids)
|
97
97
|
|
98
|
-
recs =
|
98
|
+
recs = connection.all(scope, into: Hash)
|
99
99
|
recs_by_id = H.by_key(recs, having_column)
|
100
100
|
|
101
101
|
records.each do |model|
|
@@ -104,7 +104,7 @@ module ::Simple::SQL::Result::AssociationLoader # :nodoc:
|
|
104
104
|
end
|
105
105
|
|
106
106
|
# preloads a has_one or has_many association.
|
107
|
-
def preload_has_one_or_many(records, relation, as:, order_by:, limit:)
|
107
|
+
def preload_has_one_or_many(connection, records, relation, as:, order_by:, limit:)
|
108
108
|
# To really make sense limit must be implemented using window
|
109
109
|
# functions, because one (or, at lieast, I) would expect this code
|
110
110
|
#
|
@@ -121,7 +121,7 @@ module ::Simple::SQL::Result::AssociationLoader # :nodoc:
|
|
121
121
|
|
122
122
|
host_ids = H.pluck(records, having_column).uniq.compact
|
123
123
|
|
124
|
-
scope =
|
124
|
+
scope = connection.scope(table: relation.belonging_table)
|
125
125
|
scope = scope.where(belonging_column => host_ids)
|
126
126
|
scope = scope.order_by(order_by) if order_by
|
127
127
|
|
@@ -165,9 +165,9 @@ module ::Simple::SQL::Result::AssociationLoader # :nodoc:
|
|
165
165
|
raise ArgumentError, "#{association.inspect} is a singular association, w/o support for order_by: and limit:"
|
166
166
|
end
|
167
167
|
|
168
|
-
preload_belongs_to records, relation, as: as
|
168
|
+
preload_belongs_to connection, records, relation, as: as
|
169
169
|
else
|
170
|
-
preload_has_one_or_many records, relation, as: as, order_by: order_by, limit: limit
|
170
|
+
preload_has_one_or_many connection, records, relation, as: as, order_by: order_by, limit: limit
|
171
171
|
end
|
172
172
|
end
|
173
173
|
end
|
@@ -1,10 +1,11 @@
|
|
1
|
-
class Simple::SQL::Scope
|
1
|
+
class Simple::SQL::Connection::Scope
|
2
2
|
EXACT_COUNT_THRESHOLD = 10_000
|
3
3
|
|
4
4
|
# Returns the exact count of matching records
|
5
5
|
def count
|
6
6
|
sql = order_by(nil).to_sql(pagination: false)
|
7
|
-
|
7
|
+
|
8
|
+
@connection.ask("SELECT COUNT(*) FROM (#{sql}) _total_count", *args)
|
8
9
|
end
|
9
10
|
|
10
11
|
# Returns the fast count of matching records
|
@@ -15,14 +16,15 @@ class Simple::SQL::Scope
|
|
15
16
|
return estimate if estimate > EXACT_COUNT_THRESHOLD
|
16
17
|
|
17
18
|
sql = order_by(nil).to_sql(pagination: false)
|
18
|
-
|
19
|
+
@connection.ask("SELECT COUNT(*) FROM (#{sql}) _total_count", *args)
|
19
20
|
end
|
20
21
|
|
21
22
|
private
|
22
23
|
|
23
24
|
def estimated_count
|
24
25
|
sql = order_by(nil).to_sql(pagination: false)
|
25
|
-
|
26
|
+
lines = @connection.all("EXPLAIN #{sql}", *args)
|
27
|
+
lines.each do |line|
|
26
28
|
next unless line =~ /\brows=(\d+)/
|
27
29
|
|
28
30
|
return Integer($1)
|
data/lib/simple/sql/version.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe "Simple::SQL::Scope#count_by" do
|
3
|
+
describe "Simple::SQL::Connection::Scope#count_by" do
|
4
4
|
let!(:users) { 1.upto(10).map { |i| create(:user, role_id: i) } }
|
5
5
|
let(:all_role_ids) { SQL.all("SELECT DISTINCT role_id FROM users") }
|
6
|
-
let(:scope) { SQL
|
6
|
+
let(:scope) { SQL.scope("SELECT * FROM users") }
|
7
7
|
|
8
8
|
describe "enumerate_groups" do
|
9
9
|
it "returns all groups" do
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe "Simple::SQL::Scope#count" do
|
3
|
+
describe "Simple::SQL::Connection::Scope#count" do
|
4
4
|
let!(:users) { 1.upto(USER_COUNT).map { create(:user) } }
|
5
5
|
let(:min_user_id) { SQL.ask "SELECT min(id) FROM users" }
|
6
|
-
let(:scope) { SQL
|
6
|
+
let(:scope) { SQL.scope("SELECT * FROM users") }
|
7
7
|
|
8
8
|
describe "exact count" do
|
9
9
|
it "counts" do
|
@@ -3,7 +3,7 @@ require "spec_helper"
|
|
3
3
|
describe "Simple::SQL::Result counts" do
|
4
4
|
let!(:users) { 1.upto(USER_COUNT).map { create(:user) } }
|
5
5
|
let(:min_user_id) { SQL.ask "SELECT min(id) FROM users" }
|
6
|
-
let(:scope) { SQL
|
6
|
+
let(:scope) { SQL.scope("SELECT * FROM users") }
|
7
7
|
let(:paginated_scope) { scope.paginate(per: 1, page: 1) }
|
8
8
|
|
9
9
|
describe "exact counting" do
|
@@ -39,7 +39,7 @@ describe "Simple::SQL::Result counts" do
|
|
39
39
|
|
40
40
|
|
41
41
|
context 'when running with an empty, paginated paginated_scope' do
|
42
|
-
let(:scope) { SQL
|
42
|
+
let(:scope) { SQL.scope("SELECT * FROM users WHERE FALSE") }
|
43
43
|
let(:paginated_scope) { scope.paginate(per: 1, page: 1) }
|
44
44
|
|
45
45
|
it "returns correct results" do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe "Simple::SQL::Scope" do
|
3
|
+
describe "Simple::SQL::Connection::Scope" do
|
4
4
|
def expects(expected_result, sql, *args)
|
5
5
|
expect(SQL.ask(sql, *args)).to eq(expected_result)
|
6
6
|
end
|
@@ -10,13 +10,13 @@ describe "Simple::SQL::Scope" do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'allows chaining of scopes' do
|
13
|
-
scope1 = SQL
|
13
|
+
scope1 = SQL.scope "SELECT 1, 2 FROM users"
|
14
14
|
scope2 = scope1.where("FALSE")
|
15
15
|
expect(scope1.to_sql).not_to eq(scope2.to_sql)
|
16
16
|
end
|
17
17
|
|
18
18
|
context "without conditions" do
|
19
|
-
let(:scope) { SQL
|
19
|
+
let(:scope) { SQL.scope "SELECT 1, 2 FROM users" }
|
20
20
|
|
21
21
|
it "runs with SQL.ask" do
|
22
22
|
expect(SQL.ask(scope)).to eq([1, 2])
|
@@ -29,7 +29,7 @@ describe "Simple::SQL::Scope" do
|
|
29
29
|
|
30
30
|
context "with hash conditions" do
|
31
31
|
let(:user_id) { SQL.ask "SELECT id FROM users LIMIT 1" }
|
32
|
-
let(:scope) { SQL
|
32
|
+
let(:scope) { SQL.scope "SELECT 1 FROM users" }
|
33
33
|
|
34
34
|
context "that do not match" do
|
35
35
|
it "does not match with string keys" do
|
@@ -71,7 +71,7 @@ describe "Simple::SQL::Scope" do
|
|
71
71
|
context "with non-argument conditions" do
|
72
72
|
context "that do not match" do
|
73
73
|
let(:scope) do
|
74
|
-
scope = SQL
|
74
|
+
scope = SQL.scope "SELECT 1, 2 FROM users"
|
75
75
|
scope = scope.where("id < 0")
|
76
76
|
scope.where("TRUE")
|
77
77
|
end
|
@@ -87,7 +87,7 @@ describe "Simple::SQL::Scope" do
|
|
87
87
|
|
88
88
|
context "that do match" do
|
89
89
|
let(:scope) do
|
90
|
-
scope = SQL
|
90
|
+
scope = SQL.scope "SELECT 1, 2 FROM users"
|
91
91
|
scope = scope.where("id >= 0")
|
92
92
|
scope.where("TRUE")
|
93
93
|
end
|
@@ -105,7 +105,7 @@ describe "Simple::SQL::Scope" do
|
|
105
105
|
context "with argument conditions" do
|
106
106
|
context "that do not match" do
|
107
107
|
let(:scope) do
|
108
|
-
scope = SQL
|
108
|
+
scope = SQL.scope "SELECT 1, 2 FROM users"
|
109
109
|
scope = scope.where("first_name NOT LIKE ?", "First%")
|
110
110
|
scope.where("id < ?", 0)
|
111
111
|
end
|
@@ -121,7 +121,7 @@ describe "Simple::SQL::Scope" do
|
|
121
121
|
|
122
122
|
context "where both match" do
|
123
123
|
let(:scope) do
|
124
|
-
scope = SQL
|
124
|
+
scope = SQL.scope "SELECT 1, 2 FROM users"
|
125
125
|
scope = scope.where("first_name LIKE ?", "First%")
|
126
126
|
scope.where("id >= ?", 0)
|
127
127
|
end
|
@@ -137,7 +137,7 @@ describe "Simple::SQL::Scope" do
|
|
137
137
|
|
138
138
|
context "where first condition matches" do
|
139
139
|
let(:scope) do
|
140
|
-
scope = SQL
|
140
|
+
scope = SQL.scope "SELECT 1, 2 FROM users"
|
141
141
|
scope = scope.where("first_name LIKE ?", "First%")
|
142
142
|
scope.where("id < ?", 0)
|
143
143
|
end
|
@@ -149,7 +149,7 @@ describe "Simple::SQL::Scope" do
|
|
149
149
|
|
150
150
|
context "where second condition matches" do
|
151
151
|
let(:scope) do
|
152
|
-
scope = SQL
|
152
|
+
scope = SQL.scope "SELECT 1, 2 FROM users"
|
153
153
|
scope = scope.where("first_name LIKE ?", "Boo%")
|
154
154
|
scope.where("id >= ?", 0)
|
155
155
|
end
|
@@ -160,7 +160,7 @@ describe "Simple::SQL::Scope" do
|
|
160
160
|
end
|
161
161
|
|
162
162
|
describe "hash matches" do
|
163
|
-
let(:scope) { SQL
|
163
|
+
let(:scope) { SQL.scope("SELECT id FROM users") }
|
164
164
|
|
165
165
|
it 'validates hash keys' do
|
166
166
|
expect {
|
@@ -178,7 +178,7 @@ describe "Simple::SQL::Scope" do
|
|
178
178
|
end
|
179
179
|
|
180
180
|
def ids_matching(condition)
|
181
|
-
scope = SQL
|
181
|
+
scope = SQL.scope("SELECT id FROM users")
|
182
182
|
scope = scope.where(condition)
|
183
183
|
SQL.all(scope)
|
184
184
|
end
|
@@ -205,22 +205,22 @@ describe "Simple::SQL::Scope" do
|
|
205
205
|
|
206
206
|
context "Building with Hash" do
|
207
207
|
it "runs with SQL.ask" do
|
208
|
-
scope = SQL
|
208
|
+
scope = SQL.scope table: "users", select: "1, 2", where: "id >= 0"
|
209
209
|
expect(SQL.all(scope)).to eq([[1,2], [1,2]])
|
210
210
|
|
211
|
-
scope = SQL
|
211
|
+
scope = SQL.scope table: "users", select: [1,3,4], where: "id >= 0"
|
212
212
|
expect(SQL.all(scope)).to eq([[1,3,4], [1,3,4]])
|
213
213
|
end
|
214
214
|
|
215
215
|
it "raises an error with missing or invalid attributes" do
|
216
|
-
expect { SQL
|
217
|
-
expect { SQL
|
216
|
+
expect { SQL.scope table: "users", limit: 1 }.to raise_error(ArgumentError)
|
217
|
+
expect { SQL.scope select: "*" }.to raise_error(ArgumentError)
|
218
218
|
end
|
219
219
|
end
|
220
220
|
|
221
221
|
context "describe pagination" do
|
222
222
|
let(:scope) do
|
223
|
-
scope = SQL
|
223
|
+
scope = SQL.scope "SELECT 1, 2 FROM users"
|
224
224
|
scope = scope.where("first_name LIKE ?", "First%")
|
225
225
|
scope.where("id > ?", 0)
|
226
226
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple-sql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- radiospiel
|
@@ -206,6 +206,12 @@ files:
|
|
206
206
|
- lib/simple/sql/connection/insert.rb
|
207
207
|
- lib/simple/sql/connection/raw_connection.rb
|
208
208
|
- lib/simple/sql/connection/reflection.rb
|
209
|
+
- lib/simple/sql/connection/scope.rb
|
210
|
+
- lib/simple/sql/connection/scope/count.rb
|
211
|
+
- lib/simple/sql/connection/scope/count_by_groups.rb
|
212
|
+
- lib/simple/sql/connection/scope/filters.rb
|
213
|
+
- lib/simple/sql/connection/scope/order.rb
|
214
|
+
- lib/simple/sql/connection/scope/pagination.rb
|
209
215
|
- lib/simple/sql/connection_adapter.rb
|
210
216
|
- lib/simple/sql/formatting.rb
|
211
217
|
- lib/simple/sql/fragment.rb
|
@@ -218,12 +224,7 @@ files:
|
|
218
224
|
- lib/simple/sql/result.rb
|
219
225
|
- lib/simple/sql/result/association_loader.rb
|
220
226
|
- lib/simple/sql/result/records.rb
|
221
|
-
- lib/simple/sql/scope.rb
|
222
227
|
- lib/simple/sql/scope/count.rb
|
223
|
-
- lib/simple/sql/scope/count_by_groups.rb
|
224
|
-
- lib/simple/sql/scope/filters.rb
|
225
|
-
- lib/simple/sql/scope/order.rb
|
226
|
-
- lib/simple/sql/scope/pagination.rb
|
227
228
|
- lib/simple/sql/version.rb
|
228
229
|
- log/.gitkeep
|
229
230
|
- scripts/stats
|