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,147 @@
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 SELECT token.
13
+ #
14
+
15
+ class Select < 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 = "SELECT "
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 == :select) or (name == :distinct)
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
+ elsif argument.hash?
56
+ aliases.merge! argument
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ # Closes opened native token with unknown tokens
63
+ if unknown.length > 0
64
+ native = _class::new(@_driver, @_query, unknown)
65
+ stack << native.render!
66
+ unknown = [ ]
67
+ end
68
+
69
+ # Unknowns arguments pushes to the general native token
70
+ else
71
+ unknown << token
72
+ end
73
+
74
+ distinct = (name == :distinct)
75
+ end
76
+
77
+ # Closes opened native token with unknown tokens
78
+ if unknown.length > 0
79
+ native = _class::new(@_driver, @_query, unknown)
80
+ stack << native.render!
81
+ unknown = [ ]
82
+ end
83
+
84
+ # process distinct
85
+ if distinct
86
+ result << "DISTINCT "
87
+ end
88
+
89
+ # Process stack with results
90
+
91
+ first = true
92
+
93
+ if not fields.empty?
94
+ stack.unshift(fields.uniq)
95
+ end
96
+
97
+ if not aliases.empty?
98
+ stack.unshift(aliases)
99
+ end
100
+
101
+ stack.each do |item|
102
+
103
+ if item.array?
104
+ if not first
105
+ result << ", "
106
+ end
107
+
108
+ result << processor.process_identifiers(item)
109
+ first = false
110
+
111
+ elsif item.hash?
112
+ fields = [ ]
113
+
114
+ item.each_pair do |key, value|
115
+ key = @_driver.quote_identifier(key)
116
+ value = @_driver.quote_identifier(value)
117
+
118
+ fields << (key.to_s + " AS " + value.to_s)
119
+ end
120
+
121
+ if not first
122
+ result << ", "
123
+ end
124
+
125
+ result << fields.join(", ")
126
+ first = false
127
+
128
+ elsif item.string?
129
+ if not first
130
+ result << ", "
131
+ end
132
+
133
+ result << item
134
+ first = false
135
+
136
+ end
137
+ end
138
+
139
+ return result
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+
@@ -0,0 +1,94 @@
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
+
6
+ module FluentQuery
7
+ module Drivers
8
+ module Shared
9
+ module Tokens
10
+ module SQL
11
+
12
+ ##
13
+ # Generic SQL query SET token.
14
+ #
15
+
16
+ class Set < FluentQuery::Drivers::Shared::Tokens::SQLToken
17
+
18
+ ##
19
+ # Renders this token.
20
+ #
21
+
22
+ public
23
+ def render!(mode = :build)
24
+ _class = self.unknown_token
25
+
26
+ stack = [ ]
27
+ unknown = [ ]
28
+
29
+ operator = @_driver.quote_operator(:and)
30
+ processor = @_query.processor
31
+ result = "SET "
32
+
33
+ @_subtokens.each do |token|
34
+ arguments = token.arguments
35
+
36
+ # SET token
37
+
38
+ if token.name == :set
39
+ length = arguments.length
40
+
41
+ # Checks for arguments
42
+ if length > 0
43
+ if (length > 1) or (arguments.first.string?)
44
+ stack << processor.process_formatted(arguments, mode)
45
+ elsif arguments.first.hash?
46
+ stack << processor.process_hash(arguments.first, ", ", :assigning)
47
+ end
48
+ else
49
+ raise FluentQuery::Drivers::Exception::new("SET token expects Hash or formatted string as argument.")
50
+ end
51
+
52
+ # Unknown tokens renders directly
53
+ else
54
+ result << _class::new(@_driver, @_query, [token]).render!
55
+ end
56
+
57
+ end
58
+
59
+
60
+ # Closes opened native token with unknown tokens
61
+ if unknown.length > 0
62
+ native = _class::new(@_driver, @_query, unknown)
63
+ stack << native
64
+ unknown = [ ]
65
+ end
66
+
67
+ # Process stack with results
68
+ first = true
69
+
70
+ stack.each do |item|
71
+ if item.kind_of? _class
72
+ result << item.render!
73
+ elsif item.string?
74
+ if not first
75
+ result << operator << " "
76
+ else
77
+ first = false
78
+ end
79
+
80
+ result << item
81
+ end
82
+
83
+ result << " "
84
+ end
85
+
86
+ return result
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+
@@ -0,0 +1,59 @@
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
+
6
+ module FluentQuery
7
+ module Drivers
8
+ module Shared
9
+ module Tokens
10
+ module SQL
11
+
12
+ ##
13
+ # Generic SQL query TRUNCATE token.
14
+ #
15
+
16
+ class Truncate < 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 = "TRUNCATE TABLE "
26
+
27
+ @_subtokens.each do |token|
28
+ arguments = token.arguments
29
+
30
+ # FROM token
31
+
32
+ if token.name == :truncate
33
+
34
+ # Checks for arguments
35
+ if (not arguments.first.symbol?)
36
+ raise FluentQuery::Drivers::Exception::new("Symbol argument expected for #truncate method.")
37
+ end
38
+
39
+ # Process
40
+ table = processor.quote_identifier(arguments.first)
41
+ result << table
42
+
43
+ # Unknown tokens renders directly
44
+ else
45
+ result << self.unknown_token::new(@_driver, @_query, [token]).render!
46
+ end
47
+
48
+ end
49
+
50
+ result << " CASCADE"
51
+ return result
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+ require "fluent-query/query"
3
+ require "fluent-query/drivers/shared/tokens/sql"
4
+ require "fluent-query/drivers/exception"
5
+ require "hash-utils/object" # >= 0.17.0
6
+
7
+ module FluentQuery
8
+ module Drivers
9
+ module Shared
10
+ module Tokens
11
+ module SQL
12
+
13
+ ##
14
+ # Generic SQL query UNION token.
15
+ #
16
+
17
+ class Union < FluentQuery::Drivers::Shared::Tokens::SQLToken
18
+
19
+ ##
20
+ # Renders this token.
21
+ #
22
+
23
+ public
24
+ def render!(mode = nil)
25
+ result = ""
26
+
27
+ @_subtokens.each do |token|
28
+ arguments = token.arguments
29
+
30
+ # SET token
31
+
32
+ if token.name == :union
33
+ length = arguments.length
34
+
35
+ # Checks for arguments
36
+ if length >= 2
37
+ queries = [ ]
38
+
39
+ arguments.each do |argument|
40
+ if argument.string?
41
+ queries << argument
42
+ elsif argument.kind_of? FluentQuery::Query
43
+ queries << argument.build!
44
+ end
45
+ end
46
+
47
+ else
48
+ raise FluentQuery::Drivers::Exception::new("UNION token expects at least two queries or strings as arguments.")
49
+ end
50
+ end
51
+ end
52
+
53
+ # Process stack with results
54
+ queries.map! { |i| @_driver.quote_subquery(i) }
55
+ result << queries.join(" UNION ")
56
+
57
+ return result
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
@@ -0,0 +1,58 @@
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
+
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 Update < FluentQuery::Drivers::Shared::Tokens::SQLToken
17
+
18
+ ##
19
+ # Renders this token.
20
+ #
21
+
22
+ public
23
+ def render!(mode = nil)
24
+
25
+ processor = @_query.processor
26
+ result = "UPDATE "
27
+
28
+ @_subtokens.each do |token|
29
+ arguments = token.arguments
30
+
31
+ # UPDATE token
32
+ if token.name == :update
33
+
34
+ # Checks for arguments
35
+ if (not arguments.first.symbol?)
36
+ raise FluentQuery::Drivers::Exception::("Symbol arguments expected for #update method.")
37
+ end
38
+
39
+ # Process
40
+ table = processor.quote_identifier(arguments.first)
41
+ result << table
42
+
43
+ # Unknown tokens renders directly
44
+ else
45
+ result = self.unknown_token::new(@_driver, @_query, token).render!
46
+ end
47
+
48
+ end
49
+
50
+ return result
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
@@ -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 WHERE token.
13
+ #
14
+
15
+ class Where < 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 = "WHERE "
32
+
33
+ # Process subtokens
34
+
35
+ @_subtokens.each do |token|
36
+ arguments = token.arguments
37
+
38
+ # Known process
39
+ if token.name == :where
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