fluent-query-sql 0.9.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.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,22 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ gem "hash-utils", ">= 0.18.0"
5
+ gem "abstract", ">= 1.0.0"
6
+ gem "fluent-query", ">= 0.9.0"
7
+
8
+ # Add dependencies to develop your gem here.
9
+ # Include everything needed to run rake, tests, features, etc.
10
+ group :development do
11
+ gem "bundler", "~> 1.0.13"
12
+ gem "jeweler", "~> 1.6.0"
13
+ end
14
+
15
+
16
+
17
+ # fluent-query-sql
18
+ # fluent-query-dbh
19
+ # fluent-query-mysql
20
+ # fluent-query-sqlite
21
+ # fluent-query-postgresql
22
+ # native-query
@@ -0,0 +1,26 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ abstract (1.0.0)
5
+ fluent-query (0.9.0)
6
+ abstract (>= 1.0.0)
7
+ hash-utils (>= 0.18.0)
8
+ hashie (>= 1.0.0)
9
+ git (1.2.5)
10
+ hash-utils (0.18.0)
11
+ hashie (1.0.0)
12
+ jeweler (1.6.3)
13
+ bundler (~> 1.0)
14
+ git (>= 1.2.5)
15
+ rake
16
+ rake (0.9.2)
17
+
18
+ PLATFORMS
19
+ ruby
20
+
21
+ DEPENDENCIES
22
+ abstract (>= 1.0.0)
23
+ bundler (~> 1.0.13)
24
+ fluent-query (>= 0.9.0)
25
+ hash-utils (>= 0.18.0)
26
+ jeweler (~> 1.6.0)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 - 2011 Martin Kozák (martinkozak@martinkozak.net)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,33 @@
1
+ Fluent Query SQL Driver
2
+ =======================
3
+
4
+ **Fluent Query** is cool way how to write SQL queries and general way
5
+ how to convert series of method calls to string query in an universal
6
+ and system independent manner.
7
+
8
+ This is **SQL** DBI based driver for *Fluent Query*. It can be used with
9
+ [Fluent Query][4] or [Native Query][5] only, and some specific database
10
+ driver, not standalone.
11
+
12
+
13
+ Contributing
14
+ ------------
15
+
16
+ 1. Fork it.
17
+ 2. Create a branch (`git checkout -b 20101220-my-change`).
18
+ 3. Commit your changes (`git commit -am "Added something"`).
19
+ 4. Push to the branch (`git push origin 20101220-my-change`).
20
+ 5. Create an [Issue][2] with a link to your branch.
21
+ 6. Enjoy a refreshing Diet Coke and wait.
22
+
23
+ Copyright
24
+ ---------
25
+
26
+ Copyright © 2009-2011 [Martin Kozák][3]. See `LICENSE.txt` for
27
+ further details.
28
+
29
+ [2]: http://github.com/martinkozak/fluent-query-sql/issues
30
+ [3]: http://www.martinkozak.net/
31
+ [4]: http://github.com/martinkozak/fluent-query
32
+ [5]: http://github.com/martinkozak/native-query
33
+
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+
6
+ begin
7
+ Bundler.setup(:default, :development)
8
+ rescue Bundler::BundlerError => e
9
+ $stderr.puts e.message
10
+ $stderr.puts "Run `bundle install` to install missing gems"
11
+ exit e.status_code
12
+ end
13
+
14
+ require 'rake'
15
+ require 'jeweler'
16
+
17
+ Jeweler::Tasks.new do |gem|
18
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
19
+ gem.name = "fluent-query-sql"
20
+ gem.homepage = "http://github.com/martinkozak/fluent-query-sql"
21
+ gem.license = "MIT"
22
+ gem.summary = 'Generic SQL support for the Fluent Query. Fluent Query is cool way how to write SQL queries in Ruby. Contains base libraries used by specific SQL driver.'
23
+ gem.email = "martinkozak@martinkozak.net"
24
+ gem.authors = ["Martin Kozák"]
25
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
26
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
27
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
28
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
29
+ end
30
+ Jeweler::RubygemsDotOrgTasks.new
31
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.9.0
@@ -0,0 +1,74 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{fluent-query-sql}
8
+ s.version = "0.9.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = [%q{Martin Kozák}]
12
+ s.date = %q{2011-07-14}
13
+ s.email = %q{martinkozak@martinkozak.net}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE.txt",
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ ".document",
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE.txt",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "fluent-query-sql.gemspec",
27
+ "lib/fluent-query/drivers/shared/tokens/sql.rb",
28
+ "lib/fluent-query/drivers/shared/tokens/sql/delete.rb",
29
+ "lib/fluent-query/drivers/shared/tokens/sql/from.rb",
30
+ "lib/fluent-query/drivers/shared/tokens/sql/groupby.rb",
31
+ "lib/fluent-query/drivers/shared/tokens/sql/having.rb",
32
+ "lib/fluent-query/drivers/shared/tokens/sql/insert.rb",
33
+ "lib/fluent-query/drivers/shared/tokens/sql/join.rb",
34
+ "lib/fluent-query/drivers/shared/tokens/sql/orderby.rb",
35
+ "lib/fluent-query/drivers/shared/tokens/sql/select.rb",
36
+ "lib/fluent-query/drivers/shared/tokens/sql/set.rb",
37
+ "lib/fluent-query/drivers/shared/tokens/sql/truncate.rb",
38
+ "lib/fluent-query/drivers/shared/tokens/sql/union.rb",
39
+ "lib/fluent-query/drivers/shared/tokens/sql/update.rb",
40
+ "lib/fluent-query/drivers/shared/tokens/sql/where.rb",
41
+ "lib/fluent-query/drivers/sql.rb",
42
+ "lib/fluent-query/queries/sql.rb"
43
+ ]
44
+ s.homepage = %q{http://github.com/martinkozak/fluent-query-sql}
45
+ s.licenses = [%q{MIT}]
46
+ s.require_paths = [%q{lib}]
47
+ s.rubygems_version = %q{1.8.5}
48
+ s.summary = %q{Generic SQL support for the Fluent Query. Fluent Query is cool way how to write SQL queries in Ruby. Contains base libraries used by specific SQL driver.}
49
+
50
+ if s.respond_to? :specification_version then
51
+ s.specification_version = 3
52
+
53
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
54
+ s.add_runtime_dependency(%q<hash-utils>, [">= 0.18.0"])
55
+ s.add_runtime_dependency(%q<abstract>, [">= 1.0.0"])
56
+ s.add_runtime_dependency(%q<fluent-query>, [">= 0.9.0"])
57
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.13"])
58
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.0"])
59
+ else
60
+ s.add_dependency(%q<hash-utils>, [">= 0.18.0"])
61
+ s.add_dependency(%q<abstract>, [">= 1.0.0"])
62
+ s.add_dependency(%q<fluent-query>, [">= 0.9.0"])
63
+ s.add_dependency(%q<bundler>, ["~> 1.0.13"])
64
+ s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
65
+ end
66
+ else
67
+ s.add_dependency(%q<hash-utils>, [">= 0.18.0"])
68
+ s.add_dependency(%q<abstract>, [">= 1.0.0"])
69
+ s.add_dependency(%q<fluent-query>, [">= 0.9.0"])
70
+ s.add_dependency(%q<bundler>, ["~> 1.0.13"])
71
+ s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
72
+ end
73
+ end
74
+
@@ -0,0 +1,128 @@
1
+ # encoding: utf-8
2
+ require "hash-utils/object" # >= 0.17.0
3
+
4
+ module FluentQuery
5
+ module Drivers
6
+ module Shared
7
+ module Tokens
8
+
9
+ ##
10
+ # PostgreSQL query native token.
11
+ #
12
+
13
+ class SQLToken
14
+
15
+ ##
16
+ # Query to which is this token associated to.
17
+ #
18
+
19
+ @_query
20
+
21
+ ##
22
+ # Parent driver.
23
+ #
24
+
25
+ @_driver
26
+
27
+ ##
28
+ # Original subtokens associated to native token.
29
+ #
30
+
31
+ @_subtokens
32
+
33
+ ##
34
+ # Holds token transformer.
35
+ #
36
+
37
+ TRANSFORMER = /([A-Z])/
38
+
39
+ ##
40
+ # Initializes token.
41
+ #
42
+
43
+ public
44
+ def initialize(driver, query, subtokens)
45
+ @_query = query
46
+ @_driver = driver
47
+ @_subtokens = subtokens
48
+ end
49
+
50
+ ##
51
+ # Renders this token.
52
+ #
53
+ # Name of the token transforms to the SQL form. Joins arguments
54
+ # in Array by commas, in Hash by name = value separated by
55
+ # commas form or by token body itself if token is operator.
56
+ #
57
+ # Mode can be :prepare or :build. Preparing means building the
58
+ # query without expanding the formatting directives.
59
+ #
60
+
61
+ public
62
+ def render!(mode = :build)
63
+
64
+ result = ""
65
+ processor = @_query.processor
66
+
67
+ # Transforms all subtokens to real string SQL tokens
68
+
69
+ @_subtokens.each do |token|
70
+
71
+ arguments = token.arguments
72
+ name = token.name
73
+ transformed = self._transform_token(name.to_s)
74
+ operator = @_driver.operator_token? name
75
+
76
+ if operator
77
+ glue = transformed
78
+ else
79
+ glue = ","
80
+ end
81
+
82
+ first = arguments.first
83
+
84
+ if first.array?
85
+ arguments_result = processor.process_array(first, glue)
86
+ elsif first.hash?
87
+ arguments_result = processor.process_hash(first, glue)
88
+ elsif first.symbol?
89
+ arguments_result = processor.process_identifiers(arguments)
90
+ else
91
+ arguments_result = processor.process_formatted(arguments, mode)
92
+ end
93
+
94
+ result << transformed << " " << arguments_result << " "
95
+ end
96
+
97
+ return result
98
+ end
99
+
100
+ ##
101
+ # Transform token name to the SQL token.
102
+ #
103
+ # Upper case characters handles as separators, so for example:
104
+ # 'leftJoin' will be transformed to 'LEFT JOIN'
105
+ #
106
+
107
+ protected
108
+ def _transform_token(token_name)
109
+ sql_name = token_name.to_s.gsub(self.class::TRANSFORMER, ' \1')
110
+ sql_name.upcase!
111
+
112
+ return sql_name
113
+ end
114
+
115
+ ##
116
+ # Returns appropriate class for anonymous tokens.
117
+ #
118
+
119
+ def unknown_token
120
+ FluentQuery::Drivers::Shared::Tokens::SQLToken
121
+ end
122
+
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ require "hash-utils/object" # >= 0.17.0
3
+ require "fluent-query/drivers/shared/tokens/sql"
4
+ require "fluent-query/drivers/exception"
5
+
6
+ module FluentQuery
7
+ module Drivers
8
+ module Shared
9
+ module Tokens
10
+ module SQL
11
+
12
+ ##
13
+ # Generic SQL query UPDATE token.
14
+ #
15
+
16
+ class Delete < FluentQuery::Drivers::Shared::Tokens::SQLToken
17
+
18
+ ##
19
+ # Renders this token.
20
+ #
21
+
22
+ public
23
+ def render!(mode = nil)
24
+ processor = @_query.processor
25
+ result = "DELETE"
26
+
27
+ @_subtokens.each do |token|
28
+ arguments = token.arguments
29
+
30
+ # FROM token
31
+
32
+ if token.name == :from
33
+ first = arguments.first
34
+
35
+ # Checks for arguments
36
+ if (not first.symbol?)
37
+ raise FluentQuery::Drivers::Exception::new("Symbol argument expected for #from method.")
38
+ end
39
+
40
+ # Process
41
+ table = processor.quote_identifier(first.to_s)
42
+ result << "FROM " << table
43
+
44
+ # Unknown tokens renders directly
45
+ else
46
+ result = self.unknown_token::new(@_driver, @_query, [token]).render!
47
+ end
48
+ end
49
+
50
+ return result
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
@@ -0,0 +1,103 @@
1
+ # encoding: utf-8
2
+ require "fluent-query/drivers/shared/tokens/sql"
3
+ require "hash-utils/object" # >= 0.17.0
4
+
5
+ module FluentQuery
6
+ module Drivers
7
+ module Shared
8
+ module Tokens
9
+ module SQL
10
+
11
+ ##
12
+ # Generic SQL query WHERE token.
13
+ #
14
+
15
+ class From < FluentQuery::Drivers::Shared::Tokens::SQLToken
16
+
17
+ ##
18
+ # Renders this token.
19
+ #
20
+
21
+ public
22
+ def render!(mode = :build)
23
+ _class = self.unknown_token
24
+
25
+ stack = [ ]
26
+ unknown = [ ]
27
+
28
+ processor = @_query.processor
29
+ operator = @_driver.quote_operator(:and)
30
+
31
+ result = "FROM "
32
+
33
+ # Process subtokens
34
+
35
+ @_subtokens.each do |token|
36
+ arguments = token.arguments
37
+
38
+ # Known process
39
+ if token.name == :from
40
+ length = arguments.length
41
+ first = arguments.first
42
+
43
+ if length > 0
44
+ if first.symbol?
45
+ stack << processor.process_identifiers(arguments)
46
+ elsif (length > 1) or (first.string?)
47
+ stack << processor.process_formatted(arguments, mode)
48
+ elsif first.array?
49
+ stack << first.join(operator)
50
+ elsif first.hash?
51
+ stack << processor.process_hash(first, operator)
52
+ end
53
+ end
54
+
55
+ # Closes opened native token with unknown tokens
56
+ if unknown.length > 0
57
+ native = _class::new(@_driver, @_query, unknown)
58
+ stack << native
59
+ unknown = [ ]
60
+ end
61
+
62
+ # Unknowns arguments pushes to the general native token
63
+ else
64
+ unknown << token
65
+ end
66
+
67
+ end
68
+
69
+ # Closes opened native token with unknown tokens
70
+ if unknown.length > 0
71
+ native = _class::new(@_driver, @_query, unknown)
72
+ stack << native
73
+ unknown = [ ]
74
+ end
75
+
76
+ # Process stack with results
77
+ first = true
78
+
79
+ stack.each do |item|
80
+ if item.kind_of? _class
81
+ result << item.render!
82
+ elsif item.string?
83
+ if not first
84
+ result << operator << " "
85
+ else
86
+ first = false
87
+ end
88
+
89
+ result << item
90
+ end
91
+
92
+ result << " "
93
+ end
94
+
95
+ return result
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+