sqlknit 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +22 -0
- data/lib/needle.rb +29 -0
- data/lib/sql/from.rb +85 -0
- data/lib/sql/join.rb +42 -0
- data/lib/sql/on_condition.rb +86 -0
- data/lib/sql/select.rb +36 -0
- data/lib/sqlknit.rb +8 -0
- data/test/from_test.rb +217 -0
- data/test/join_test.rb +227 -0
- data/test/select_test.rb +37 -0
- data/test/test_helper.rb +9 -0
- metadata +59 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YTc3ZTllNTMyYmY4MzI1ZDBlNDE2MWFhYjc0MGI4NDFjYTgwNGRjMQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MTcwMzAyNDAyNTZhNzRlZjA0OGFkZjRlYmM3OWYxMWI1ODc1MjMzYw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YmMyM2ZjZDMzZTc3ZDBlOTlkZmZjZjQ1Y2M3OGFkYTg2Yjc4YjhhOWI2N2Mw
|
10
|
+
YjQxZDU0ZTc2MmMyNTc3NjVjNmViMmQ1OGUyOTA0ZTMxZGUxZDcyMWFlOGJl
|
11
|
+
Zjc5YjVhMDNiNTU0MzNmOGM1NDUzOGMwMDcwMjA3MmZhMmEzYTM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
N2E2MjhlN2IxZDFiMzc5OGM4ZDg4MDM0NjliNjdkMWIxOTY4ZGMzZTMyZDg1
|
14
|
+
MjQ1MDNlZTBmMmI1OTRjMTVkYTg0YzY3Mjk2NGEwZmZlZGUxMmM2MGU1MGYw
|
15
|
+
NWJlY2I4YTkzZjRmNzRlOTQyNjQzODFiNTc2MzA0YTI1ZWQ5MDk=
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (4.2.0)
|
5
|
+
i18n (~> 0.7)
|
6
|
+
json (~> 1.7, >= 1.7.7)
|
7
|
+
minitest (~> 5.1)
|
8
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
9
|
+
tzinfo (~> 1.1)
|
10
|
+
i18n (0.7.0)
|
11
|
+
json (1.8.1)
|
12
|
+
minitest (5.5.0)
|
13
|
+
thread_safe (0.3.4)
|
14
|
+
tzinfo (1.2.2)
|
15
|
+
thread_safe (~> 0.1)
|
16
|
+
|
17
|
+
PLATFORMS
|
18
|
+
ruby
|
19
|
+
|
20
|
+
DEPENDENCIES
|
21
|
+
activesupport
|
22
|
+
minitest
|
data/lib/needle.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module SQLKnit
|
2
|
+
|
3
|
+
class Needle
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@sql_select = SQL::Select.new
|
7
|
+
@sql_from = SQL::From.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def select &block
|
11
|
+
@sql_select.instance_eval &block
|
12
|
+
end
|
13
|
+
|
14
|
+
def from *table_names, &block
|
15
|
+
table_names[0..-2].each {|table_name| @sql_from.add_table table_name }
|
16
|
+
@sql_from.contextlize table_names.last, &block
|
17
|
+
end
|
18
|
+
|
19
|
+
def select_statement
|
20
|
+
@sql_select.to_statement
|
21
|
+
end
|
22
|
+
|
23
|
+
def from_statement
|
24
|
+
@sql_from.to_statement
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
data/lib/sql/from.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
module SQLKnit
|
2
|
+
module SQL
|
3
|
+
class From
|
4
|
+
|
5
|
+
attr_reader :statement_chains, :current_chain, :current_table_name
|
6
|
+
attr_reader :current_join_type
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@statement_chains = Hash.new {|hash, key| hash[key] = []}
|
10
|
+
end
|
11
|
+
|
12
|
+
def contextlize table_name, &block
|
13
|
+
switch_to table_name
|
14
|
+
instance_eval &block if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def text str
|
18
|
+
statement_chains << str if not statement_chains.include? str
|
19
|
+
end
|
20
|
+
|
21
|
+
def join table_name
|
22
|
+
opts = {type: current_join_type}
|
23
|
+
join = SQL::Join.new(current_table_name, table_name, opts)
|
24
|
+
current_chain << join
|
25
|
+
join
|
26
|
+
end
|
27
|
+
|
28
|
+
alias_method :join_chain, :join
|
29
|
+
|
30
|
+
def join *table_names
|
31
|
+
|
32
|
+
if table_names.size > 1
|
33
|
+
table_name_paires = pairelize_table_names table_names
|
34
|
+
table_name_paires.unshift [current_table_name, table_names.first]
|
35
|
+
table_name_paires.each {|paire|
|
36
|
+
on_table_name, join_table_name = paire
|
37
|
+
join_chain(join_table_name).on(on_table_name)
|
38
|
+
}
|
39
|
+
else
|
40
|
+
join_chain(table_names.first)
|
41
|
+
end
|
42
|
+
|
43
|
+
current_chain.last
|
44
|
+
end
|
45
|
+
|
46
|
+
def left_join *table_names
|
47
|
+
switch_join_type 'left join'
|
48
|
+
join table_names
|
49
|
+
end
|
50
|
+
|
51
|
+
def pairelize_table_names table_names
|
52
|
+
last_index = table_names.length - 1
|
53
|
+
(0..(last_index-1)).map {|i| table_names[i..i+1] }
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_statement
|
57
|
+
statement = statement_chains.map {|table_name, joins|
|
58
|
+
if joins.size > 0
|
59
|
+
"#{table_name} #{joins.map(&:to_statement).join("\n")}"
|
60
|
+
else
|
61
|
+
table_name.to_s
|
62
|
+
end
|
63
|
+
}.join(",\n")
|
64
|
+
|
65
|
+
["from", statement].join(" ")
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_table table_name
|
69
|
+
statement_chains[table_name] if not statement_chains.has_key? table_name
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def switch_join_type type
|
75
|
+
@current_join_type = type
|
76
|
+
end
|
77
|
+
|
78
|
+
def switch_to table_name
|
79
|
+
@current_table_name = table_name
|
80
|
+
@current_chain = @statement_chains[table_name]
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/sql/join.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module SQLKnit
|
2
|
+
module SQL
|
3
|
+
class Join
|
4
|
+
|
5
|
+
TableAbbrSymbol = ':'
|
6
|
+
|
7
|
+
attr_reader :head_table_name, :join_table_name, :on_table_name
|
8
|
+
attr_reader :type
|
9
|
+
attr_reader :on_conditions
|
10
|
+
attr_reader :statement_chains
|
11
|
+
|
12
|
+
def initialize head_table_name, table_name, opts = {}
|
13
|
+
@head_table_name = head_table_name
|
14
|
+
@join_table_name = table_name
|
15
|
+
@on_conditions = []
|
16
|
+
@type = opts[:type] || 'join'
|
17
|
+
@statement_chains = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def on text = nil, &block
|
21
|
+
|
22
|
+
if text.include? TableAbbrSymbol
|
23
|
+
join_text = text.gsub(TableAbbrSymbol, join_table_name.to_s)
|
24
|
+
else
|
25
|
+
join_text = text
|
26
|
+
end
|
27
|
+
|
28
|
+
on_condition = OnCondition.new join_table_name
|
29
|
+
on_condition.add_text join_text
|
30
|
+
|
31
|
+
on_conditions << on_condition
|
32
|
+
on_condition.instance_eval &block if block_given?
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_statement
|
36
|
+
statement = on_conditions.map(&:to_statement).join("\n")
|
37
|
+
[type, statement].join(" ")
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
class OnCondition
|
2
|
+
|
3
|
+
attr_reader :join_table_name, :on_table_name, :texts, :current_logic_op
|
4
|
+
|
5
|
+
def initialize join_table_name, on_table_name = nil
|
6
|
+
@join_table_name = join_table_name
|
7
|
+
@on_table_name = on_table_name
|
8
|
+
@texts = []
|
9
|
+
@curent_logic_op = 'and'
|
10
|
+
add_default_relation_text
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_default_relation_text
|
14
|
+
add_text default_relation_text if default_relation_text
|
15
|
+
end
|
16
|
+
|
17
|
+
def text str
|
18
|
+
add_text str
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_text text
|
22
|
+
if not texts.include? text
|
23
|
+
if texts.size > 0
|
24
|
+
texts << [current_logic_op, text].join(" ")
|
25
|
+
else
|
26
|
+
texts << text
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_statement
|
32
|
+
statement = texts.join(" ")
|
33
|
+
[join_table_name, "on", statement].join(" ")
|
34
|
+
end
|
35
|
+
|
36
|
+
def default_relation_text
|
37
|
+
if on_table_name
|
38
|
+
foreign_key = get_foreign_key on_table_name
|
39
|
+
"#{join_table_name}.#{foreign_key} = #{on_table_name}.id"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def sql_and
|
46
|
+
@current_logic_op = 'and'
|
47
|
+
end
|
48
|
+
|
49
|
+
def sql_or
|
50
|
+
@current_logic_op = 'or'
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_foreign_key table_name
|
54
|
+
"#{table_name.to_s.singularize}_id"
|
55
|
+
end
|
56
|
+
|
57
|
+
def method_missing table_name, values_mapper
|
58
|
+
create_method table_name do |values_mapper|
|
59
|
+
statement = values_mapper.map {|col, value|
|
60
|
+
if value.is_a? Array or value.is_a? Range
|
61
|
+
range = value.map {|v| quote v}.join(',')
|
62
|
+
"#{table_name}.#{col} in (#{range})"
|
63
|
+
else
|
64
|
+
"#{table_name}.#{col} = #{quote(value)}"
|
65
|
+
end
|
66
|
+
}.join(" and ")
|
67
|
+
|
68
|
+
text statement
|
69
|
+
end
|
70
|
+
|
71
|
+
send table_name, values_mapper
|
72
|
+
end
|
73
|
+
|
74
|
+
def quote value
|
75
|
+
if value.is_a? String
|
76
|
+
["'", value, "'"].join
|
77
|
+
else
|
78
|
+
value
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def create_method name, &block
|
83
|
+
self.class.send :define_method, name, &block
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
data/lib/sql/select.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module SQLKnit
|
2
|
+
module SQL
|
3
|
+
class Select
|
4
|
+
|
5
|
+
attr_reader :statement_chains
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@statement_chains = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def text str
|
12
|
+
statement_chains << str if not statement_chains.include? str
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_statement
|
16
|
+
"select #{statement_chains.join(",\n")}"
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def method_missing table_name, as_mapper
|
22
|
+
|
23
|
+
create_method table_name do |as_mapper|
|
24
|
+
as_mapper.each {|col, as_col| text "#{table_name}.#{col} as #{as_col}"}
|
25
|
+
end
|
26
|
+
|
27
|
+
send table_name, as_mapper
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_method name, &block
|
31
|
+
self.class.send :define_method, name, &block
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/sqlknit.rb
ADDED
data/test/from_test.rb
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FromStatementTest < MiniTest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@needle = SQLKnit::Needle.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_from_single_table_01
|
10
|
+
@needle.sql_from :orders do
|
11
|
+
join(:line_items).on('line_items.order_id = orders.id')
|
12
|
+
end
|
13
|
+
statement = "from orders join line_items on line_items.order_id = orders.id"
|
14
|
+
|
15
|
+
assert_equal @needle.from_statement, statement
|
16
|
+
end
|
17
|
+
|
18
|
+
# def test_from_single_table_without_join
|
19
|
+
# @needle.sql_from :orders do
|
20
|
+
# join(:line_items).on :orders if false
|
21
|
+
# end
|
22
|
+
# statement = "from orders"
|
23
|
+
|
24
|
+
# assert_equal @needle.from_statement, statement
|
25
|
+
# end
|
26
|
+
|
27
|
+
# def test_from_single_table_join_mult_tables
|
28
|
+
# @needle.sql_from :orders do
|
29
|
+
# join(:line_items).on :orders
|
30
|
+
# end
|
31
|
+
|
32
|
+
# @needle.sql_from :orders do
|
33
|
+
# join(:variants).on :line_items
|
34
|
+
# end
|
35
|
+
|
36
|
+
# @needle.sql_from :orders do
|
37
|
+
# join(:products).on :variants
|
38
|
+
# end
|
39
|
+
|
40
|
+
# statement = "from orders join line_items on line_items.order_id = orders.id
|
41
|
+
# join variants on variants.line_item_id = line_items.id
|
42
|
+
# join products on products.variant_id = variants.id"
|
43
|
+
|
44
|
+
# assert_equal @needle.from_statement, statement
|
45
|
+
|
46
|
+
# end
|
47
|
+
|
48
|
+
# def test_from_single_table_join_mult_tables_at_once
|
49
|
+
# @needle.sql_from :orders do
|
50
|
+
# join(:line_items).on :orders
|
51
|
+
# join(:variants).on :line_items
|
52
|
+
# join(:products).on :variants
|
53
|
+
# join(:products_taxons).on :products
|
54
|
+
# end
|
55
|
+
|
56
|
+
# statement = "from orders join line_items on line_items.order_id = orders.id
|
57
|
+
# join variants on variants.line_item_id = line_items.id
|
58
|
+
# join products on products.variant_id = variants.id
|
59
|
+
# join products_taxons on products_taxons.product_id = products.id"
|
60
|
+
|
61
|
+
# assert_equal @needle.from_statement, statement
|
62
|
+
# end
|
63
|
+
|
64
|
+
# def test_from_mult_tables_without_join
|
65
|
+
# @needle.sql_from :orders, :line_items
|
66
|
+
# statement = "from orders,
|
67
|
+
# line_items"
|
68
|
+
|
69
|
+
# assert_equal @needle.from_statement, statement
|
70
|
+
# end
|
71
|
+
|
72
|
+
# def test_from_mult_tables_join_single_table_at_once
|
73
|
+
# @needle.sql_from :orders, :variants do
|
74
|
+
# join(:line_items).on :variants
|
75
|
+
# end
|
76
|
+
|
77
|
+
# statement = "from orders,
|
78
|
+
# variants join line_items on line_items.variant_id = variants.id"
|
79
|
+
|
80
|
+
# assert_equal @needle.from_statement, statement
|
81
|
+
# end
|
82
|
+
|
83
|
+
# def test_from_mult_tables_join_single_table_at_mult_time
|
84
|
+
# @needle.sql_from :orders do
|
85
|
+
# join(:lineitems).on :orders
|
86
|
+
# end
|
87
|
+
|
88
|
+
# @needle.sql_from :variants do
|
89
|
+
# join(:products).on :variants
|
90
|
+
# end
|
91
|
+
|
92
|
+
# statement = "from orders join lineitems on lineitems.order_id = orders.id,
|
93
|
+
# variants join products on products.variant_id = variants.id"
|
94
|
+
|
95
|
+
# assert_equal @needle.from_statement, statement
|
96
|
+
|
97
|
+
# end
|
98
|
+
|
99
|
+
# def test_from_single_table_join_single_table_chain
|
100
|
+
# @needle.sql_from :orders do
|
101
|
+
# join :products
|
102
|
+
# end
|
103
|
+
# statement = "from orders join products on products.order_id = orders.id"
|
104
|
+
|
105
|
+
# assert_equal @needle.from_statement, statement
|
106
|
+
# end
|
107
|
+
|
108
|
+
# def test_from_single_table_join_mult_tables_chain
|
109
|
+
# @needle.sql_from :orders do
|
110
|
+
# join :line_items, :variants, :products, :products_taxons
|
111
|
+
# end
|
112
|
+
# statement = "from orders join line_items on line_items.order_id = orders.id
|
113
|
+
# join variants on variants.line_item_id = line_items.id
|
114
|
+
# join products on products.variant_id = variants.id
|
115
|
+
# join products_taxons on products_taxons.product_id = products.id"
|
116
|
+
|
117
|
+
# assert_equal @needle.from_statement, statement
|
118
|
+
# end
|
119
|
+
|
120
|
+
# def test_join_single_table_on_text
|
121
|
+
# @needle.sql_from :orders do
|
122
|
+
# join(:line_items).on "line_items.order_id = orders.id"
|
123
|
+
# end
|
124
|
+
|
125
|
+
# statement = "from orders join line_items on line_items.order_id = orders.id"
|
126
|
+
# assert_equal @needle.from_statement, statement
|
127
|
+
# end
|
128
|
+
|
129
|
+
# def test_join_single_table_on_text_in_a_block
|
130
|
+
# @needle.sql_from :orders do
|
131
|
+
# join(:line_items).on do
|
132
|
+
# text "line_items.order_id = orders.id"
|
133
|
+
# end
|
134
|
+
# end
|
135
|
+
|
136
|
+
# statement = "from orders join line_items on line_items.order_id = orders.id"
|
137
|
+
|
138
|
+
# assert_equal @needle.from_statement, statement
|
139
|
+
# end
|
140
|
+
|
141
|
+
# def test_join_table_on_table_attributes
|
142
|
+
# @needle.sql_from :orders do
|
143
|
+
# join(:line_items).on :orders
|
144
|
+
# join(:state_events).on do
|
145
|
+
# text "state_events.stateful_id = orders.id"
|
146
|
+
# sql_and
|
147
|
+
# state_events name: 'payment', stateful_type: 'Order', next_state: ['paid', 'credit_owed']
|
148
|
+
# end
|
149
|
+
# end
|
150
|
+
|
151
|
+
# statement = "from orders join line_items on line_items.order_id = orders.id
|
152
|
+
# join state_events on state_events.stateful_id = orders.id and state_events.name = 'payment' and state_events.stateful_type = 'Order' and state_events.next_state in ('paid','credit_owed')"
|
153
|
+
|
154
|
+
# assert_equal @needle.from_statement, statement
|
155
|
+
|
156
|
+
# end
|
157
|
+
|
158
|
+
# def test_left_join
|
159
|
+
# @needle.sql_from :orders do
|
160
|
+
# left_join(:line_items).on :orders
|
161
|
+
# left_join(:state_events).on do
|
162
|
+
# text "state_events.stateful_id = orders.id"
|
163
|
+
# sql_and
|
164
|
+
# state_events name: 'payment', stateful_type: 'Order', next_state: ['paid', 'credit_owed']
|
165
|
+
# end
|
166
|
+
# end
|
167
|
+
|
168
|
+
# statement = "from orders left join line_items on [:line_items].order_id = orders.id
|
169
|
+
# left join state_events on state_events.stateful_id = orders.id and state_events.name = 'payment' and state_events.stateful_type = 'Order' and state_events.next_state in ('paid','credit_owed')"
|
170
|
+
|
171
|
+
# assert_equal @needle.from_statement, statement
|
172
|
+
# end
|
173
|
+
|
174
|
+
# def test_from
|
175
|
+
|
176
|
+
@needle.sql_from :orders do
|
177
|
+
join(:line_items).on(:orders)
|
178
|
+
join(:variants).on(:line_items)
|
179
|
+
join(:products).on(:variants)
|
180
|
+
join(:products_taxons).on(:products)
|
181
|
+
join(:state_events).on do
|
182
|
+
text "state_events.stateful_id = orders.id"
|
183
|
+
and
|
184
|
+
state_events name: 'payment', stateful_type: 'Order', next_state: ['paid', 'credit_owed']
|
185
|
+
end
|
186
|
+
left_join(:shipments).on(:orders)
|
187
|
+
left_join(:warehouses).on(:shipments)
|
188
|
+
left_join(:users).on(:orders)
|
189
|
+
left_join(:addresses, as: 'sold_address').on(:users)
|
190
|
+
left_join(:distributors).on(:users)
|
191
|
+
left_join(:addresses).on('orders.ship_address_id = :.id')
|
192
|
+
left_join(:address_addons).on(:addresses)
|
193
|
+
left_join(:states).on(:addresses)
|
194
|
+
left_join(:countries).on(:addresses)
|
195
|
+
left_join(:currencies).on(:orders)
|
196
|
+
left_join(:adjustments, as: 'shipping_adjustments').on do
|
197
|
+
shipping_adjustments label: 'Shipping', source_type: 'Shipment'
|
198
|
+
text "orders.id = :.order_id"
|
199
|
+
text ":.source_id = shipments.id"
|
200
|
+
end
|
201
|
+
left_join(:adjustments, as: 'gst_adjustments').on do
|
202
|
+
gst_adjustments label: 'gst', source_type: 'Order'
|
203
|
+
text "orders.id = :.order_id"
|
204
|
+
text ":.source_id = orders.id"
|
205
|
+
end
|
206
|
+
left_join(:adjustments, as: 'gst_shipping_adjustments').on do
|
207
|
+
gst_shipping_adjustments label: 'gst_shipping', source_type: 'Order'
|
208
|
+
text "orders.id = :.order_id"
|
209
|
+
text ":.source_id = orders.id"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# puts @needle.from_statement
|
214
|
+
|
215
|
+
# end
|
216
|
+
|
217
|
+
end
|
data/test/join_test.rb
ADDED
@@ -0,0 +1,227 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class JoinStatementTest < MiniTest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@needle = SQLKnit::Needle.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_join_on_text
|
10
|
+
@needle.from :orders do
|
11
|
+
join(:line_items).on('line_items.order_id = orders.id')
|
12
|
+
end
|
13
|
+
statement = "from orders join line_items on line_items.order_id = orders.id"
|
14
|
+
|
15
|
+
assert_equal @needle.from_statement, statement
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_join_on_text_with_placeholder
|
19
|
+
@needle.from :orders do
|
20
|
+
join(:line_items).on(':.order_id = orders.id')
|
21
|
+
end
|
22
|
+
statement = "from orders join line_items on line_items.order_id = orders.id"
|
23
|
+
|
24
|
+
assert_equal @needle.from_statement, statement
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
# def test_from_single_table_without_join
|
29
|
+
# @needle.sql_from :orders do
|
30
|
+
# join(:line_items).on :orders if false
|
31
|
+
# end
|
32
|
+
# statement = "from orders"
|
33
|
+
|
34
|
+
# assert_equal @needle.from_statement, statement
|
35
|
+
# end
|
36
|
+
|
37
|
+
# def test_from_single_table_join_mult_tables
|
38
|
+
# @needle.sql_from :orders do
|
39
|
+
# join(:line_items).on :orders
|
40
|
+
# end
|
41
|
+
|
42
|
+
# @needle.sql_from :orders do
|
43
|
+
# join(:variants).on :line_items
|
44
|
+
# end
|
45
|
+
|
46
|
+
# @needle.sql_from :orders do
|
47
|
+
# join(:products).on :variants
|
48
|
+
# end
|
49
|
+
|
50
|
+
# statement = "from orders join line_items on line_items.order_id = orders.id
|
51
|
+
# join variants on variants.line_item_id = line_items.id
|
52
|
+
# join products on products.variant_id = variants.id"
|
53
|
+
|
54
|
+
# assert_equal @needle.from_statement, statement
|
55
|
+
|
56
|
+
# end
|
57
|
+
|
58
|
+
# def test_from_single_table_join_mult_tables_at_once
|
59
|
+
# @needle.sql_from :orders do
|
60
|
+
# join(:line_items).on :orders
|
61
|
+
# join(:variants).on :line_items
|
62
|
+
# join(:products).on :variants
|
63
|
+
# join(:products_taxons).on :products
|
64
|
+
# end
|
65
|
+
|
66
|
+
# statement = "from orders join line_items on line_items.order_id = orders.id
|
67
|
+
# join variants on variants.line_item_id = line_items.id
|
68
|
+
# join products on products.variant_id = variants.id
|
69
|
+
# join products_taxons on products_taxons.product_id = products.id"
|
70
|
+
|
71
|
+
# assert_equal @needle.from_statement, statement
|
72
|
+
# end
|
73
|
+
|
74
|
+
# def test_from_mult_tables_without_join
|
75
|
+
# @needle.sql_from :orders, :line_items
|
76
|
+
# statement = "from orders,
|
77
|
+
# line_items"
|
78
|
+
|
79
|
+
# assert_equal @needle.from_statement, statement
|
80
|
+
# end
|
81
|
+
|
82
|
+
# def test_from_mult_tables_join_single_table_at_once
|
83
|
+
# @needle.sql_from :orders, :variants do
|
84
|
+
# join(:line_items).on :variants
|
85
|
+
# end
|
86
|
+
|
87
|
+
# statement = "from orders,
|
88
|
+
# variants join line_items on line_items.variant_id = variants.id"
|
89
|
+
|
90
|
+
# assert_equal @needle.from_statement, statement
|
91
|
+
# end
|
92
|
+
|
93
|
+
# def test_from_mult_tables_join_single_table_at_mult_time
|
94
|
+
# @needle.sql_from :orders do
|
95
|
+
# join(:lineitems).on :orders
|
96
|
+
# end
|
97
|
+
|
98
|
+
# @needle.sql_from :variants do
|
99
|
+
# join(:products).on :variants
|
100
|
+
# end
|
101
|
+
|
102
|
+
# statement = "from orders join lineitems on lineitems.order_id = orders.id,
|
103
|
+
# variants join products on products.variant_id = variants.id"
|
104
|
+
|
105
|
+
# assert_equal @needle.from_statement, statement
|
106
|
+
|
107
|
+
# end
|
108
|
+
|
109
|
+
# def test_from_single_table_join_single_table_chain
|
110
|
+
# @needle.sql_from :orders do
|
111
|
+
# join :products
|
112
|
+
# end
|
113
|
+
# statement = "from orders join products on products.order_id = orders.id"
|
114
|
+
|
115
|
+
# assert_equal @needle.from_statement, statement
|
116
|
+
# end
|
117
|
+
|
118
|
+
# def test_from_single_table_join_mult_tables_chain
|
119
|
+
# @needle.sql_from :orders do
|
120
|
+
# join :line_items, :variants, :products, :products_taxons
|
121
|
+
# end
|
122
|
+
# statement = "from orders join line_items on line_items.order_id = orders.id
|
123
|
+
# join variants on variants.line_item_id = line_items.id
|
124
|
+
# join products on products.variant_id = variants.id
|
125
|
+
# join products_taxons on products_taxons.product_id = products.id"
|
126
|
+
|
127
|
+
# assert_equal @needle.from_statement, statement
|
128
|
+
# end
|
129
|
+
|
130
|
+
# def test_join_single_table_on_text
|
131
|
+
# @needle.sql_from :orders do
|
132
|
+
# join(:line_items).on "line_items.order_id = orders.id"
|
133
|
+
# end
|
134
|
+
|
135
|
+
# statement = "from orders join line_items on line_items.order_id = orders.id"
|
136
|
+
# assert_equal @needle.from_statement, statement
|
137
|
+
# end
|
138
|
+
|
139
|
+
# def test_join_single_table_on_text_in_a_block
|
140
|
+
# @needle.sql_from :orders do
|
141
|
+
# join(:line_items).on do
|
142
|
+
# text "line_items.order_id = orders.id"
|
143
|
+
# end
|
144
|
+
# end
|
145
|
+
|
146
|
+
# statement = "from orders join line_items on line_items.order_id = orders.id"
|
147
|
+
|
148
|
+
# assert_equal @needle.from_statement, statement
|
149
|
+
# end
|
150
|
+
|
151
|
+
# def test_join_table_on_table_attributes
|
152
|
+
# @needle.sql_from :orders do
|
153
|
+
# join(:line_items).on :orders
|
154
|
+
# join(:state_events).on do
|
155
|
+
# text "state_events.stateful_id = orders.id"
|
156
|
+
# sql_and
|
157
|
+
# state_events name: 'payment', stateful_type: 'Order', next_state: ['paid', 'credit_owed']
|
158
|
+
# end
|
159
|
+
# end
|
160
|
+
|
161
|
+
# statement = "from orders join line_items on line_items.order_id = orders.id
|
162
|
+
# join state_events on state_events.stateful_id = orders.id and state_events.name = 'payment' and state_events.stateful_type = 'Order' and state_events.next_state in ('paid','credit_owed')"
|
163
|
+
|
164
|
+
# assert_equal @needle.from_statement, statement
|
165
|
+
|
166
|
+
# end
|
167
|
+
|
168
|
+
# def test_left_join
|
169
|
+
# @needle.sql_from :orders do
|
170
|
+
# left_join(:line_items).on :orders
|
171
|
+
# left_join(:state_events).on do
|
172
|
+
# text "state_events.stateful_id = orders.id"
|
173
|
+
# sql_and
|
174
|
+
# state_events name: 'payment', stateful_type: 'Order', next_state: ['paid', 'credit_owed']
|
175
|
+
# end
|
176
|
+
# end
|
177
|
+
|
178
|
+
# statement = "from orders left join line_items on [:line_items].order_id = orders.id
|
179
|
+
# left join state_events on state_events.stateful_id = orders.id and state_events.name = 'payment' and state_events.stateful_type = 'Order' and state_events.next_state in ('paid','credit_owed')"
|
180
|
+
|
181
|
+
# assert_equal @needle.from_statement, statement
|
182
|
+
# end
|
183
|
+
|
184
|
+
# def test_from
|
185
|
+
|
186
|
+
# @needle.sql_from :orders do
|
187
|
+
# join(:line_items).on(:orders)
|
188
|
+
# join(:variants).on(:line_items)
|
189
|
+
# join(:products).on(:variants)
|
190
|
+
# join(:products_taxons).on(:products)
|
191
|
+
# join(:state_events).on do
|
192
|
+
# text "state_events.stateful_id = orders.id"
|
193
|
+
# and
|
194
|
+
# state_events name: 'payment', stateful_type: 'Order', next_state: ['paid', 'credit_owed']
|
195
|
+
# end
|
196
|
+
# left_join(:shipments).on(:orders)
|
197
|
+
# left_join(:warehouses).on(:shipments)
|
198
|
+
# left_join(:users).on(:orders)
|
199
|
+
# left_join(:addresses, as: 'sold_address').on(:users)
|
200
|
+
# left_join(:distributors).on(:users)
|
201
|
+
# left_join(:addresses).on('orders.ship_address_id = :.id')
|
202
|
+
# left_join(:address_addons).on(:addresses)
|
203
|
+
# left_join(:states).on(:addresses)
|
204
|
+
# left_join(:countries).on(:addresses)
|
205
|
+
# left_join(:currencies).on(:orders)
|
206
|
+
# left_join(:adjustments, as: 'shipping_adjustments').on do
|
207
|
+
# shipping_adjustments label: 'Shipping', source_type: 'Shipment'
|
208
|
+
# text "orders.id = :.order_id"
|
209
|
+
# text ":.source_id = shipments.id"
|
210
|
+
# end
|
211
|
+
# left_join(:adjustments, as: 'gst_adjustments').on do
|
212
|
+
# gst_adjustments label: 'gst', source_type: 'Order'
|
213
|
+
# text "orders.id = :.order_id"
|
214
|
+
# text ":.source_id = orders.id"
|
215
|
+
# end
|
216
|
+
# left_join(:adjustments, as: 'gst_shipping_adjustments').on do
|
217
|
+
# gst_shipping_adjustments label: 'gst_shipping', source_type: 'Order'
|
218
|
+
# text "orders.id = :.order_id"
|
219
|
+
# text ":.source_id = orders.id"
|
220
|
+
# end
|
221
|
+
# end
|
222
|
+
|
223
|
+
# puts @needle.from_statement
|
224
|
+
|
225
|
+
# end
|
226
|
+
|
227
|
+
end
|
data/test/select_test.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SelectStatementTest < MiniTest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@needle = SQLKnit::Needle.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_select
|
10
|
+
|
11
|
+
@needle.sql_select do
|
12
|
+
text "coalesce(addresses.address1, '') as shipto_address1"
|
13
|
+
text "coalesce(addresses.address2, '') as shipto_address2"
|
14
|
+
addresses city: 'shipto_city', zipcode: 'shipto_zip'
|
15
|
+
states name: 'shipto_state', abbr: 'shipto_state_abbr'
|
16
|
+
countries iso: 'shipto_country'
|
17
|
+
orders email: 'shipto_email'
|
18
|
+
addresses phone: 'shipto_phone'
|
19
|
+
distributors id: 'distributor_id'
|
20
|
+
end
|
21
|
+
|
22
|
+
select_statement = "select coalesce(addresses.address1, '') as shipto_address1,
|
23
|
+
coalesce(addresses.address2, '') as shipto_address2,
|
24
|
+
addresses.city as shipto_city,
|
25
|
+
addresses.zipcode as shipto_zip,
|
26
|
+
states.name as shipto_state,
|
27
|
+
states.abbr as shipto_state_abbr,
|
28
|
+
countries.iso as shipto_country,
|
29
|
+
orders.email as shipto_email,
|
30
|
+
addresses.phone as shipto_phone,
|
31
|
+
distributors.id as distributor_id"
|
32
|
+
|
33
|
+
assert_equal @needle.select_statement, select_statement
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sqlknit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- jm
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-03 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A sql builder
|
14
|
+
email: kayak.jiang@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- Gemfile
|
20
|
+
- Gemfile.lock
|
21
|
+
- lib/needle.rb
|
22
|
+
- lib/sql/from.rb
|
23
|
+
- lib/sql/join.rb
|
24
|
+
- lib/sql/on_condition.rb
|
25
|
+
- lib/sql/select.rb
|
26
|
+
- lib/sqlknit.rb
|
27
|
+
- test/from_test.rb
|
28
|
+
- test/join_test.rb
|
29
|
+
- test/select_test.rb
|
30
|
+
- test/test_helper.rb
|
31
|
+
homepage: https://github.com/baya/sqlknit
|
32
|
+
licenses:
|
33
|
+
- MIT
|
34
|
+
metadata: {}
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
requirements: []
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 2.2.2
|
52
|
+
signing_key:
|
53
|
+
specification_version: 4
|
54
|
+
summary: knit sql
|
55
|
+
test_files:
|
56
|
+
- test/from_test.rb
|
57
|
+
- test/join_test.rb
|
58
|
+
- test/select_test.rb
|
59
|
+
- test/test_helper.rb
|