quote-sql 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +34 -4
- data/lib/quote_sql/quoter.rb +32 -7
- data/lib/quote_sql/test.rb +0 -1
- data/lib/quote_sql.rb +10 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e32e2e164efd0cfb007de82abb8870b13d5b432856d21af6f75faed9d2d1107
|
4
|
+
data.tar.gz: 141ef285fbb563e649d5c4b71faa8b1d9d67066d1c600dd9d85c7dd5ee017edc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e13010de0021284de07a99e33822e54b530d3d5dfbc5986028327c903b5c3ab55ceadcf0042eb7207eea8245f31f57db5811a0f902fe8f68eb9a435c02ff255
|
7
|
+
data.tar.gz: f178c03540bdea0b38c8278ace489954d9efff1786fa76b804950c11bf60f2ac3162f6ca3ac9f142f08dc62d830e10cd8835786618175a922b7eb183e71c89bc
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# QuoteSql - Tool to build and run SQL queries easier
|
2
2
|
I've built this library as an addition to ActiveRecord and Arel, however you can use it with any sql database and plain Ruby.
|
3
|
+
However currently it is just used with PostgreSQL.
|
3
4
|
|
4
5
|
Creating SQL queries and proper quoting becomes complicated especially when you need advanced queries.
|
5
6
|
|
@@ -8,7 +9,7 @@ I created this library while coding for different projects, and had lots of Here
|
|
8
9
|
|
9
10
|
My strategy is to segment SQL Queries in readable junks, which can be individually tested and then combine their sql to the final query.
|
10
11
|
|
11
|
-
QuoteSql is used in production, but is still
|
12
|
+
QuoteSql is used in production, but is still bleeding edge - and there is not a fully sync between doc and code.
|
12
13
|
|
13
14
|
If you think QuoteSql is interesting, let's chat!
|
14
15
|
Also if you have problems using it, just drop me a note.
|
@@ -23,6 +24,10 @@ Best Martin
|
|
23
24
|
`QuoteSql.new("SELECT %field__text").quote(field__text: 9).to_sql`
|
24
25
|
=> SELECT 9::TEXT
|
25
26
|
|
27
|
+
### Rails models
|
28
|
+
`QuoteSql.new(Users.limit(10).select("%columns")).quote(columns: ['first_name', 'last_name').to_sql`
|
29
|
+
=> SELECT first_name, last_name FROM users LIMIT 10
|
30
|
+
|
26
31
|
### Quoting of columns and table from a model - or an object responding to table_name and column_names or columns
|
27
32
|
`QuoteSql.new("SELECT %columns FROM %table_name").quote(table: User).to_sql`
|
28
33
|
=> SELECT "id",firstname","lastname",... FROM "users"
|
@@ -47,10 +52,18 @@ Values are be ordered in sequence of columns. Missing value entries are substitu
|
|
47
52
|
ON CONFLICT ("id") DO NOTHING
|
48
53
|
|
49
54
|
### Columns from a list
|
50
|
-
`QuoteSql.new("SELECT %columns").quote(columns: [:a, :"b.c", c:
|
51
|
-
=> SELECT "a","b"."c",jsonb_build_object('d',
|
55
|
+
`QuoteSql.new("SELECT %columns").quote(columns: [:a, :"b.c", c: {d: field}]).to_sql`
|
56
|
+
=> SELECT "a","b"."c",jsonb_build_object('d', field) AS c
|
57
|
+
|
58
|
+
`QuoteSql.new("SELECT %columns").quote(columns: [:a, :"b.c", c: {d: field, nil: false}]).to_sql`
|
59
|
+
=> SELECT "a","b"."c",jsonb_strip_nulls(jsonb_build_object('d', 1)) AS c
|
60
|
+
|
61
|
+
|
62
|
+
### Execution of a query
|
63
|
+
`QuoteSql.new("Select 1 as abc").result` => [{:abc=>1}]
|
52
64
|
|
53
|
-
|
65
|
+
|
66
|
+
## Substitution of mixins with quoted values
|
54
67
|
In the SQL matches of `%foo` or `%{foo}` or `%foo_4_bar` or `%{foo_4_bar}` the *"mixins"*
|
55
68
|
are substituted with quoted values
|
56
69
|
the values are looked up from the options given in the quotes method
|
@@ -106,6 +119,16 @@ with optional array dimension
|
|
106
119
|
- +String+ value will become the expression, the key the AS {result: "SUM(*)"} => SUM(*) AS result
|
107
120
|
- +Proc+ are executed with the +QuoteSQL::Quoter+ object as parameter and added as raw SQL
|
108
121
|
|
122
|
+
## Shortcuts and functions
|
123
|
+
- `QuoteSQL("select %abc", abc: 1)` == `QuoteSql.new("select %abc").quote(abc: 1)`
|
124
|
+
- when you have in your initializer `String.include QuoteSql::Extension` you can do e.g. `"select %abc".quote_sql(abc: 1)`
|
125
|
+
- when you have in your initializer `ActiveRecord::Relation.include QuoteSql::Extension` you can do e.g. `Profile.limit(10).select('%abc').quote_sql(abc: 1)`
|
126
|
+
|
127
|
+
## Debug and dump
|
128
|
+
If you have pg_format installed you can get the resulting query inspected:
|
129
|
+
`QuoteSql.new("select %abc").quote(abc: 1).dsql`
|
130
|
+
|
131
|
+
|
109
132
|
## Installing
|
110
133
|
`gem install quote-sql`
|
111
134
|
or in Gemfile
|
@@ -121,3 +144,10 @@ Add this to config/initializers/quote_sql.rb
|
|
121
144
|
ActiveRecord::Relation.include QuoteSql::Extension
|
122
145
|
end
|
123
146
|
|
147
|
+
## Todos
|
148
|
+
- Functionalities not yet used in my production might not work
|
149
|
+
- More documentation
|
150
|
+
- Tests missing
|
151
|
+
- Missing functionalities
|
152
|
+
- Prepare
|
153
|
+
- which other - let me know!
|
data/lib/quote_sql/quoter.rb
CHANGED
@@ -13,7 +13,7 @@ class QuoteSql
|
|
13
13
|
when /(?:^|(.*)_)table$/i
|
14
14
|
table
|
15
15
|
when /(?:^|(.*)_)columns?$/i
|
16
|
-
|
16
|
+
columns
|
17
17
|
when /(?:^|(.*)_)(table_name?s?)$/i
|
18
18
|
table_name
|
19
19
|
when /(?:^|(.*)_)(column_name?s?)$/i
|
@@ -22,9 +22,9 @@ class QuoteSql
|
|
22
22
|
ident_name
|
23
23
|
when /(?:^|(.*)_)constraints?$/i
|
24
24
|
quotable.to_s
|
25
|
-
when /(?:^|(.*)_)(raw|sql)$/
|
25
|
+
when /(?:^|(.*)_)(raw|sql)$/i
|
26
26
|
quotable.to_s
|
27
|
-
when /(?:^|(.*)_)(values?)$/
|
27
|
+
when /(?:^|(.*)_)(values?)$/i
|
28
28
|
values
|
29
29
|
else
|
30
30
|
quote
|
@@ -121,6 +121,20 @@ class QuoteSql
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
+
def columns(item = @quotable)
|
125
|
+
if item.respond_to?(:column_names)
|
126
|
+
item = item.column_names
|
127
|
+
elsif item.class.respond_to?(:column_names)
|
128
|
+
item = item.class.column_names
|
129
|
+
elsif item.is_a?(Array)
|
130
|
+
if item[0].respond_to?(:name)
|
131
|
+
item = item.map(&:name)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
@qsql.column_names ||= item
|
135
|
+
ident_name(item)
|
136
|
+
end
|
137
|
+
|
124
138
|
def column_names(item = @quotable)
|
125
139
|
if item.respond_to?(:column_names)
|
126
140
|
item = item.column_names
|
@@ -133,6 +147,13 @@ class QuoteSql
|
|
133
147
|
ident_name(item)
|
134
148
|
end
|
135
149
|
|
150
|
+
def json_build_object(h)
|
151
|
+
compact = h.delete(nil) == false
|
152
|
+
rv = "jsonb_build_object(" + h.map { "'#{_1}',#{_2}" }.join(",") + ")"
|
153
|
+
return rv unless compact
|
154
|
+
"jsonb_strip_nulls(#{rv})"
|
155
|
+
end
|
156
|
+
|
136
157
|
def ident_name(item = @quotable)
|
137
158
|
case item
|
138
159
|
when Array
|
@@ -147,14 +168,18 @@ class QuoteSql
|
|
147
168
|
end
|
148
169
|
end.join(",")
|
149
170
|
when Hash
|
150
|
-
item.map do
|
151
|
-
case
|
171
|
+
item.map do |k,v|
|
172
|
+
case v
|
152
173
|
when Symbol
|
153
|
-
_quote_column_name(
|
174
|
+
_quote_column_name(k, v)
|
154
175
|
when String
|
155
|
-
"#{
|
176
|
+
"#{v} AS #{k}"
|
156
177
|
when Proc
|
157
178
|
item.call(self)
|
179
|
+
when Hash
|
180
|
+
"#{json_build_object(v)} AS #{k}"
|
181
|
+
else
|
182
|
+
raise ArgumentError
|
158
183
|
end
|
159
184
|
end.join(",")
|
160
185
|
else
|
data/lib/quote_sql/test.rb
CHANGED
data/lib/quote_sql.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Dir.glob(__FILE__.sub(/\.rb$/, "/*.rb")).each { require(_1) unless _1[/test\.rb$/] }
|
1
|
+
Dir.glob(__FILE__.sub(/\.rb$/, "/*.rb")).each { require(_1) unless _1[/(deprecated|test)\.rb$/] }
|
2
2
|
|
3
3
|
# Tool to build and run SQL queries easier
|
4
4
|
#
|
@@ -294,6 +294,15 @@ time(stamp)?(_\\(\d+\\))?(_with(out)?_time_zone)?
|
|
294
294
|
|
295
295
|
extend Quoting
|
296
296
|
|
297
|
+
def self.test
|
298
|
+
require __dir__ + "/quote_sql/test.rb"
|
299
|
+
Test
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def QuoteSQL(sql, **options)
|
304
|
+
rv = QuoteSql.new(sql)
|
305
|
+
options.any? ? rv.quote(**options) : rv
|
297
306
|
end
|
298
307
|
|
299
308
|
QuoteSql.include QuoteSql::Formater
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quote-sql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Kufner
|
@@ -39,9 +39,9 @@ require_paths:
|
|
39
39
|
- lib
|
40
40
|
required_ruby_version: !ruby/object:Gem::Requirement
|
41
41
|
requirements:
|
42
|
-
- - "
|
42
|
+
- - "~>"
|
43
43
|
- !ruby/object:Gem::Version
|
44
|
-
version: '0'
|
44
|
+
version: '3.0'
|
45
45
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - ">="
|