File tree 11 files changed +230
-60
lines changed
11 files changed +230
-60
lines changed Original file line number Diff line number Diff line change 1
1
# frozen_string_literal: true
2
2
3
+ require "sql/composer/statement"
4
+ require "sql/composer/tokens"
5
+
3
6
module SQL
4
7
module Composer
5
8
class Compiler
9
+ include ::Dry ::Effects ::Handler . State ( :tokens )
10
+
6
11
attr_reader :backend
7
12
8
13
attr_reader :nodes
9
14
10
- def initialize ( backend )
15
+ attr_reader :options
16
+
17
+ attr_reader :tokens
18
+
19
+ def initialize ( backend , options )
11
20
@backend = backend
12
- @nodes = [ ]
21
+ @options = options
22
+ @nodes = options [ :nodes ] || [ ]
23
+ @tokens = options [ :tokens ]
13
24
end
14
25
15
26
def call ( ast )
16
- ast . map { |node | visit ( node ) }
17
- freeze
27
+ with_tokens ( tokens ) { ast . map { |node | visit ( node ) } }
28
+ Statement . new ( compiler : freeze )
29
+ end
30
+
31
+ def with ( new_options )
32
+ self . class . new ( backend , options . merge ( new_options ) . merge ( nodes : nodes ) )
18
33
end
19
34
20
35
def to_s
21
- nodes . map ( &:to_s ) . join ( "\n " )
36
+ with_tokens ( tokens ) { nodes . map ( &:to_s ) . join ( "\n " ) } . last
22
37
end
23
38
24
39
def visit ( node )
Original file line number Diff line number Diff line change 1
1
# frozen_string_literal: true
2
2
3
+ require "dry/effects"
4
+
3
5
require "sql/composer/compiler"
6
+ require "sql/composer/tokens"
4
7
5
8
module SQL
6
9
module Composer
7
10
class DSL < BasicObject
11
+ include ::Dry ::Effects ::Handler . State ( :tokens )
12
+
8
13
attr_reader :options
9
14
10
15
attr_reader :ast
11
16
17
+ attr_reader :tokens
18
+
12
19
def initialize ( options , &block )
13
- @ast = [ ]
14
20
@options = options
15
- instance_exec ( *options [ :args ] , &block )
21
+ @ast = [ ]
22
+ @tokens = options [ :tokens ] || Tokens . new
23
+
24
+ with_tokens ( tokens ) do
25
+ instance_exec ( *options [ :args ] , &block )
26
+ end
16
27
end
17
28
18
29
def call
19
- compiler = Compiler . new ( options . fetch ( :backend ) )
30
+ compiler = Compiler . new ( options . fetch ( :backend ) , tokens : tokens )
20
31
compiler . ( ast )
21
32
end
22
33
Original file line number Diff line number Diff line change 1
1
# frozen_string_literal: true
2
2
3
+ require "dry/effects"
4
+
3
5
module SQL
4
6
module Composer
5
7
module Nodes
6
8
class Core
9
+ include Dry ::Effects . State ( :tokens )
10
+
11
+ attr_reader :id
12
+
7
13
attr_reader :options
8
14
9
15
def initialize ( options )
10
16
@options = options
17
+ @id = tokens . next_id
11
18
end
12
19
13
- def fetch ( name )
14
- @options . fetch ( name )
20
+ def fetch ( name , default = nil )
21
+ @options . fetch ( name , default )
15
22
end
16
23
17
24
def backend
Original file line number Diff line number Diff line change @@ -32,7 +32,15 @@ def qualify?
32
32
33
33
# this is probably a stupid idea lol
34
34
def ==( other )
35
- Operations ::Eql . new ( self , Nodes ::Value . new ( input : other , backend : backend ) )
35
+ value = Nodes ::Value . new ( input : other , backend : backend )
36
+
37
+ operation = Operations ::Eql . new ( left : self , right : value )
38
+
39
+ if other . start_with? ( "%" ) && other . end_with? ( "%" )
40
+ tokens . add ( other , value )
41
+ end
42
+
43
+ operation
36
44
end
37
45
end
38
46
end
Original file line number Diff line number Diff line change 1
1
# frozen_string_literal: true
2
2
3
+ require "sql/composer/nodes/core"
4
+
3
5
module SQL
4
6
module Composer
5
7
module Nodes
6
8
module Operations
7
- class Eql
8
- attr_reader :left , :right
9
+ class Eql < Core
10
+ def left
11
+ fetch ( :left )
12
+ end
9
13
10
- def initialize ( left , right )
11
- @left , @ right = left , right
14
+ def right
15
+ fetch ( : right)
12
16
end
13
17
14
18
def or ( other )
15
- Operations ::Or . new ( self , other )
19
+ Operations ::Or . new ( left : self , right : other )
16
20
end
17
21
alias_method :OR , :or
18
22
Original file line number Diff line number Diff line change 1
1
# frozen_string_literal: true
2
2
3
+ require "sql/composer/nodes/core"
4
+
3
5
module SQL
4
6
module Composer
5
7
module Nodes
6
8
module Operations
7
- class Or
8
- attr_reader :left , :right
9
+ class Or < Core
10
+ def left
11
+ fetch ( :left )
12
+ end
9
13
10
- def initialize ( left , right )
11
- @left , @ right = left , right
14
+ def right
15
+ fetch ( : right)
12
16
end
13
17
14
18
def to_s
Original file line number Diff line number Diff line change @@ -7,7 +7,7 @@ module Composer
7
7
module Nodes
8
8
class Value < Core
9
9
def input
10
- fetch ( :input )
10
+ tokens . value ( id , fetch ( :input ) )
11
11
end
12
12
13
13
def to_s
Original file line number Diff line number Diff line change
1
+ # frozen_string_literal: true
2
+
3
+ module SQL
4
+ module Composer
5
+ class Statement
6
+ include Enumerable
7
+
8
+ attr_reader :options
9
+
10
+ def initialize ( options )
11
+ @options = options
12
+ end
13
+
14
+ def each ( &block )
15
+ nodes . each ( &block )
16
+ end
17
+
18
+ def set ( values )
19
+ tokens = compiler . tokens . new
20
+
21
+ values . each do |key , value |
22
+ tokens . set ( key , value )
23
+ end
24
+
25
+ compiler . with ( tokens : tokens )
26
+ end
27
+
28
+ def to_s
29
+ compiler . to_s
30
+ end
31
+
32
+ def compiler
33
+ options . fetch ( :compiler )
34
+ end
35
+
36
+ def nodes
37
+ compiler . nodes
38
+ end
39
+ end
40
+ end
41
+ end
Original file line number Diff line number Diff line change
1
+ # frozen_string_literal: true
2
+
3
+ module SQL
4
+ module Composer
5
+ class Tokens
6
+ include Dry ::Core ::Constants
7
+
8
+ attr_reader :data
9
+
10
+ def initialize ( data : { } , counter : 0 )
11
+ @data = data
12
+ @counter = counter
13
+ end
14
+
15
+ def add ( key , node )
16
+ data [ key [ 1 ..-2 ] . to_sym ] = [ node . id , Undefined ]
17
+ self
18
+ end
19
+
20
+ def set ( key , value )
21
+ tuple = [ data [ key ] [ 0 ] , value ]
22
+ data [ key ] = tuple
23
+ self
24
+ end
25
+
26
+ def new
27
+ self . class . new ( data : data . dup , counter : @counter )
28
+ end
29
+
30
+ def value ( id , default )
31
+ entry = data . detect { |_ , ( node_id , value ) | node_id . equal? ( id ) }
32
+ entry ? entry [ 1 ] [ 1 ] : default
33
+ end
34
+
35
+ def next_id
36
+ @counter += 1
37
+ end
38
+ end
39
+ end
40
+ end
You can’t perform that action at this time.
0 commit comments