fluent-query 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +22 -0
- data/LICENSE.txt +20 -0
- data/README.md +230 -0
- data/Rakefile +29 -0
- data/VERSION +1 -0
- data/fluent-query.gemspec +75 -0
- data/lib/fluent-query.rb +2 -0
- data/lib/fluent-query/compiler.rb +182 -0
- data/lib/fluent-query/compilers/result.rb +33 -0
- data/lib/fluent-query/connection.rb +316 -0
- data/lib/fluent-query/data.rb +17 -0
- data/lib/fluent-query/driver.rb +279 -0
- data/lib/fluent-query/drivers/exception.rb +13 -0
- data/lib/fluent-query/drivers/result.rb +98 -0
- data/lib/fluent-query/exception.rb +12 -0
- data/lib/fluent-query/queries/abstract.rb +169 -0
- data/lib/fluent-query/queries/compiled.rb +51 -0
- data/lib/fluent-query/queries/prepared.rb +50 -0
- data/lib/fluent-query/queries/processor.rb +392 -0
- data/lib/fluent-query/query.rb +118 -0
- data/lib/fluent-query/result.rb +153 -0
- data/lib/fluent-query/token.rb +73 -0
- data/lib/fluent-query/tokens/raw.rb +26 -0
- metadata +136 -0
@@ -0,0 +1,118 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "fluent-query/queries/abstract"
|
3
|
+
require "fluent-query/queries/compiled"
|
4
|
+
require "fluent-query/queries/prepared"
|
5
|
+
require "fluent-query/token"
|
6
|
+
require "fluent-query/tokens/raw"
|
7
|
+
|
8
|
+
module FluentQuery
|
9
|
+
|
10
|
+
##
|
11
|
+
# Represents single query.
|
12
|
+
#
|
13
|
+
|
14
|
+
class Query < FluentQuery::Queries::Abstract
|
15
|
+
|
16
|
+
##
|
17
|
+
# Tokens stack.
|
18
|
+
#
|
19
|
+
|
20
|
+
@stack
|
21
|
+
attr_reader :stack
|
22
|
+
|
23
|
+
##
|
24
|
+
# Initializes query.
|
25
|
+
#
|
26
|
+
|
27
|
+
public
|
28
|
+
def initialize(connection)
|
29
|
+
super(connection)
|
30
|
+
@stack = [ ]
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Catches missing methods calls. Converts them to tokens.
|
35
|
+
#
|
36
|
+
|
37
|
+
public
|
38
|
+
def method_missing(sym, *args, &block)
|
39
|
+
|
40
|
+
self.push_token(sym, args)
|
41
|
+
driver = @connection.driver
|
42
|
+
conditionally = driver.execute_conditionally(self, sym, *args, &block)
|
43
|
+
|
44
|
+
if not conditionally.nil?
|
45
|
+
result = conditionally
|
46
|
+
else
|
47
|
+
result = self
|
48
|
+
end
|
49
|
+
|
50
|
+
return result
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Pushes new token according to specified arguments to the stack.
|
55
|
+
#
|
56
|
+
|
57
|
+
public
|
58
|
+
def push_token(name, arguments)
|
59
|
+
@stack << FluentQuery::Token::new(name, arguments)
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Pushes raw token to the query, so free unassociated query string.
|
64
|
+
#
|
65
|
+
|
66
|
+
public
|
67
|
+
def query(*args)
|
68
|
+
@stack << FluentQuery::Tokens::Raw::new(args)
|
69
|
+
return self
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Returns type of the query, so name of the first token
|
74
|
+
# in the stack.
|
75
|
+
#
|
76
|
+
|
77
|
+
public
|
78
|
+
def type
|
79
|
+
self.stack.first.name.to_sym
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Builds the query.
|
84
|
+
#
|
85
|
+
|
86
|
+
public
|
87
|
+
def build
|
88
|
+
@connection.driver.build_query(self)
|
89
|
+
end
|
90
|
+
|
91
|
+
alias :"build!" :build
|
92
|
+
|
93
|
+
##
|
94
|
+
# Compiles query.
|
95
|
+
# Returns compiled query object.
|
96
|
+
#
|
97
|
+
|
98
|
+
public
|
99
|
+
def compile
|
100
|
+
FluentQuery::Queries::Compiled::new(@connection, self)
|
101
|
+
end
|
102
|
+
|
103
|
+
alias :"compile!" :compile
|
104
|
+
|
105
|
+
##
|
106
|
+
# Prepares query.
|
107
|
+
# Returns prepared query object.
|
108
|
+
#
|
109
|
+
|
110
|
+
public
|
111
|
+
def prepare
|
112
|
+
FluentQuery::Queries::Prepared::new(@connection, self)
|
113
|
+
end
|
114
|
+
|
115
|
+
alias :"prepare!" :prepare
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "fluent-query/exception"
|
3
|
+
|
4
|
+
module FluentQuery
|
5
|
+
|
6
|
+
##
|
7
|
+
# Represents result wrapper.
|
8
|
+
#
|
9
|
+
|
10
|
+
class Result
|
11
|
+
|
12
|
+
##
|
13
|
+
# Holds driver result.
|
14
|
+
#
|
15
|
+
|
16
|
+
@_result
|
17
|
+
|
18
|
+
##
|
19
|
+
# Initializes result.
|
20
|
+
#
|
21
|
+
|
22
|
+
public
|
23
|
+
def initialize(result)
|
24
|
+
@_result = result
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Finishes the result set.
|
29
|
+
# (Cleanups.)
|
30
|
+
#
|
31
|
+
|
32
|
+
public
|
33
|
+
def finish!
|
34
|
+
@_result.free!
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Returns all selected rows.
|
39
|
+
#
|
40
|
+
|
41
|
+
public
|
42
|
+
def all
|
43
|
+
@_result.all
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Returns one row.
|
48
|
+
#
|
49
|
+
|
50
|
+
public
|
51
|
+
def one
|
52
|
+
@_result.one
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Returns first value of first row.
|
57
|
+
#
|
58
|
+
|
59
|
+
public
|
60
|
+
def single
|
61
|
+
@_result.single
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Returns data in complex associative level.
|
66
|
+
# Only two levels are currently supported.
|
67
|
+
#
|
68
|
+
|
69
|
+
public
|
70
|
+
def assoc(*specification, &block)
|
71
|
+
|
72
|
+
if block.nil?
|
73
|
+
block = Proc::new { |v| v }
|
74
|
+
end
|
75
|
+
|
76
|
+
specification.map! { |i| i.to_s }
|
77
|
+
length = specification.length
|
78
|
+
result = { }
|
79
|
+
|
80
|
+
##
|
81
|
+
|
82
|
+
if length == 0
|
83
|
+
raise FluentQuery::Exception::new("Specification must content at least one field name.")
|
84
|
+
elsif length == 1
|
85
|
+
key = specification.first
|
86
|
+
|
87
|
+
self.each do |item|
|
88
|
+
result[item[key]] = block.call(item)
|
89
|
+
end
|
90
|
+
else
|
91
|
+
key_1, key_2 = specification
|
92
|
+
|
93
|
+
self.each do |item|
|
94
|
+
target_1 = item[key_1]
|
95
|
+
target_2 = item[key_2]
|
96
|
+
|
97
|
+
if not result[target_1]
|
98
|
+
result[target_1] = { }
|
99
|
+
end
|
100
|
+
|
101
|
+
result[target_1][target_2] = block.call(item)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
return result
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# Handles iterating.
|
110
|
+
#
|
111
|
+
|
112
|
+
public
|
113
|
+
def each(&block)
|
114
|
+
@_result.each &block
|
115
|
+
self.free!
|
116
|
+
end
|
117
|
+
|
118
|
+
##
|
119
|
+
# Repeats the query leaded to the result.
|
120
|
+
#
|
121
|
+
|
122
|
+
public
|
123
|
+
def repeat!
|
124
|
+
@_result.repeat!
|
125
|
+
end
|
126
|
+
|
127
|
+
##
|
128
|
+
# Returns rows count.
|
129
|
+
#
|
130
|
+
|
131
|
+
public
|
132
|
+
def count
|
133
|
+
@_result.count
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Frees result resources.
|
138
|
+
#
|
139
|
+
|
140
|
+
public
|
141
|
+
def free!
|
142
|
+
@_result.free!
|
143
|
+
end
|
144
|
+
|
145
|
+
##
|
146
|
+
# Finishes the result set.
|
147
|
+
# (Cleanups.)
|
148
|
+
#
|
149
|
+
|
150
|
+
alias :"finish!" :"free!"
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module FluentQuery
|
4
|
+
|
5
|
+
##
|
6
|
+
# Represents general query token.
|
7
|
+
#
|
8
|
+
|
9
|
+
class Token
|
10
|
+
|
11
|
+
##
|
12
|
+
# Name of the token.
|
13
|
+
#
|
14
|
+
|
15
|
+
@_name
|
16
|
+
|
17
|
+
##
|
18
|
+
# Alias of the token.
|
19
|
+
#
|
20
|
+
|
21
|
+
@_alias
|
22
|
+
|
23
|
+
##
|
24
|
+
# Arguments for the token.
|
25
|
+
#
|
26
|
+
|
27
|
+
@arguments
|
28
|
+
attr_reader :arguments
|
29
|
+
|
30
|
+
##
|
31
|
+
# Initializes token.
|
32
|
+
#
|
33
|
+
|
34
|
+
public
|
35
|
+
def initialize(name, arguments)
|
36
|
+
@_name = name
|
37
|
+
@arguments = arguments
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Returns token name.
|
42
|
+
#
|
43
|
+
|
44
|
+
public
|
45
|
+
def name
|
46
|
+
if @_alias
|
47
|
+
return @_alias
|
48
|
+
else
|
49
|
+
return @_name
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Returns original token name.
|
55
|
+
#
|
56
|
+
|
57
|
+
public
|
58
|
+
def original_name
|
59
|
+
@_name
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Sets alias for token.
|
64
|
+
#
|
65
|
+
|
66
|
+
public
|
67
|
+
def alias=(_alias)
|
68
|
+
@_alias = _alias
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "fluent-query/token"
|
3
|
+
|
4
|
+
module FluentQuery
|
5
|
+
module Tokens
|
6
|
+
|
7
|
+
##
|
8
|
+
# Represents query raw token.
|
9
|
+
#
|
10
|
+
|
11
|
+
class Raw < FluentQuery::Token
|
12
|
+
|
13
|
+
##
|
14
|
+
# Initializes token.
|
15
|
+
#
|
16
|
+
|
17
|
+
public
|
18
|
+
def initialize(arguments)
|
19
|
+
super(:" ", arguments)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-query
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.9.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- "Martin Koz\xC3\xA1k"
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-07-14 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hash-utils
|
17
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.18.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: abstract
|
28
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *id002
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: hashie
|
39
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 1.0.0
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *id003
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: bundler
|
50
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.0.13
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *id004
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: jeweler
|
61
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ~>
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 1.6.0
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *id005
|
70
|
+
description:
|
71
|
+
email: martinkozak@martinkozak.net
|
72
|
+
executables: []
|
73
|
+
|
74
|
+
extensions: []
|
75
|
+
|
76
|
+
extra_rdoc_files:
|
77
|
+
- LICENSE.txt
|
78
|
+
- README.md
|
79
|
+
files:
|
80
|
+
- .document
|
81
|
+
- Gemfile
|
82
|
+
- Gemfile.lock
|
83
|
+
- LICENSE.txt
|
84
|
+
- README.md
|
85
|
+
- Rakefile
|
86
|
+
- VERSION
|
87
|
+
- fluent-query.gemspec
|
88
|
+
- lib/fluent-query.rb
|
89
|
+
- lib/fluent-query/compiler.rb
|
90
|
+
- lib/fluent-query/compilers/result.rb
|
91
|
+
- lib/fluent-query/connection.rb
|
92
|
+
- lib/fluent-query/data.rb
|
93
|
+
- lib/fluent-query/driver.rb
|
94
|
+
- lib/fluent-query/drivers/exception.rb
|
95
|
+
- lib/fluent-query/drivers/result.rb
|
96
|
+
- lib/fluent-query/exception.rb
|
97
|
+
- lib/fluent-query/queries/abstract.rb
|
98
|
+
- lib/fluent-query/queries/compiled.rb
|
99
|
+
- lib/fluent-query/queries/prepared.rb
|
100
|
+
- lib/fluent-query/queries/processor.rb
|
101
|
+
- lib/fluent-query/query.rb
|
102
|
+
- lib/fluent-query/result.rb
|
103
|
+
- lib/fluent-query/token.rb
|
104
|
+
- lib/fluent-query/tokens/raw.rb
|
105
|
+
homepage: http://github.com/martinkozak/fluent-query
|
106
|
+
licenses:
|
107
|
+
- MIT
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
hash: 4267616257212336465
|
119
|
+
segments:
|
120
|
+
- 0
|
121
|
+
version: "0"
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: "0"
|
128
|
+
requirements: []
|
129
|
+
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 1.8.5
|
132
|
+
signing_key:
|
133
|
+
specification_version: 3
|
134
|
+
summary: Cool way how to write SQL queries and general way how to convert series of method calls to string query in an universal and system independent manner. This gem contains base libraries only. SQL implementation is available standalone.
|
135
|
+
test_files: []
|
136
|
+
|