fluent-query-sql 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,117 @@
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 GROUP BY token.
13
+ #
14
+
15
+ class GroupBy < FluentQuery::Drivers::Shared::Tokens::SQLToken
16
+
17
+ ##
18
+ # Renders this token.
19
+ #
20
+
21
+ public
22
+ def render!(mode = :build)
23
+ stack = [ ]
24
+ unknown = [ ]
25
+ fields = [ ]
26
+ aliases = { }
27
+ distinct = false
28
+
29
+ result = "GROUP BY "
30
+ processor = @_query.processor
31
+
32
+ _class = self.unknown_token
33
+
34
+ # Process subtokens
35
+
36
+ @_subtokens.each do |token|
37
+ arguments = token.arguments
38
+ name = token.name
39
+
40
+ # Known select process
41
+ if name == :groupBy
42
+ length = arguments.length
43
+
44
+ if length > 0
45
+ first = arguments.first
46
+
47
+ if first.symbol?
48
+ stack << arguments
49
+ elsif first.string?
50
+ stack << processor.process_formatted(arguments, mode)
51
+ else
52
+ arguments.each do |argument|
53
+ if argument.array?
54
+ fields += argument
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ # Closes opened native token with unknown tokens
61
+ if unknown.length > 0
62
+ native = _class::new(@_driver, @_query, unknown)
63
+ stack << native.render!
64
+ unknown = [ ]
65
+ end
66
+
67
+ # Unknowns arguments pushes to the general native token
68
+ else
69
+ unknown << token
70
+ end
71
+ end
72
+
73
+ # Closes opened native token with unknown tokens
74
+ if unknown.length > 0
75
+ native = _class::new(@_driver, @_query, unknown)
76
+ stack << native.render!
77
+ unknown = [ ]
78
+ end
79
+
80
+ # Process stack with results
81
+
82
+ first = true
83
+
84
+ if not fields.empty?
85
+ stack.unshift(fields.uniq)
86
+ end
87
+
88
+ stack.each do |item|
89
+
90
+ if item.array?
91
+ if not first
92
+ result << ", "
93
+ end
94
+
95
+ result << processor.process_identifiers(item)
96
+ first = false
97
+
98
+ elsif item.string?
99
+ if not first
100
+ result << ", "
101
+ end
102
+
103
+ result << item.strip!
104
+ first = false
105
+
106
+ end
107
+ end
108
+
109
+ return result
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+
@@ -0,0 +1,100 @@
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 HAVING token.
13
+ #
14
+
15
+ class Having < 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
+ operator = @_driver.quote_operator(:and)
29
+ processor = @_query.processor
30
+
31
+ result = "HAVING "
32
+
33
+ # Process subtokens
34
+
35
+ @_subtokens.each do |token|
36
+ arguments = token.arguments
37
+
38
+ # Known process
39
+ if token.name == :having
40
+ length = arguments.length
41
+ first = arguments.first
42
+
43
+ if length > 0
44
+ if (length > 1) or (first.string?)
45
+ stack << processor.process_formatted(arguments, mode)
46
+ elsif first.array?
47
+ stack << first.join(operator)
48
+ elsif first.hash?
49
+ stack << processor.process_hash(first, operator)
50
+ end
51
+ end
52
+
53
+ # Closes opened native token with unknown tokens
54
+ if unknown.length > 0
55
+ native = _class::new(@_driver, @_query, unknown)
56
+ stack << native
57
+ unknown = [ ]
58
+ end
59
+
60
+ # Unknowns arguments pushes to the general native token
61
+ else
62
+ unknown << token
63
+ end
64
+
65
+ end
66
+
67
+ # Closes opened native token with unknown tokens
68
+ if unknown.length > 0
69
+ native = _class::new(@_driver, @_query, unknown)
70
+ stack << native
71
+ unknown = [ ]
72
+ end
73
+
74
+ # Process stack with results
75
+ first = true
76
+
77
+ stack.each do |item|
78
+ if item.kind_of? _class
79
+ result << item.render!
80
+ elsif item.string?
81
+ if not first
82
+ result << operator << " "
83
+ else
84
+ first = false
85
+ end
86
+
87
+ result << item
88
+ end
89
+
90
+ result << " "
91
+ end
92
+
93
+ return result
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+ require "fluent-query/drivers/shared/tokens/sql"
3
+ require "fluent-query/drivers/exception"
4
+ require "hash-utils/object" # >= 0.17.0
5
+ require "hash-utils/array"
6
+
7
+ module FluentQuery
8
+ module Drivers
9
+ module Shared
10
+ module Tokens
11
+ module SQL
12
+
13
+ ##
14
+ # Generic SQL query INSERT token.
15
+ #
16
+
17
+ class Insert < FluentQuery::Drivers::Shared::Tokens::SQLToken
18
+
19
+ ##
20
+ # Renders this token.
21
+ #
22
+
23
+ public
24
+ def render!(mode = nil)
25
+ processor = @_query.processor
26
+ result = "INSERT INTO "
27
+
28
+ @_subtokens.each do |token|
29
+ arguments = token.arguments
30
+
31
+ # INSERT token
32
+ if token.name == :insert
33
+
34
+ # Checks for arguments
35
+ if (not arguments.first.symbol?) or (not arguments.second.hash?)
36
+ raise FluentQuery::Drivers::Exception::new("Symbol and Hash arguments expected for #insert method.")
37
+ end
38
+
39
+ # Process
40
+ table = processor.quote_identifier(arguments.first)
41
+ fields = processor.process_identifiers(arguments.second.keys)
42
+ values = processor.process_array(arguments.second.values)
43
+
44
+ result << table << " (" << fields << ") VALUES (" << values << ")"
45
+
46
+ # Unknown tokens renders directly
47
+ else
48
+ result = self.unknown_token::new(@_driver, @_query, token).render!
49
+ end
50
+ end
51
+
52
+ return result
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+
@@ -0,0 +1,98 @@
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 [LEFT|RIGHT|INNER|OUTER] JOIN token.
13
+ #
14
+
15
+ class Join < FluentQuery::Drivers::Shared::Tokens::SQLToken
16
+
17
+ ##
18
+ # Renders this token.
19
+ #
20
+
21
+ public
22
+ def render!(mode = :build)
23
+ stack = [ ]
24
+ unknown = [ ]
25
+
26
+ _class = self.unknown_token
27
+ processor = @_query.processor
28
+ result = ""
29
+
30
+ @_subtokens.each do |token|
31
+ arguments = token.arguments
32
+
33
+ # JOIN token
34
+ if token.name == :join
35
+
36
+ original_name = token.original_name
37
+ stack << self._transform_token(original_name.to_s)
38
+
39
+ ##
40
+
41
+ length = arguments.length
42
+ first = arguments.first
43
+
44
+ if length > 0
45
+ if first.symbol?
46
+ stack << processor.process_identifiers(arguments)
47
+ elsif (length > 1) or (first.string?)
48
+ stack << processor.process_formatted(arguments, mode)
49
+ elsif first.hash?
50
+ t_name = first.keys.first
51
+ t_alias = first.values.first
52
+ stack << (processor.quote_identifier(t_name) + " AS " + processor.quote_identifier(t_alias))
53
+ end
54
+ end
55
+
56
+ # Closes opened native token with unknown tokens
57
+ if unknown.length > 0
58
+ native = _class::new(@_driver, @_query, unknown)
59
+ stack << native
60
+ unknown = [ ]
61
+ end
62
+
63
+ # Unknown arguments pushes to the general native token
64
+ else
65
+ unknown << token
66
+ end
67
+
68
+ end
69
+
70
+ # Closes opened native token with unknown tokens
71
+ if unknown.length > 0
72
+ native = _class::new(@_driver, @_query, unknown)
73
+ stack << native
74
+ unknown = [ ]
75
+ end
76
+
77
+ # Process stack with results
78
+ first = true
79
+
80
+ stack.each do |item|
81
+ if item.kind_of? _class
82
+ result << item.render!
83
+ elsif item.string?
84
+ result << item
85
+ end
86
+
87
+ result << " "
88
+ end
89
+
90
+ return result
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+
@@ -0,0 +1,148 @@
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 ORDER BY token.
13
+ #
14
+
15
+ class OrderBy < FluentQuery::Drivers::Shared::Tokens::SQLToken
16
+
17
+ ##
18
+ # Renders this token.
19
+ #
20
+
21
+ public
22
+ def render!(mode = :build)
23
+
24
+ stack = [ ]
25
+ custom = [ ]
26
+ unknown = [ ]
27
+ fields = [ ]
28
+ distinct = false
29
+
30
+ result = "ORDER BY "
31
+ processor = @_query.processor
32
+ _class = self.unknown_token
33
+
34
+
35
+ # Process subtokens
36
+
37
+ @_subtokens.each do |token|
38
+ arguments = token.arguments
39
+ name = token.name
40
+
41
+ # Known select process
42
+ if name == :orderBy
43
+ length = arguments.length
44
+ close_custom = false
45
+
46
+ if length > 0
47
+ if (length > 1) or (arguments.first.string?)
48
+ value = processor.process_formatted(arguments, mode).dup
49
+ custom.push(value)
50
+
51
+ # Closes fields if they are set
52
+ if not fields.empty?
53
+ stack << (processor.process_identifiers(fields) << ", ")
54
+ fields = [ ]
55
+ end
56
+
57
+ elsif arguments.first.array?
58
+ fields += arguments.first
59
+ close_custom = true
60
+
61
+ elsif arguments.first.symbol?
62
+ fields += arguments
63
+ close_custom = true
64
+
65
+ end
66
+
67
+ # Closes custom formulations if they are set
68
+ # and it's required.
69
+ if close_custom and not custom.empty?
70
+ stack << (self._close_custom(custom) << ", ")
71
+ custom = [ ]
72
+ end
73
+ end
74
+
75
+ # Closes opened native token with unknown tokens
76
+ if unknown.length > 0
77
+ native = _class::new(@_driver, @_query, unknown)
78
+ stack << (native.render! + ", ")
79
+ unknown = [ ]
80
+ end
81
+
82
+ # Unknowns arguments pushes to the general native token
83
+ else
84
+ unknown << token
85
+
86
+ if not fields.empty?
87
+ stack << processor.process_identifiers(fields)
88
+ fields = [ ]
89
+ elsif not custom.empty?
90
+ stack << self._close_custom(custom)
91
+ custom = [ ]
92
+ end
93
+ end
94
+ end
95
+
96
+ # Closes
97
+
98
+ # Opened native token with unknown tokens
99
+ if unknown.length > 0
100
+ native = _class::new(@_driver, @_query, unknown)
101
+ value = native.render!
102
+ unknown = [ ]
103
+
104
+ if (not fields.empty?) or (not custom.empty?)
105
+ value << ", "
106
+ end
107
+
108
+ stack << value
109
+ end
110
+
111
+ # Fields list
112
+ if not fields.empty?
113
+ value = processor.process_identifiers(fields)
114
+
115
+ if not custom.empty?
116
+ value << ", "
117
+ end
118
+
119
+ stack << value
120
+ end
121
+
122
+ # Custom list
123
+ if not custom.empty?
124
+ stack << self._close_custom(custom)
125
+ end
126
+
127
+ # Process stack with results
128
+ result << stack.join(" ")
129
+
130
+ return result
131
+
132
+ end
133
+
134
+ ##
135
+ # Closes array of custom (formatted) strings.
136
+ #
137
+
138
+ protected
139
+ def _close_custom(custom)
140
+ custom.join(", ")
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
148
+