sql-maker 0.0.2 → 0.0.3

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.
@@ -0,0 +1,11 @@
1
+ # NAME
2
+
3
+ SQL::Maker::Error
4
+
5
+ # SYNOPSIS
6
+
7
+ SQL::Maker::Error.new('message')
8
+
9
+ # DESCRIPTION
10
+
11
+ An error class of the SQL::Maker.
@@ -0,0 +1,48 @@
1
+ # NAME
2
+
3
+ SQL::Maker::Helper - helper functions for SQL::Maker
4
+
5
+ # SYNOPSIS
6
+
7
+ include SQL::Maker::Helper
8
+ sql_raw('WHERE `id` = ?' => [1])
9
+
10
+ # DESCRIPTION
11
+
12
+ This module is to to provide sql_xxx helper functions.
13
+
14
+ # FUNCTIONS
15
+
16
+ Following functions will be available by `include SQL::Maker::Helper`:
17
+
18
+ * sql_raw
19
+ * sql_op
20
+ * sql_is_null
21
+ * sql_is_not_null
22
+ * sql_eq
23
+ * sql_ne
24
+ * sql_lt
25
+ * sql_gt
26
+ * sql_le
27
+ * sql_ge
28
+ * sql_like
29
+ * sql_between
30
+ * sql_not_between
31
+ * sql_not
32
+ * sql_and
33
+ * sql_or
34
+ * sql_in
35
+ * sql_not_in
36
+ * sql_not_in
37
+
38
+ and
39
+
40
+ * sql_union
41
+ * sql_union_all
42
+ * sql_intersect
43
+ * sql_intersect_all
44
+ * sql_except
45
+ * sql_except_all
46
+
47
+ Please see [SQL::QueryMaker](../query_maker.md)
48
+ and [SQL::Maker::SelectSet](./select_set.md) for details.
@@ -0,0 +1,11 @@
1
+ # NAME
2
+
3
+ SQL::Maker::Quoting - Quoting and Escaping
4
+
5
+ # DESCRIPTION
6
+
7
+ This module is to privide quoting and escaping function of SQL values.
8
+
9
+ # REFERENCE
10
+
11
+ ActiveRecord::ConnectionAdapter::Quoting
@@ -0,0 +1,204 @@
1
+ # NAME
2
+
3
+ SQL::Maker::Select - dynamic SQL generator
4
+
5
+ # SYNOPSIS
6
+
7
+ sql = SQL::Maker::Select.new
8
+ .add_select('foo')
9
+ .add_select('bar')
10
+ .add_select('baz')
11
+ .add_from('table_name' => 't')
12
+ .as_sql
13
+ # => "SELECT foo, bar, baz FROM table_name t"
14
+
15
+ # DESCRIPTION
16
+
17
+ # METHODS
18
+
19
+
20
+
21
+ ### sql = stmt.as_sql
22
+
23
+ Render the SQL string.
24
+
25
+ ### bind = stmt.bind
26
+
27
+ Get the bind variables.
28
+
29
+ ### stmt.add_select('*')
30
+
31
+ ### stmt.add_select(:col => alias)
32
+
33
+ ### stmt.add_select(sql_raw('COUNT(*)') => 'cnt')
34
+
35
+ Add a new select term. It's automatically quoted.
36
+
37
+ ### stmt.add_from(table :Str | select :SQL::Maker::Select) : SQL::Maker::Select
38
+
39
+ Add a new FROM clause. You can specify the table name or an instance of SQL::Maker::Select for a sub-query.
40
+
41
+ I<Return:> stmt itself.
42
+
43
+ ### stmt.add_join(:user => {:type => 'inner', :table => 'config', :condition => 'user.user_id = config.user_id'})
44
+
45
+ ### stmt.add_join(:user => {:type => 'inner', :table => 'config', :condition => {'user.user_id' => 'config.user_id'})
46
+
47
+ ### stmt.add_join(:user => {:type => 'inner', :table => 'config', :condition => ['user_id']})
48
+
49
+ Add a new JOIN clause. If you pass an array for 'condition' then it uses 'USING'. If 'type' is omitted
50
+ it falls back to plain JOIN.
51
+
52
+ stmt = SQL::Maker::Select.new
53
+ stmt.add_join(
54
+ :user => {
55
+ :type => 'inner',
56
+ :table => 'config',
57
+ :condition => 'user.user_id = config.user_id',
58
+ }
59
+ )
60
+ stmt.as_sql
61
+ # => 'FROM user INNER JOIN config ON user.user_id = config.user_id'
62
+
63
+ stmt = SQL::Maker::Select.new(:quote_char => '`', :name_sep => '.')
64
+ stmt.add_join(
65
+ :user => {
66
+ :type => 'inner',
67
+ :table => 'config',
68
+ :condition => {'user.user_id' => 'config.user_id'},
69
+ }
70
+ )
71
+ stmt.as_sql
72
+ # => 'FROM `user` INNER JOIN `config` ON `user`.`user_id` = `config`.`user_id`'
73
+
74
+ stmt = SQL::Maker::Select.new
75
+ stmt.add_select('name')
76
+ stmt.add_join(
77
+ :user => {
78
+ :type => 'inner',
79
+ :table => 'config',
80
+ :condition => ['user_id'],
81
+ }
82
+ )
83
+ stmt.as_sql
84
+ # => 'SELECT name FROM user INNER JOIN config USING (user_id)'
85
+
86
+ subquery = SQL::Maker::Select.new
87
+ subquery.add_select('*')
88
+ subquery.add_from( 'foo' )
89
+ subquery.add_where( 'hoge' => 'fuga' )
90
+ stmt = SQL::Maker::Select.new
91
+ stmt.add_join(
92
+ [ subquery, 'bar' ] => {
93
+ :type => 'inner',
94
+ :table => 'baz',
95
+ :alias => 'b1',
96
+ :condition => 'bar.baz_id = b1.baz_id'
97
+ },
98
+ )
99
+ stmt.as_sql
100
+ # => "FROM (SELECT * FROM foo WHERE (hoge = ?)) bar INNER JOIN baz b1 ON bar.baz_id = b1.baz_id"
101
+
102
+ ### stmt.add_index_hint(:foo => {:type => 'USE', :list => ['index_hint']})
103
+
104
+ ### stmt.add_index_hint(:foo => 'index_hint')
105
+
106
+ ### stmt.add_index_hint(:foo => ['index_hint'])
107
+
108
+ stmt = SQL::Maker::Select.new
109
+ stmt.add_select('name')
110
+ stmt.add_from('user')
111
+ stmt.add_index_hint(:user => {:type => 'USE', :list => ['index_hint']})
112
+ stmt.as_sql
113
+ # => "SELECT name FROM user USE INDEX (index_hint)"
114
+
115
+ ### stmt.add_where('foo_id' => 'bar');
116
+
117
+ Add a new WHERE clause.
118
+
119
+ stmt = SQL::Maker::Select.new.add_select('c')
120
+ .add_from('foo')
121
+ .add_where('name' => 'john')
122
+ .add_where('type' => {:IN => %w/1 2 3/})
123
+ .as_sql
124
+ # => "SELECT c FROM foo WHERE (name = ?) AND (type IN (?, ?, ?))"
125
+
126
+ Please see SQL::Maker::Condition#add for more details.
127
+
128
+ ### stmt.add_where_raw('id = ?', [1])
129
+
130
+ Add a new WHERE clause from raw placeholder string and bind variables.
131
+
132
+ stmt = SQL::Maker::Select.new.add_select('c')
133
+ .add_from('foo')
134
+ .add_where_raw('EXISTS(SELECT * FROM bar WHERE name = ?)' => ['john'])
135
+ .add_where_raw('type IS NOT NULL')
136
+ .as_sql
137
+ # => "SELECT c FROM foo WHERE (EXISTS(SELECT * FROM bar WHERE name = ?)) AND (type IS NOT NULL)"
138
+
139
+
140
+ ### stmt.set_where(condition)
141
+
142
+ Set the WHERE clause.
143
+
144
+ condition should be instance of SQL::Maker::Condition.
145
+
146
+ cond1 = SQL::Maker::Condition.new.add("name" => "john")
147
+ cond2 = SQL::Maker::Condition.new.add("type" => {:IN => %w/1 2 3/})
148
+ stmt = SQL::Maker::Select.new.add_select('c')
149
+ .add_from('foo')
150
+ .set_where(cond1 & cond2)
151
+ .as_sql
152
+ # => "SELECT c FROM foo WHERE ((name = ?)) AND ((type IN (?, ?, ?)))"
153
+
154
+ ### stmt.add_order_by('foo');
155
+
156
+ ### stmt.add_order_by({'foo' => 'DESC'});
157
+
158
+ Add a new ORDER BY clause.
159
+
160
+ stmt = SQL::Maker::Select.new.add_select('c')
161
+ .add_from('foo')
162
+ .add_order_by('name' => 'DESC')
163
+ .add_order_by('id')
164
+ .as_sql
165
+ # => "SELECT c FROM foo ORDER BY name DESC, id"
166
+
167
+ ### stmt.add_group_by('foo');
168
+
169
+ Add a new GROUP BY clause.
170
+
171
+ stmt = SQL::Maker::Select.new.add_select('c')
172
+ .add_from('foo')
173
+ .add_group_by('id')
174
+ .as_sql
175
+ # => "SELECT c FROM foo GROUP BY id"
176
+
177
+ stmt = SQL::Maker::Select.new.add_select('c')
178
+ .add_from('foo')
179
+ .add_group_by('id' => 'DESC')
180
+ .as_sql
181
+ # => "SELECT c FROM foo GROUP BY id DESC"
182
+
183
+ ### stmt.limit(30)
184
+
185
+ ### stmt.offset(5)
186
+
187
+ Add LIMIT and OFFSET.
188
+
189
+ stmt = SQL::Maker::Select.new.add_select('c')
190
+ .add_from('foo')
191
+ .limit(30)
192
+ .offset(5)
193
+ .as_sql
194
+ # => "SELECT c FROM foo LIMIT 30 OFFSET 5"
195
+
196
+ ### stmt.add_having(:cnt => 2)
197
+
198
+ Add a HAVING clause.
199
+
200
+ stmt = SQL::Maker::Select.new.add_from('foo')
201
+ .add_select(sql_raw('COUNT(*)') => 'cnt')
202
+ .add_having(:cnt => 2)
203
+ .as_sql
204
+ # => "SELECT COUNT(*) AS cnt FROM foo HAVING (COUNT(*) = ?)"
@@ -0,0 +1,100 @@
1
+ # NAME
2
+
3
+ SQL::Maker::SelectSet - provides set functions
4
+
5
+ # SYNOPSIS
6
+
7
+ include SQL::Maker::Helper
8
+
9
+ s1 = SQL::Maker::Select.new()
10
+ .add_select('foo')
11
+ .add_from('t1')
12
+ s2 = SQL::Maker::Select.new()
13
+ .add_select('bar')
14
+ .add_from('t2')
15
+ sql_union_all( s1, s2 ).as_sql
16
+ # =>
17
+ # SQL::Maker::SelectSet.new_set(
18
+ # :operator => 'UNION ALL',
19
+ # :new_line => s1.new_line
20
+ # ).add_statement(s1)
21
+ # .add_statement(s2)
22
+ # .as_sql
23
+ # => "SELECT foo FROM t1 UNION ALL SELECT bar FROM t2"
24
+ except( s1, s2 ).as_sql
25
+ # => SQL::Maker::SelectSet.new_set( :operator => 'EXCEPT', :new_line => s1.new_line )
26
+ # .add_statement( s1 )
27
+ # .add_statement( s2 )
28
+ # .as_sql
29
+ # => "SELECT foo FROM t1 EXCEPT SELECT bar FROM t2"
30
+
31
+ # DESCRIPTION
32
+
33
+ This module provides some set functions which return a SQL::Maker::SelectSet object
34
+ inherited from SQL::Maker::Select.
35
+
36
+ # FUNCTION
37
+
38
+ Following functions will be avaiable with `include SQL::Maker::Helper`.
39
+
40
+ ### sql_union(select :SQL::Maker::Select | set :SQL::Maker::SelectSet) : SQL::Maker::SelectSet
41
+
42
+ Tow statements are combined by UNION.
43
+
44
+ ### sql_union_all(select :SQL::Maker::Select | set :SQL::Maker::SelectSet) : SQL::Maker::SelectSet
45
+
46
+ Tow statements are combined by UNION ALL.
47
+
48
+ ### sql_intersect(select :SQL::Maker::Select | set :SQL::Maker::SelectSet) : SQL::Maker::SelectSet
49
+
50
+ Tow statements are combined by INTERSECT.
51
+
52
+ ### sql_intersect_all(select :SQL::Maker::Select | set :SQL::Maker::SelectSet) : SQL::Maker::SelectSet
53
+
54
+ Tow statements are combined by INTERSECT ALL.
55
+
56
+ ### sql_except(select :SQL::Maker::Select | set :SQL::Maker::SelectSet) : SQL::Maker::SelectSet
57
+
58
+ Tow statements are combined by EXCEPT.
59
+
60
+ ### sql_except(select :SQL::Maker::Select | set :SQL::Maker::SelectSet) : SQL::Maker::SelectSet
61
+
62
+ Tow statements are combined by EXCEPT ALL.
63
+
64
+ # Class Method
65
+
66
+ ## stmt = SQL::Maker::SelectSet.new( args )
67
+
68
+ opretaor is a set operator (ex. UNION).
69
+ one and another are SQL::Maker::Select object or SQL::Maker::SelectSet object.
70
+ It returns a SQL::Maker::SelectSet object.
71
+
72
+ The parameters are:
73
+
74
+ ### new_line
75
+
76
+ Default values is "\n".
77
+
78
+ ### operator : Str
79
+
80
+ The operator. This parameter is required.
81
+
82
+ # Instance Methods
83
+
84
+ ## sql = set.as_sql : Str
85
+
86
+ Returns a new select statement.
87
+
88
+ ## bind = set.bind : Array[Str]
89
+
90
+ Returns bind variables.
91
+
92
+ ## set.add_statement(stmt) : SQL::Maker::SelectSet
93
+
94
+ This method adds new statement object. stmt must provides 'as_sql' method.
95
+
96
+ I<Return Value> is the set itself.
97
+
98
+ # SEE ALSO
99
+
100
+ [SQL::Maker::Select](./select.md)
@@ -0,0 +1,7 @@
1
+ # NAME
2
+
3
+ SQL::Maker::Util - utility functions
4
+
5
+ # DESCRITPION
6
+
7
+ Just a set of utility functions used inside of SQL::Maker
@@ -0,0 +1,242 @@
1
+ # NAME
2
+
3
+ SQL::QueryMaker - helper functions for SQL query generation
4
+
5
+ # SYNOPSIS
6
+
7
+ include SQL::Maker::Helper # adds `sql_eq`, etc
8
+
9
+ query = sql_eq(:foo => v)
10
+ query.as_sql # `foo`=?
11
+ query.bind # (v)
12
+
13
+ query = sql_lt(:foo => v)
14
+ query.as_sql # `foo`<?
15
+ query.bind # (v)
16
+
17
+ query = sql_in(:foo => [
18
+ v1, v2, v3,
19
+ ])
20
+ query.as_sql # `foo` IN (?,?,?)
21
+ query.bind # (v1,v2,v3)
22
+
23
+ query = sql_and(:foo => [
24
+ sql_ge(min),
25
+ sql_lt(max)
26
+ ])
27
+ query.as_sql # `foo`>=? AND `foo`<?
28
+ query.bind # (min,max)
29
+
30
+ query = sql_and([
31
+ sql_eq(:foo => v1),
32
+ sql_eq(:bar => v2)
33
+ ]
34
+ query.as_sql # `foo`=? AND `bar`=?
35
+ query.bind # (v1,v2)
36
+
37
+ query = sql_and([
38
+ :foo => v1,
39
+ :bar => sql_lt(v2),
40
+ ])
41
+ query.as_sql # `foo`=? AND `bar`<?
42
+ query.bind # (v1,v2)
43
+
44
+ query = sql_raw('COUNT(*)')
45
+ query.as_asl # COUNT(*)
46
+ query.bind # []
47
+
48
+ query = sql_raw('SELECT * FROM t WHERE id=?',123)
49
+ query.as_sql # SELECT * FROM t WHERE id=?
50
+ query.bind # [123]
51
+
52
+ # DESCRIPTION
53
+
54
+ This module concentrates on providing an expressive, concise way to declare SQL
55
+ expressions by exporting carefully-designed functions.
56
+ It is possible to use the module to generate SQL query conditions and pass them
57
+ as arguments to other more versatile query builders such as SQL::Maker.
58
+
59
+ The functions exported by the module instantiate comparator objects that build
60
+ SQL expressions when their as_sql method are being invoked.
61
+ There are two ways to specify the names of the columns to the comparator; to
62
+ pass in the names as argument or to specify then as an argument to the
63
+ as_sql method.
64
+
65
+ # FUNCTIONS
66
+
67
+ ### sql_eq([column,] value)
68
+ ### sql_eq(column => value)
69
+
70
+ ### sql_lt([column,] value)
71
+ ### sql_lt(column => value)
72
+
73
+ ### sql_gt([column,] value)
74
+ ### sql_gt(column => value)
75
+
76
+ ### sql_le([column,] value)
77
+ ### sql_le(column => value)
78
+
79
+ ### sql_ge([column,] value)
80
+ ### sql_ge(column => value)
81
+
82
+ ### sql_like([column,] value)
83
+ ### sql_like(column => value)
84
+
85
+ ### sql_is_null([column])
86
+
87
+ ### sql_is_not_null([column])
88
+
89
+ ### sql_not([column])
90
+
91
+ ### sql_between([column,] min_value, max_value)
92
+ ### sql_between([column,] min_value, max_value)
93
+
94
+ ### sql_not_between([column,] min_value, max_value)
95
+
96
+ ### sql_in([column,] values)
97
+ ### sql_in(column => values)
98
+
99
+ ### sql_not_in([column,] \@values)
100
+ ### sql_not_in(column => \@values)
101
+
102
+ Instantiates a comparator object that tests a column against given value(s).
103
+
104
+ ### sql_and([column,] conditions)
105
+ ### sql_and(column => conditions)
106
+
107
+ ### sql_or([column,] conditions)
108
+ ### sql_or(column => conditions)
109
+
110
+ Aggregates given comparator objects into a logical expression.
111
+
112
+ If specified, the column name is pushed down to the arguments when the
113
+ as_sql method is being called, as show in the second example below.
114
+
115
+ sql_and([ # => `foo`=? AND `bar`<?
116
+ sql_eq("foo" => v1),
117
+ sql_lt("bar" => v2)
118
+ ])
119
+
120
+ sql_and("foo" => [ # => `foo`>=min OR `foo`<max
121
+ sql_ge(min),
122
+ sql_lt(max),
123
+ ])
124
+
125
+ ### sql_and(conditions)
126
+
127
+ ### sql_or(conditions)
128
+
129
+ Aggregates given pairs of column names and comparators into a logical
130
+ expression.
131
+
132
+ The value part is composed of as the argument to the = operator if it is
133
+ not a blessed reference.
134
+
135
+ query = sql_and({
136
+ :foo => 'abc',
137
+ :bar => sql_lt(123),
138
+ })
139
+ query.as_sql # => `foo`=? AND bar<?
140
+ query.bind # => ('abc', 123)
141
+
142
+
143
+ ### sql_op([column,] op_sql, bind_values)
144
+
145
+ Generates a comparator object that tests a column using the given SQL and
146
+ values. <@> in the given SQL are replaced by the column name (specified
147
+ either by the argument to the function or later by the call to the <as_sql>
148
+ method), and <?> are substituted by the given bind values.
149
+
150
+ ### sql_raw(sql[, bind_values])
151
+ ### sql_raw(sql => bind_values)
152
+
153
+ Generates a comparator object from raw SQL and bind values. <?> in the
154
+ given SQL are replaced by the bind values.
155
+
156
+ ### obj.as_sql
157
+
158
+ ### obj.as_sql(column_name)
159
+
160
+ ### obj.as_sql(column_name, quote_identifier_cb)
161
+
162
+ Compiles given comparator object and returns an SQL expression.
163
+ Corresponding bind values should be obtained by calling the bind method.
164
+
165
+ The function optionally accepts a column name to which the comparator object
166
+ should be bound; an error is thrown if the comparator object is already bound
167
+ to another column.
168
+
169
+ The function also accepts a callback for quoting the identifiers. If omitted,
170
+ the identifiers are quoted using ` after being splitted using .; i.e. a
171
+ column designated as foo.bar is quoted as `foo`.`bar`.
172
+
173
+ ### obj.bind
174
+
175
+ Returns a list of bind values corresponding to the SQL expression returned by
176
+ the as_sql method.
177
+
178
+ # CHEAT SHEET
179
+
180
+ IN: sql_eq('foo' => 'bar')
181
+ OUT QUERY: '`foo` = ?'
182
+ OUT BIND: ['bar']
183
+
184
+ IN: sql_in('foo' => ['bar', 'baz'])
185
+ OUT QUERY: '`foo` IN (?,?)'
186
+ OUT BIND: ['bar','baz']
187
+
188
+ IN: sql_and([sql_eq('foo' => 'bar'), sql_eq('baz' => 123)])
189
+ OUT QUERY: '(`foo` = ?) AND (`baz` = ?)'
190
+ OUT BIND: ['bar',123]
191
+
192
+ IN: sql_and('foo' => [sql_ge(3), sql_lt(5)])
193
+ OUT QUERY: '(`foo` >= ?) AND (`foo` < ?)'
194
+ OUT BIND: [3,5]
195
+
196
+ IN: sql_or([sql_eq('foo' => 'bar'), sql_eq('baz' => 123)])
197
+ OUT QUERY: '(`foo` = ?) OR (`baz` = ?)'
198
+ OUT BIND: ['bar',123]
199
+
200
+ IN: sql_or('foo' => ['bar', 'baz'])
201
+ OUT QUERY: '(`foo` = ?) OR (`foo` = ?)'
202
+ OUT BIND: ['bar','baz']
203
+
204
+ IN: sql_is_null('foo')
205
+ OUT QUERY: '`foo` IS NULL'
206
+ OUT BIND: []
207
+
208
+ IN: sql_is_not_null('foo')
209
+ OUT QUERY: '`foo` IS NOT NULL'
210
+ OUT BIND: []
211
+
212
+ IN: sql_between('foo', 1, 2)
213
+ OUT QUERY: '`foo` BETWEEN ? AND ?'
214
+ OUT BIND: [1,2]
215
+
216
+ IN: sql_not('foo')
217
+ OUT QUERY: 'NOT `foo`'
218
+ OUT BIND: []
219
+
220
+ IN: sql_op('apples', 'MATCH (@) AGAINST (?)', ['oranges'])
221
+ OUT QUERY: 'MATCH (`apples`) AGAINST (?)'
222
+ OUT BIND: ['oranges']
223
+
224
+ IN: sql_raw('COUNT(*)')
225
+ OUT QUERY: 'COUNT(*)'
226
+ OUT BIND: []
227
+
228
+ IN: sql_raw('SELECT * FROM t WHERE id=?',123)
229
+ OUT QUERY: 'SELECT * FROM t WHERE id=?'
230
+ OUT BIND: [123]
231
+
232
+ IN: sql_in('foo' => [123,sql_raw('SELECT id FROM t WHERE cat=?',5)])
233
+ OUT QUERY: '`foo` IN (?,(SELECT id FROM t WHERE cat=?))'
234
+ OUT BIND: [123,5]
235
+
236
+ # AUTHOR
237
+
238
+ Natoshi Seo (Originally designed by Kazuho Oku as a Perl module)
239
+
240
+ # LICENSE
241
+
242
+ This library is free software; you can redistribute it and/or modify it under the MIT License.