sql-maker 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.