query_generator 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c457fa2ad87d9d0e8ec0bc43bdad3dbf648e3fb2
4
+ data.tar.gz: 27d7c3f09e72a530860af6ad08261625418755eb
5
+ SHA512:
6
+ metadata.gz: 2b7d52c23af43c9adb652e8cab777c9d418dfb777d587cf7711b5bdf9b7f20f448f5531ff28868107fc66f1e8616b6c84e9d08d47d4dd7c4283d0a3c36a61560
7
+ data.tar.gz: 2a5bb852956e1353fb984105e46aea0cc0842b1f86473b493709846f5e7aee3582a2f2e9e177e902be83f5e04ede3900b0b2fb533c84f6ea40a02263d59f6496
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.2
5
+ before_install: gem install bundler -v 1.16.1
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in query_generator.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ query_generator (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ coderay (1.1.2)
10
+ diff-lcs (1.3)
11
+ method_source (0.9.2)
12
+ pry (0.12.2)
13
+ coderay (~> 1.1.0)
14
+ method_source (~> 0.9.0)
15
+ rake (10.5.0)
16
+ rspec (3.8.0)
17
+ rspec-core (~> 3.8.0)
18
+ rspec-expectations (~> 3.8.0)
19
+ rspec-mocks (~> 3.8.0)
20
+ rspec-core (3.8.0)
21
+ rspec-support (~> 3.8.0)
22
+ rspec-expectations (3.8.3)
23
+ diff-lcs (>= 1.2.0, < 2.0)
24
+ rspec-support (~> 3.8.0)
25
+ rspec-mocks (3.8.0)
26
+ diff-lcs (>= 1.2.0, < 2.0)
27
+ rspec-support (~> 3.8.0)
28
+ rspec-support (3.8.0)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ bundler (~> 1.16)
35
+ pry
36
+ query_generator!
37
+ rake (~> 10.0)
38
+ rspec (~> 3.0)
39
+
40
+ BUNDLED WITH
41
+ 1.16.1
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # QueryGenerator
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/query_generator`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'query_generator'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install query_generator
22
+
23
+ ## Usage
24
+
25
+ ```
26
+ require 'query_generator'
27
+
28
+ TABLE_NAME = 'products'.freeze
29
+ table = QueryGenerator::Table.new(TABLE_NAME)
30
+ table.select.where(
31
+ [:user_id, :eq, 1]
32
+ ).to_s
33
+ # => SELECT * FROM products WHERE user_id = 1
34
+ ```
35
+
36
+ ## Development
37
+
38
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
39
+
40
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
41
+
42
+ ## Contributing
43
+
44
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/query_generator.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "query_generator"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,11 @@
1
+ require "query_generator/version"
2
+ require 'query_generator/table'
3
+ require 'date'
4
+ require 'query_generator/strict_mode_error'
5
+ require 'query_generator/select_already_used'
6
+ require 'query_generator/where_does_not_used'
7
+ require 'query_generator/not_include_type'
8
+
9
+ module QueryGenerator
10
+ # Your code goes here...
11
+ end
@@ -0,0 +1,4 @@
1
+ module QueryGenerator
2
+ class NotIncludeType < StandardError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module QueryGenerator
2
+ class SelectAlreadyUsed < StandardError
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module QueryGenerator
2
+ class StrictModeError < StandardError; end
3
+ end
@@ -0,0 +1,148 @@
1
+ module QueryGenerator
2
+ class Table
3
+ attr_reader :table, :query, :select_used, :where_used, :strict
4
+ def initialize(table, strict: true)
5
+ @table = table
6
+ @query = ''
7
+ @select_used = false
8
+ @where_used = false
9
+ @strict = strict
10
+ end
11
+
12
+ def select(*columns)
13
+ raise SelectAlreadyUsed if select_used
14
+
15
+ @query = "SELECT #{result_columns(columns)} FROM #{table}"
16
+ @select_used = true
17
+ self
18
+ end
19
+
20
+ def where(*conds)
21
+ @query += if where_used
22
+ " AND #{expand_conds(conds)}"
23
+ else
24
+ " WHERE #{expand_conds(conds)}"
25
+ end
26
+ @where_used = true
27
+ self
28
+ end
29
+
30
+ def or(*conds)
31
+ # NOTE: OR句はWHERE句のあとに使うので単独では使わせない
32
+ raise WhereDoesNotUsed unless where_used
33
+
34
+ @query += " OR #{expand_conds(conds, 'OR')}"
35
+ self
36
+ end
37
+
38
+ def group_by(*columns)
39
+ @query += " GROUP BY #{columns.join(',')}"
40
+ self
41
+ end
42
+
43
+ def order_by(by, order_type = :ASC)
44
+ raise NotIncludeType unless [:ASC, :DESC].include?(order_type.upcase)
45
+
46
+ @query += " ORDER BY #{by} #{order_type.upcase}"
47
+ self
48
+ end
49
+
50
+ def run
51
+ raise StrictModeError if !where_used && strict
52
+ # FIXME: 各DBへSQLを実行しその結果を取得する
53
+ end
54
+
55
+ def to_s
56
+ raise StrictModeError if !where_used && strict
57
+
58
+ puts query
59
+ end
60
+
61
+ def left_outer_join(join_table, base, to)
62
+ "LEFT #{outer_join(join_table, base, to)}"
63
+ end
64
+
65
+ def right_outer_join(join_table, base, to)
66
+ "RIGHT #{outer_join(join_table, base, to)}"
67
+ end
68
+
69
+ private
70
+
71
+ def outer_join(join_table, base, to)
72
+ "OUTER JOIN #{join_table} ON #{base} = #{to}"
73
+ end
74
+
75
+ def expand_conds(conds, join_cond = 'AND')
76
+ conds.map do |s_exp|
77
+ "#{car(s_exp)} #{parse_cond(cdr(s_exp))}"
78
+ end.join(" #{join_cond} ")
79
+ end
80
+
81
+ def parse_cond(s_exp)
82
+ case car(s_exp)
83
+ when :is then "IS #{parse_type(car(cdr(s_exp)))}"
84
+ when :eq then "= #{parse_type(car(cdr(s_exp)))}"
85
+ when :not_eq then "!= #{parse_type(car(cdr(s_exp)))}"
86
+ when :in then "IN #{parse_in(cdr(s_exp))}"
87
+ when :like then "LIKE #{parse_type(car(cdr(s_exp)))}"
88
+ when :between
89
+ from_and_to = car(cdr(s_exp))
90
+ from = car(from_and_to)
91
+ to = car(cdr(from_and_to))
92
+ "BETWEEN '#{parse_date_and_timestamp(from)}' AND '#{parse_date_and_timestamp(to)}'"
93
+ end
94
+ end
95
+
96
+ def parse_date_and_timestamp(time)
97
+ case time
98
+ when Date then time.strftime('%Y-%m-%d')
99
+ when Time then time.strftime('%Y-%m-%d %H:%M:%S')
100
+ end
101
+ end
102
+
103
+ def parse_in(list)
104
+ # NOTE: IN句には配列を渡す想定だが[]で出力されるため()に置換する
105
+ list.flatten.to_s.sub('[', '(').sub(']', ')')
106
+ end
107
+
108
+ def parse_type(atom)
109
+ case atom
110
+ when NilClass then 'NULL'
111
+ when Fixnum, Float, TrueClass, FalseClass then atom
112
+ when String then "'#{atom}'"
113
+ when Time, Date then "'#{parse_date_and_timestamp(atom)}'"
114
+ end
115
+ end
116
+
117
+ def car(list)
118
+ list.first
119
+ end
120
+
121
+ def cdr(list)
122
+ list.drop(1)
123
+ end
124
+
125
+ def result_columns(selects)
126
+ return '*' if selects == []
127
+
128
+ selects.map do |select_with_conds|
129
+ conds_with_as = cdr(select_with_conds)
130
+ conds = conds_with_as.reject { |e| e.class == Hash }.sort.reverse
131
+ as = conds_with_as.select { |e| e.class == Hash }[0][:as] rescue nil
132
+
133
+ if as
134
+ "#{parse_select(car(select_with_conds), conds)} AS #{as}"
135
+ else
136
+ parse_select(car(select_with_conds), conds)
137
+ end
138
+ end.join(', ')
139
+ end
140
+
141
+ def parse_select(select, conds)
142
+ return select if conds == []
143
+
144
+ cond = car(conds)
145
+ parse_select("#{cond}(#{select})", cdr(conds))
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,3 @@
1
+ module QueryGenerator
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,4 @@
1
+ module QueryGenerator
2
+ class WhereDoesNotUsed < StandardError
3
+ end
4
+ end
@@ -0,0 +1,27 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "query_generator/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "query_generator"
8
+ spec.version = QueryGenerator::VERSION
9
+ spec.authors = ["aimerald"]
10
+ spec.email = [""]
11
+
12
+ spec.summary = %q{Generate Standard SQL Query}
13
+ spec.description = %q{Generate Standard Sql query}
14
+ spec.homepage = "https://github.com/aimerald/query_generator"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.16"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec", "~> 3.0"
26
+ spec.add_development_dependency "pry"
27
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: query_generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - aimerald
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-08-15 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.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
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: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
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: Generate Standard Sql query
70
+ email:
71
+ - ''
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - ".travis.yml"
79
+ - Gemfile
80
+ - Gemfile.lock
81
+ - README.md
82
+ - Rakefile
83
+ - bin/console
84
+ - bin/setup
85
+ - lib/query_generator.rb
86
+ - lib/query_generator/not_include_type.rb
87
+ - lib/query_generator/select_already_used.rb
88
+ - lib/query_generator/strict_mode_error.rb
89
+ - lib/query_generator/table.rb
90
+ - lib/query_generator/version.rb
91
+ - lib/query_generator/where_does_not_used.rb
92
+ - query_generator.gemspec
93
+ homepage: https://github.com/aimerald/query_generator
94
+ licenses: []
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.5.2.3
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: Generate Standard SQL Query
116
+ test_files: []