hash_sql 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 +7 -0
- data/.gitignore +15 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +104 -0
- data/Rakefile +2 -0
- data/hash_sql.gemspec +25 -0
- data/lib/hash_sql.rb +86 -0
- data/lib/hash_sql/version.rb +3 -0
- data/spec/hash_sql_spec.rb +29 -0
- data/spec/spec_helper.rb +1 -0
- metadata +112 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: da65f98d338f1af5177476ab817339484ea99364
|
4
|
+
data.tar.gz: b10cca603a1a2bd644e70a61589fe98f3d729aab
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9d25a94ea23473b68915651d151f50988422a8d69650e276a584085287e845a8a01728d335c315bdfd8ccf5d3873b8f8f3ba7959b892500e099db4479306d551
|
7
|
+
data.tar.gz: b779a6ba3e2ef6fd1353ca3cfaf603eebd1da669bd87e680b6e987e48d97f67e37d971cc63d00109186d5e3bdc27888f5d19505c01d9e67a66a61f3db619d7da
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Nick Delos Santos (code@nickdsantos.com)
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# HashSql
|
2
|
+
|
3
|
+
Create SQL statements using Hashes.
|
4
|
+
*(Currently only supports SELECT statements.)*
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'hash_sql'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install hash_sql
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
# Basic query
|
26
|
+
# Will produce:
|
27
|
+
# SELECT UID,profile.firstName,profile.lastName,profile.email
|
28
|
+
# FROM accounts
|
29
|
+
# WHERE profile.email='test05@mailinator.com'
|
30
|
+
# AND (profile.firstName='Five' AND profile.lastName='Zero')
|
31
|
+
#
|
32
|
+
query = HashSql.select_statement(:accounts,
|
33
|
+
fields: ['UID', 'profile.firstName', 'profile.lastName', 'profile.email'],
|
34
|
+
filter: {
|
35
|
+
"profile.email" => "='test05@mailinator.com'",
|
36
|
+
and: { "profile.firstName" => "='Five'", "profile.lastName" => "='Zero'" }
|
37
|
+
}
|
38
|
+
)
|
39
|
+
|
40
|
+
# Nested conditions
|
41
|
+
# Will produce:
|
42
|
+
# SELECT UID,profile.firstName,profile.lastName,profile.email
|
43
|
+
# FROM accounts
|
44
|
+
# WHERE profile.email='test05@mailinator.com'
|
45
|
+
# AND (profile.firstName='Five'
|
46
|
+
# OR (profile.lastName='Zero' AND isActive=true))
|
47
|
+
#
|
48
|
+
query = HashSql.select_statement(:accounts,
|
49
|
+
fields: ['UID', 'profile.firstName', 'profile.lastName', 'profile.email'],
|
50
|
+
filter: {
|
51
|
+
"profile.email" => "='test05@mailinator.com'",
|
52
|
+
and: { "profile.firstName" => "='Five'", or: { "profile.lastName" => "='Zero'", and: { "isActive" => "=true" } } }
|
53
|
+
}
|
54
|
+
)
|
55
|
+
```
|
56
|
+
|
57
|
+
## Filter Hash
|
58
|
+
|
59
|
+
### Comparison
|
60
|
+
The filter to use for searching accounts. The key is the field name
|
61
|
+
to set the filter on, and the value is the concatenation of the
|
62
|
+
operator to use for comparison and the value used for comparing.
|
63
|
+
Example:
|
64
|
+
```ruby
|
65
|
+
{ email: "='test@abc.com'"}
|
66
|
+
```
|
67
|
+
|
68
|
+
### AND and ORs:
|
69
|
+
The logical operations between filters can be AND or OR and the
|
70
|
+
it could be set by setting the key to either "and:" or "or:"
|
71
|
+
Example:
|
72
|
+
```ruby
|
73
|
+
{ email: "='test@abc.com", and: {firstname: "='Nick'"} }
|
74
|
+
```
|
75
|
+
Will be translated to: ```email='test@abc.com' AND firstname = 'Nick'```
|
76
|
+
|
77
|
+
If multiple entries are placed inside an "and:" or "or:" they will
|
78
|
+
"ANDed" or "ORed" together.
|
79
|
+
Example:
|
80
|
+
```ruby
|
81
|
+
{ email: "='test@abc.com", and: {firstname: "='Nick'", lastname: "='DS'"} }
|
82
|
+
```
|
83
|
+
Will be translated to ```email='test@abc.com' AND (firstname = 'Nick' AND lastname = 'DS')```
|
84
|
+
|
85
|
+
Example:
|
86
|
+
```ruby
|
87
|
+
{ email: "='test@abc.com", or: {firstname: "='Nick'", lastname: "='DS'"} }
|
88
|
+
```
|
89
|
+
Will be translated to ```email='test@abc.com' OR (firstname = 'Nick' OR lastname = 'DS')```
|
90
|
+
|
91
|
+
### NESTING
|
92
|
+
Example:
|
93
|
+
```ruby
|
94
|
+
{ email: "='test@abc.com", and: {firstname: "='Nick'", or: {lastname: "='DS'"}} }
|
95
|
+
```
|
96
|
+
Will be translated to ```email='test@abc.com' AND (firstname = 'Nick' OR lastname = 'DS') ```
|
97
|
+
|
98
|
+
## Contributing
|
99
|
+
|
100
|
+
1. Fork it ( https://github.com/nicknux/hash_sql/fork )
|
101
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
102
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
103
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
104
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/hash_sql.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hash_sql/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "hash_sql"
|
8
|
+
spec.version = HashSql::VERSION
|
9
|
+
spec.authors = ["nicknux"]
|
10
|
+
spec.email = ["code@nickdsantos.com"]
|
11
|
+
spec.summary = %q{Create SQL statements using Hashes.}
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency 'pry-byebug'
|
24
|
+
spec.add_development_dependency 'rspec'
|
25
|
+
end
|
data/lib/hash_sql.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require "hash_sql/version"
|
2
|
+
|
3
|
+
module HashSql
|
4
|
+
# Creates a SQL Select Statement
|
5
|
+
# @param [String] table The table name to select records from
|
6
|
+
# @param [Hash] options Additional options for the query
|
7
|
+
# @option options [Array] fields An array of field names to return in the seach result
|
8
|
+
# @option options [Hash] filter
|
9
|
+
# The filter to use for searching accounts. The key is the field name
|
10
|
+
# to set the filter on, and the value is the concatenation of the
|
11
|
+
# operator to use for comparison and the value used for comparing.
|
12
|
+
# Example: { email: "='test@abc.com'"}
|
13
|
+
#
|
14
|
+
# AND and ORs:
|
15
|
+
# The logical operations between filters can be AND or OR and
|
16
|
+
# it could be set by setting the key to either "and:" or "or:"
|
17
|
+
# Example: { email: "='test@abc.com", and: {firstname: "='Nick'"} }
|
18
|
+
# Will be translated to email='test@abc.com' AND firstname = 'Nick'
|
19
|
+
#
|
20
|
+
# If multiple entries are placed inside an "and:" or "or:" they will
|
21
|
+
# "ANDed" or "ORed" together.
|
22
|
+
# Example: { email: "='test@abc.com", and: {firstname: "='Nick'", lastname: "='DS'"} }
|
23
|
+
# Will be translated to email='test@abc.com' AND (firstname = 'Nick' AND lastname = 'DS')
|
24
|
+
#
|
25
|
+
# Example: { email: "='test@abc.com", or: {firstname: "='Nick'", lastname: "='DS'"} }
|
26
|
+
# Will be translated to email='test@abc.com' OR (firstname = 'Nick' OR lastname = 'DS')
|
27
|
+
#
|
28
|
+
# NESTING
|
29
|
+
# Example: { email: "='test@abc.com", and: {firstname: "='Nick'", or: {lastname: "='DS'"}} }
|
30
|
+
# Will be translated to:
|
31
|
+
# email='test@abc.com' AND (firstname = 'Nick' OR lastname = 'DS')
|
32
|
+
# @option options [Hash] :order_by The order in which the results are returned. The key is the
|
33
|
+
# field to order on, and the value is :ASC or :DESC
|
34
|
+
# @option options [Number] :limit the number of results to return
|
35
|
+
# @return [Hash]
|
36
|
+
#
|
37
|
+
def self.select_statement(table, options={})
|
38
|
+
fields = options[:fields]
|
39
|
+
order_by = options[:order_by]
|
40
|
+
limit = options[:limit]
|
41
|
+
filter = options[:filter]
|
42
|
+
query = "SELECT #{fields.join(',')} FROM #{table}"
|
43
|
+
|
44
|
+
filter_string = " WHERE #{parse_filter(filter, nil, '')}" unless filter.nil?
|
45
|
+
order_string = " ORDER BY #{parse_order_by(order_by)}" unless order_by.nil?
|
46
|
+
limit_string = " LIMIT #{limit}" unless limit.nil?
|
47
|
+
|
48
|
+
filter_string ||= ''
|
49
|
+
order_string ||= ''
|
50
|
+
limit_string ||= ''
|
51
|
+
|
52
|
+
query = query + filter_string + order_string + limit_string
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def self.parse_filter(filter={}, operator, filter_string)
|
58
|
+
filter.each_with_index do |(k, v), index|
|
59
|
+
if k == :and || k == :or
|
60
|
+
filter_string += "#{k.to_s.upcase} " unless index == 0
|
61
|
+
filter_string += '(' unless v.count == 1
|
62
|
+
filter_string = parse_filter(v, k, filter_string)
|
63
|
+
filter_string += ')' unless v.count == 1
|
64
|
+
else
|
65
|
+
filter_string += "#{k}#{v} "
|
66
|
+
if !operator.nil? && index < filter.count - 1 && filter.values[index + 1].class != Hash
|
67
|
+
filter_string += "#{operator.to_s.upcase} "
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
filter_string.rstrip
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.parse_order_by(order_by={})
|
75
|
+
order_string = ''
|
76
|
+
order_by.each_with_index do |(k,v), index|
|
77
|
+
if v != :ASC || v != :DESC
|
78
|
+
v = :ASC
|
79
|
+
end
|
80
|
+
order_string += "#{k} #{v.to_s.upcase}"
|
81
|
+
order_string += ',' unless index == order_by.count - 1
|
82
|
+
end
|
83
|
+
|
84
|
+
order_string
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe HashSql do
|
4
|
+
describe '#query_basic' do
|
5
|
+
it 'returns a query statement using a simple filter' do
|
6
|
+
query = HashSql.select_statement(:accounts,
|
7
|
+
fields: ['UID', 'profile.firstName', 'profile.lastName', 'profile.email'],
|
8
|
+
filter: {
|
9
|
+
"profile.email" => "='test05@mailinator.com'",
|
10
|
+
and: { "profile.firstName" => "='Five'", "profile.lastName" => "='Zero'" }
|
11
|
+
}
|
12
|
+
)
|
13
|
+
expect(query).to eq("SELECT UID,profile.firstName,profile.lastName,profile.email FROM accounts WHERE profile.email='test05@mailinator.com' AND (profile.firstName='Five' AND profile.lastName='Zero')")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#query_nested' do
|
18
|
+
it 'returns a query statement using nested filters' do
|
19
|
+
query = HashSql.select_statement(:accounts,
|
20
|
+
fields: ['UID', 'profile.firstName', 'profile.lastName', 'profile.email'],
|
21
|
+
filter: {
|
22
|
+
"profile.email" => "='test05@mailinator.com'",
|
23
|
+
and: { "profile.firstName" => "='Five'", or: { "profile.lastName" => "='Zero'", and: { "isActive" => "=true" } } }
|
24
|
+
}
|
25
|
+
)
|
26
|
+
expect(query).to eq("SELECT UID,profile.firstName,profile.lastName,profile.email FROM accounts WHERE profile.email='test05@mailinator.com' AND (profile.firstName='Five' OR (profile.lastName='Zero' AND isActive=true))")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'hash_sql'
|
metadata
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hash_sql
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- nicknux
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry-byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: ''
|
70
|
+
email:
|
71
|
+
- code@nickdsantos.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE.txt
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- hash_sql.gemspec
|
82
|
+
- lib/hash_sql.rb
|
83
|
+
- lib/hash_sql/version.rb
|
84
|
+
- spec/hash_sql_spec.rb
|
85
|
+
- spec/spec_helper.rb
|
86
|
+
homepage: ''
|
87
|
+
licenses:
|
88
|
+
- MIT
|
89
|
+
metadata: {}
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
requirements: []
|
105
|
+
rubyforge_project:
|
106
|
+
rubygems_version: 2.4.3
|
107
|
+
signing_key:
|
108
|
+
specification_version: 4
|
109
|
+
summary: Create SQL statements using Hashes.
|
110
|
+
test_files:
|
111
|
+
- spec/hash_sql_spec.rb
|
112
|
+
- spec/spec_helper.rb
|