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,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
+