sqlknit 0.0.1
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 +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
|