simple-sql 0.5.4 → 0.5.5
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.
- 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
|