twowaysql 0.2.1 → 0.3.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.
- data/History.txt +12 -4
- data/Manifest.txt +5 -0
- data/README.txt +84 -12
- data/issues/issue-001c53236380a42cd8c5a9099bbcc6ec613919c2.yaml +18 -0
- data/issues/issue-25efcfc383f3b0f6c0e2730ae7c2975bb2b3de26.yaml +15 -3
- data/issues/issue-279105dd0d9f03514d318f5eab5e99c4c2d47fda.yaml +21 -0
- data/issues/issue-28cde89ed3eb306957edc90595b1d16bf43daf42.yaml +26 -0
- data/issues/issue-664986b219202ff1948cab717b56e7540f493561.yaml +5 -1
- data/issues/issue-6daccddf089d11d42bf016897da98f70cf5ab46c.yaml +18 -0
- data/issues/issue-901f65630639507c8b05b466790e9f22256c6450.yaml +15 -3
- data/issues/issue-f1bd40de5458397d9b142ea3e197e5264e0dcdbf.yaml +26 -0
- data/issues/issue-f2b773020b54f839c03d899b38b5113c8fd991df.yaml +15 -3
- data/issues/issue-f64d73ed4f9854f1ded77e6496dbf59cfb3770a7.yaml +10 -2
- data/issues/project.yaml +15 -2
- data/lib/twowaysql/node.rb +16 -6
- data/lib/twowaysql/parser.rb +115 -126
- data/lib/twowaysql/parser.y +24 -29
- data/lib/twowaysql/template.rb +26 -4
- data/lib/twowaysql/version.rb +2 -2
- data/spec/large_sql_spec.rb +67 -4
- data/spec/twowaysql_spec.rb +225 -44
- metadata +7 -2
    
        data/lib/twowaysql/parser.rb
    CHANGED
    
    | @@ -11,21 +11,19 @@ module TwoWaySQL | |
| 11 11 |  | 
| 12 12 | 
             
              class Parser < Racc::Parser
         | 
| 13 13 |  | 
| 14 | 
            -
            module_eval <<'..end lib/twowaysql/parser.y modeval.. | 
| 14 | 
            +
            module_eval <<'..end lib/twowaysql/parser.y modeval..idd0cee34b5c', 'lib/twowaysql/parser.y', 134
         | 
| 15 15 |  | 
| 16 16 | 
             
            require 'strscan'
         | 
| 17 17 |  | 
| 18 18 | 
             
            def initialize(opts={})
         | 
| 19 19 | 
             
              opts = {
         | 
| 20 | 
            -
                :debug =>  | 
| 20 | 
            +
                :debug => false,
         | 
| 21 21 | 
             
                :preserve_space => true,
         | 
| 22 | 
            -
                :preserve_comment =>  | 
| 23 | 
            -
                :preserve_eol => true
         | 
| 22 | 
            +
                :preserve_comment => false
         | 
| 24 23 | 
             
              }.merge(opts)
         | 
| 25 24 | 
             
              @yydebug = opts[:debug]
         | 
| 26 25 | 
             
              @preserve_space = opts[:preserve_space]
         | 
| 27 26 | 
             
              @preserve_comment = opts[:preserve_comment]
         | 
| 28 | 
            -
              @preserve_eol = opts[:preserve_eol]
         | 
| 29 27 | 
             
              @num_questions = 0
         | 
| 30 28 | 
             
            end
         | 
| 31 29 |  | 
| @@ -36,28 +34,30 @@ BIND_VARIABLE_PATTERN        = /\A#{BEGIN_BIND_VARIABLE}\s*/ | |
| 36 34 | 
             
            PAREN_BIND_VARIABLE_PATTERN  = /\A#{BEGIN_BIND_VARIABLE}\s*#{PAREN_EXAMPLE}/
         | 
| 37 35 | 
             
            EMBED_VARIABLE_PATTERN       = /\A(\/|\#)\*\$([^\*]+)\*\1\s*/
         | 
| 38 36 |  | 
| 39 | 
            -
            CONDITIONAL_PATTERN | 
| 40 | 
            -
            BEGIN_END_PATTERN | 
| 41 | 
            -
            STRING_LITERAL_PATTERN | 
| 42 | 
            -
            SPLIT_TOKEN_PATTERN | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
            LPAREN_PATTERN        = /\A\(/
         | 
| 51 | 
            -
            RPAREN_PATTERN        = /\A\)/
         | 
| 52 | 
            -
            ACTUAL_COMMENT_PATTERN          = /\A(\/|\#)\*\s+(.+)\s*\*\1/  ## start with spaces
         | 
| 37 | 
            +
            CONDITIONAL_PATTERN     = /\A(\/|\#)\*(IF)\s+([^\*]+)\s*\*\1/
         | 
| 38 | 
            +
            BEGIN_END_PATTERN       = /\A(\/|\#)\*(BEGIN|END)\s*\*\1/
         | 
| 39 | 
            +
            STRING_LITERAL_PATTERN  = /\A(\'(?:[^\']+|\'\')*\')/   ## quoted string
         | 
| 40 | 
            +
            SPLIT_TOKEN_PATTERN     = /\A(\S+?)(?=\s*(?:(?:\/|\#)\*|-{2,}|\(|\)|\,))/  ## stop on delimiters --,/*,#*,',',(,)
         | 
| 41 | 
            +
            LITERAL_PATTERN         = /\A([^;\s]+)/
         | 
| 42 | 
            +
            SPACES_PATTERN          = /\A(\s+)/
         | 
| 43 | 
            +
            QUESTION_PATTERN        = /\A\?/
         | 
| 44 | 
            +
            COMMA_PATTERN           = /\A\,/
         | 
| 45 | 
            +
            LPAREN_PATTERN          = /\A\(/
         | 
| 46 | 
            +
            RPAREN_PATTERN          = /\A\)/
         | 
| 47 | 
            +
            ACTUAL_COMMENT_PATTERN          = /\A(\/|\#)\*(\s{1,}(?:.*?))\*\1/m  ## start with spaces
         | 
| 53 48 | 
             
            SEMICOLON_AT_INPUT_END_PATTERN  = /\A\;\s*\Z/
         | 
| 54 49 | 
             
            UNMATCHED_COMMENT_START_PATTERN = /\A(?:(?:\/|\#)\*)/
         | 
| 55 50 |  | 
| 51 | 
            +
            #TODO: remove trailing spaces for S2Dao compatibility, but this spec sometimes causes SQL bugs...
         | 
| 52 | 
            +
            ELSE_PATTERN            = /\A\-{2,}\s*ELSE\s*/
         | 
| 53 | 
            +
            AND_PATTERN             = /\A(\ *AND)\b/i
         | 
| 54 | 
            +
            OR_PATTERN              = /\A(\ *OR)\b/i
         | 
| 55 | 
            +
             | 
| 56 56 |  | 
| 57 57 | 
             
            def parse( io )
         | 
| 58 58 | 
             
              @q = []
         | 
| 59 | 
            -
              io.each_line do | | 
| 60 | 
            -
                s = StringScanner.new( | 
| 59 | 
            +
              io.each_line(nil) do |whole|
         | 
| 60 | 
            +
                s = StringScanner.new(whole)
         | 
| 61 61 | 
             
                until s.eos? do
         | 
| 62 62 | 
             
                  case
         | 
| 63 63 | 
             
                  when s.scan(AND_PATTERN)
         | 
| @@ -65,7 +65,7 @@ def parse( io ) | |
| 65 65 | 
             
                  when s.scan(OR_PATTERN)
         | 
| 66 66 | 
             
                    @q.push [ :OR, s[1] ]
         | 
| 67 67 | 
             
                  when s.scan(SPACES_PATTERN)
         | 
| 68 | 
            -
                    @q.push [ :SPACES, s[1] ] | 
| 68 | 
            +
                    @q.push [ :SPACES, s[1] ]
         | 
| 69 69 | 
             
                  when s.scan(QUESTION_PATTERN)
         | 
| 70 70 | 
             
                    @q.push [ :QUESTION, nil ]
         | 
| 71 71 | 
             
                  when s.scan(COMMA_PATTERN)
         | 
| @@ -77,7 +77,7 @@ def parse( io ) | |
| 77 77 | 
             
                  when s.scan(ELSE_PATTERN)
         | 
| 78 78 | 
             
                    @q.push [ :ELSE, nil ]
         | 
| 79 79 | 
             
                  when s.scan(ACTUAL_COMMENT_PATTERN)
         | 
| 80 | 
            -
                    @q.push [ :ACTUAL_COMMENT, s[2] ] if @preserve_comment
         | 
| 80 | 
            +
                    @q.push [ :ACTUAL_COMMENT, [s[1], s[2]] ] if @preserve_comment
         | 
| 81 81 | 
             
                  when s.scan(BEGIN_END_PATTERN)
         | 
| 82 82 | 
             
                    @q.push [ s[2].intern, nil ]
         | 
| 83 83 | 
             
                  when s.scan(CONDITIONAL_PATTERN)
         | 
| @@ -103,7 +103,6 @@ def parse( io ) | |
| 103 103 | 
             
                  end
         | 
| 104 104 | 
             
                end
         | 
| 105 105 |  | 
| 106 | 
            -
                @q.push [ :EOL, nil ] if @preserve_eol
         | 
| 107 106 | 
             
              end
         | 
| 108 107 |  | 
| 109 108 | 
             
              @q.push [ false, nil ]
         | 
| @@ -115,109 +114,108 @@ end | |
| 115 114 | 
             
            def next_token
         | 
| 116 115 | 
             
              @q.shift
         | 
| 117 116 | 
             
            end
         | 
| 118 | 
            -
            ..end lib/twowaysql/parser.y modeval.. | 
| 117 | 
            +
            ..end lib/twowaysql/parser.y modeval..idd0cee34b5c
         | 
| 119 118 |  | 
| 120 119 | 
             
            ##### racc 1.4.5 generates ###
         | 
| 121 120 |  | 
| 122 121 | 
             
            racc_reduce_table = [
         | 
| 123 122 | 
             
             0, 0, :racc_error,
         | 
| 124 | 
            -
             1,  | 
| 125 | 
            -
             0,  | 
| 126 | 
            -
             2,  | 
| 127 | 
            -
             1,  | 
| 123 | 
            +
             1, 20, :_reduce_1,
         | 
| 124 | 
            +
             0, 21, :_reduce_2,
         | 
| 125 | 
            +
             2, 21, :_reduce_3,
         | 
| 126 | 
            +
             1, 22, :_reduce_none,
         | 
| 127 | 
            +
             1, 22, :_reduce_none,
         | 
| 128 | 
            +
             1, 22, :_reduce_none,
         | 
| 129 | 
            +
             3, 25, :_reduce_7,
         | 
| 130 | 
            +
             4, 24, :_reduce_8,
         | 
| 131 | 
            +
             2, 27, :_reduce_9,
         | 
| 132 | 
            +
             0, 27, :_reduce_10,
         | 
| 133 | 
            +
             1, 26, :_reduce_none,
         | 
| 134 | 
            +
             1, 26, :_reduce_none,
         | 
| 135 | 
            +
             1, 26, :_reduce_none,
         | 
| 136 | 
            +
             2, 28, :_reduce_14,
         | 
| 137 | 
            +
             2, 29, :_reduce_15,
         | 
| 138 | 
            +
             1, 23, :_reduce_16,
         | 
| 139 | 
            +
             1, 23, :_reduce_17,
         | 
| 140 | 
            +
             1, 23, :_reduce_18,
         | 
| 141 | 
            +
             1, 23, :_reduce_19,
         | 
| 142 | 
            +
             1, 23, :_reduce_20,
         | 
| 143 | 
            +
             1, 23, :_reduce_21,
         | 
| 144 | 
            +
             1, 23, :_reduce_22,
         | 
| 145 | 
            +
             1, 23, :_reduce_23,
         | 
| 146 | 
            +
             1, 23, :_reduce_24,
         | 
| 147 | 
            +
             1, 23, :_reduce_25,
         | 
| 128 148 | 
             
             1, 23, :_reduce_none,
         | 
| 129 149 | 
             
             1, 23, :_reduce_none,
         | 
| 130 | 
            -
              | 
| 131 | 
            -
              | 
| 132 | 
            -
             2,  | 
| 133 | 
            -
              | 
| 134 | 
            -
             1,  | 
| 135 | 
            -
              | 
| 136 | 
            -
              | 
| 137 | 
            -
             | 
| 138 | 
            -
              | 
| 139 | 
            -
             | 
| 140 | 
            -
              | 
| 141 | 
            -
             1, 24, :_reduce_18,
         | 
| 142 | 
            -
             1, 24, :_reduce_19,
         | 
| 143 | 
            -
             1, 24, :_reduce_20,
         | 
| 144 | 
            -
             1, 24, :_reduce_21,
         | 
| 145 | 
            -
             1, 24, :_reduce_22,
         | 
| 146 | 
            -
             1, 24, :_reduce_23,
         | 
| 147 | 
            -
             1, 24, :_reduce_24,
         | 
| 148 | 
            -
             1, 24, :_reduce_25,
         | 
| 149 | 
            -
             1, 24, :_reduce_26,
         | 
| 150 | 
            -
             1, 24, :_reduce_none,
         | 
| 151 | 
            -
             1, 24, :_reduce_none,
         | 
| 152 | 
            -
             2, 31, :_reduce_29,
         | 
| 153 | 
            -
             3, 31, :_reduce_30,
         | 
| 154 | 
            -
             2, 31, :_reduce_31,
         | 
| 155 | 
            -
             3, 31, :_reduce_32,
         | 
| 156 | 
            -
             1, 31, :_reduce_33,
         | 
| 157 | 
            -
             2, 32, :_reduce_34,
         | 
| 158 | 
            -
             3, 32, :_reduce_35 ]
         | 
| 159 | 
            -
             | 
| 160 | 
            -
            racc_reduce_n = 36
         | 
| 161 | 
            -
             | 
| 162 | 
            -
            racc_shift_n = 49
         | 
| 150 | 
            +
             2, 30, :_reduce_28,
         | 
| 151 | 
            +
             3, 30, :_reduce_29,
         | 
| 152 | 
            +
             2, 30, :_reduce_30,
         | 
| 153 | 
            +
             3, 30, :_reduce_31,
         | 
| 154 | 
            +
             1, 30, :_reduce_32,
         | 
| 155 | 
            +
             2, 31, :_reduce_33,
         | 
| 156 | 
            +
             3, 31, :_reduce_34 ]
         | 
| 157 | 
            +
             | 
| 158 | 
            +
            racc_reduce_n = 35
         | 
| 159 | 
            +
             | 
| 160 | 
            +
            racc_shift_n = 48
         | 
| 163 161 |  | 
| 164 162 | 
             
            racc_action_table = [
         | 
| 165 | 
            -
                  | 
| 166 | 
            -
                  | 
| 167 | 
            -
                 | 
| 168 | 
            -
             | 
| 169 | 
            -
                 | 
| 170 | 
            -
                 | 
| 171 | 
            -
             | 
| 172 | 
            -
                 | 
| 173 | 
            -
                 | 
| 174 | 
            -
                 | 
| 163 | 
            +
                 9,    36,    14,    37,    17,    19,    21,    23,    24,     4,
         | 
| 164 | 
            +
                 6,     8,    11,    13,    15,    16,    18,     9,    39,    14,
         | 
| 165 | 
            +
                45,    17,    19,    21,    23,    24,     4,     6,     8,    11,
         | 
| 166 | 
            +
                13,    15,    16,    18,     9,    47,    14,    25,    17,    19,
         | 
| 167 | 
            +
                21,    23,    24,     4,     6,     8,    11,    13,    15,    16,
         | 
| 168 | 
            +
                18,     9,    38,    14,     3,    17,    19,    21,    23,    24,
         | 
| 169 | 
            +
                 4,     6,     8,    11,    13,    15,    16,    18,     9,   nil,
         | 
| 170 | 
            +
                14,   nil,    17,    19,    21,    23,    24,     4,     6,     8,
         | 
| 171 | 
            +
                11,    13,    15,    16,    18,    33,    34,    35,    28,    30,
         | 
| 172 | 
            +
                28,    30,    43,    44 ]
         | 
| 175 173 |  | 
| 176 174 | 
             
            racc_action_check = [
         | 
| 177 | 
            -
             | 
| 178 | 
            -
             | 
| 179 | 
            -
                 | 
| 180 | 
            -
             | 
| 181 | 
            -
                 | 
| 182 | 
            -
                 | 
| 183 | 
            -
                26,    26,    26,    26,    26,    26,    26,    26,     | 
| 184 | 
            -
                 | 
| 185 | 
            -
                 | 
| 186 | 
            -
                 | 
| 175 | 
            +
                42,    18,    42,    18,    42,    42,    42,    42,    42,    42,
         | 
| 176 | 
            +
                42,    42,    42,    42,    42,    42,    42,     2,    27,     2,
         | 
| 177 | 
            +
                37,     2,     2,     2,     2,     2,     2,     2,     2,     2,
         | 
| 178 | 
            +
                 2,     2,     2,     2,    41,    40,    41,     3,    41,    41,
         | 
| 179 | 
            +
                41,    41,    41,    41,    41,    41,    41,    41,    41,    41,
         | 
| 180 | 
            +
                41,    26,    26,    26,     1,    26,    26,    26,    26,    26,
         | 
| 181 | 
            +
                26,    26,    26,    26,    26,    26,    26,    26,    32,   nil,
         | 
| 182 | 
            +
                32,   nil,    32,    32,    32,    32,    32,    32,    32,    32,
         | 
| 183 | 
            +
                32,    32,    32,    32,    32,    15,    15,    15,    39,    39,
         | 
| 184 | 
            +
                14,    14,    35,    35 ]
         | 
| 187 185 |  | 
| 188 186 | 
             
            racc_action_pointer = [
         | 
| 189 | 
            -
               nil,     | 
| 190 | 
            -
               nil,   nil, | 
| 191 | 
            -
               nil,   nil,   nil,   nil,   nil, | 
| 192 | 
            -
               nil,   nil, | 
| 193 | 
            -
                 | 
| 187 | 
            +
               nil,    54,    15,    37,   nil,   nil,   nil,   nil,   nil,   nil,
         | 
| 188 | 
            +
               nil,   nil,   nil,   nil,    84,    77,   nil,   nil,    -7,   nil,
         | 
| 189 | 
            +
               nil,   nil,   nil,   nil,   nil,   nil,    49,    13,   nil,   nil,
         | 
| 190 | 
            +
               nil,   nil,    66,   nil,   nil,    84,   nil,    12,   nil,    82,
         | 
| 191 | 
            +
                32,    32,    -2,   nil,   nil,   nil,   nil,   nil ]
         | 
| 194 192 |  | 
| 195 193 | 
             
            racc_action_default = [
         | 
| 196 | 
            -
                -2,    -1,   - | 
| 197 | 
            -
                -5,   - | 
| 198 | 
            -
               -16,   -27,   -17,   - | 
| 199 | 
            -
                -2,   - | 
| 200 | 
            -
             | 
| 194 | 
            +
                -2,   -35,    -1,   -35,   -21,    -3,   -22,    -4,   -23,    -2,
         | 
| 195 | 
            +
                -5,   -24,    -6,   -25,    -2,   -35,   -32,   -18,   -35,   -19,
         | 
| 196 | 
            +
               -26,   -16,   -27,   -17,   -20,    48,   -35,   -10,    -2,   -11,
         | 
| 197 | 
            +
                -2,   -12,   -13,   -30,   -28,   -35,   -33,   -35,    -7,    -2,
         | 
| 198 | 
            +
               -35,   -14,   -15,   -31,   -29,   -34,    -9,    -8 ]
         | 
| 201 199 |  | 
| 202 200 | 
             
            racc_goto_table = [
         | 
| 203 | 
            -
                  | 
| 201 | 
            +
                 2,    27,     1,    40,   nil,   nil,   nil,   nil,   nil,    26,
         | 
| 204 202 | 
             
               nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
         | 
| 205 | 
            -
               nil,   nil,   nil,   nil,   nil,   nil, | 
| 206 | 
            -
                 | 
| 203 | 
            +
               nil,   nil,   nil,   nil,   nil,   nil,    46,   nil,    41,   nil,
         | 
| 204 | 
            +
                42 ]
         | 
| 207 205 |  | 
| 208 206 | 
             
            racc_goto_check = [
         | 
| 209 | 
            -
                 2,     1,     8, | 
| 207 | 
            +
                 2,     7,     1,     8,   nil,   nil,   nil,   nil,   nil,     2,
         | 
| 210 208 | 
             
               nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
         | 
| 211 | 
            -
               nil,   nil,   nil,   nil,   nil,   nil, | 
| 212 | 
            -
                 2 | 
| 209 | 
            +
               nil,   nil,   nil,   nil,   nil,   nil,     7,   nil,     2,   nil,
         | 
| 210 | 
            +
                 2 ]
         | 
| 213 211 |  | 
| 214 212 | 
             
            racc_goto_pointer = [
         | 
| 215 | 
            -
               nil,      | 
| 213 | 
            +
               nil,     2,     0,   nil,   nil,   nil,   nil,   -13,   -24,   nil,
         | 
| 216 214 | 
             
               nil,   nil,   nil ]
         | 
| 217 215 |  | 
| 218 216 | 
             
            racc_goto_default = [
         | 
| 219 | 
            -
               nil,   nil,     | 
| 220 | 
            -
                 | 
| 217 | 
            +
               nil,   nil,    32,     5,     7,    10,    12,   nil,   nil,    29,
         | 
| 218 | 
            +
                31,    20,    22 ]
         | 
| 221 219 |  | 
| 222 220 | 
             
            racc_token_table = {
         | 
| 223 221 | 
             
             false => 0,
         | 
| @@ -236,14 +234,13 @@ racc_token_table = { | |
| 236 234 | 
             
             :RPAREN => 13,
         | 
| 237 235 | 
             
             :QUESTION => 14,
         | 
| 238 236 | 
             
             :ACTUAL_COMMENT => 15,
         | 
| 239 | 
            -
             : | 
| 240 | 
            -
             : | 
| 241 | 
            -
             : | 
| 242 | 
            -
             :EMBED_VARIABLE => 19 }
         | 
| 237 | 
            +
             :BIND_VARIABLE => 16,
         | 
| 238 | 
            +
             :PAREN_BIND_VARIABLE => 17,
         | 
| 239 | 
            +
             :EMBED_VARIABLE => 18 }
         | 
| 243 240 |  | 
| 244 241 | 
             
            racc_use_result_var = true
         | 
| 245 242 |  | 
| 246 | 
            -
            racc_nt_base =  | 
| 243 | 
            +
            racc_nt_base = 19
         | 
| 247 244 |  | 
| 248 245 | 
             
            Racc_arg = [
         | 
| 249 246 | 
             
             racc_action_table,
         | 
| @@ -278,7 +275,6 @@ Racc_token_to_s_table = [ | |
| 278 275 | 
             
            'RPAREN',
         | 
| 279 276 | 
             
            'QUESTION',
         | 
| 280 277 | 
             
            'ACTUAL_COMMENT',
         | 
| 281 | 
            -
            'EOL',
         | 
| 282 278 | 
             
            'BIND_VARIABLE',
         | 
| 283 279 | 
             
            'PAREN_BIND_VARIABLE',
         | 
| 284 280 | 
             
            'EMBED_VARIABLE',
         | 
| @@ -407,7 +403,7 @@ module_eval <<'.,.,', 'lib/twowaysql/parser.y', 71 | |
| 407 403 |  | 
| 408 404 | 
             
            module_eval <<'.,.,', 'lib/twowaysql/parser.y', 75
         | 
| 409 405 | 
             
              def _reduce_20( val, _values, result )
         | 
| 410 | 
            -
                              result =  | 
| 406 | 
            +
                              result = WhiteSpaceNode.new( val[0], @preserve_space )
         | 
| 411 407 | 
             
               result
         | 
| 412 408 | 
             
              end
         | 
| 413 409 | 
             
            .,.,
         | 
| @@ -443,21 +439,21 @@ module_eval <<'.,.,', 'lib/twowaysql/parser.y', 92 | |
| 443 439 |  | 
| 444 440 | 
             
            module_eval <<'.,.,', 'lib/twowaysql/parser.y', 96
         | 
| 445 441 | 
             
              def _reduce_25( val, _values, result )
         | 
| 446 | 
            -
                              result =  | 
| 442 | 
            +
                              result = ActualCommentNode.new( val[0][0] , val[0][1] )
         | 
| 447 443 | 
             
               result
         | 
| 448 444 | 
             
              end
         | 
| 449 445 | 
             
            .,.,
         | 
| 450 446 |  | 
| 451 | 
            -
             | 
| 452 | 
            -
              def _reduce_26( val, _values, result )
         | 
| 453 | 
            -
                              result = EolNode.new
         | 
| 454 | 
            -
               result
         | 
| 455 | 
            -
              end
         | 
| 456 | 
            -
            .,.,
         | 
| 447 | 
            +
             # reduce 26 omitted
         | 
| 457 448 |  | 
| 458 449 | 
             
             # reduce 27 omitted
         | 
| 459 450 |  | 
| 460 | 
            -
              | 
| 451 | 
            +
            module_eval <<'.,.,', 'lib/twowaysql/parser.y', 103
         | 
| 452 | 
            +
              def _reduce_28( val, _values, result )
         | 
| 453 | 
            +
                              result = BindVariableNode.new( val[0] )
         | 
| 454 | 
            +
               result
         | 
| 455 | 
            +
              end
         | 
| 456 | 
            +
            .,.,
         | 
| 461 457 |  | 
| 462 458 | 
             
            module_eval <<'.,.,', 'lib/twowaysql/parser.y', 107
         | 
| 463 459 | 
             
              def _reduce_29( val, _values, result )
         | 
| @@ -482,14 +478,14 @@ module_eval <<'.,.,', 'lib/twowaysql/parser.y', 115 | |
| 482 478 |  | 
| 483 479 | 
             
            module_eval <<'.,.,', 'lib/twowaysql/parser.y', 119
         | 
| 484 480 | 
             
              def _reduce_32( val, _values, result )
         | 
| 485 | 
            -
                              result =  | 
| 481 | 
            +
                              result = ParenBindVariableNode.new( val[0] )
         | 
| 486 482 | 
             
               result
         | 
| 487 483 | 
             
              end
         | 
| 488 484 | 
             
            .,.,
         | 
| 489 485 |  | 
| 490 | 
            -
            module_eval <<'.,.,', 'lib/twowaysql/parser.y',  | 
| 486 | 
            +
            module_eval <<'.,.,', 'lib/twowaysql/parser.y', 124
         | 
| 491 487 | 
             
              def _reduce_33( val, _values, result )
         | 
| 492 | 
            -
                              result =  | 
| 488 | 
            +
                              result = EmbedVariableNode.new( val[0] )
         | 
| 493 489 | 
             
               result
         | 
| 494 490 | 
             
              end
         | 
| 495 491 | 
             
            .,.,
         | 
| @@ -501,13 +497,6 @@ module_eval <<'.,.,', 'lib/twowaysql/parser.y', 128 | |
| 501 497 | 
             
              end
         | 
| 502 498 | 
             
            .,.,
         | 
| 503 499 |  | 
| 504 | 
            -
            module_eval <<'.,.,', 'lib/twowaysql/parser.y', 132
         | 
| 505 | 
            -
              def _reduce_35( val, _values, result )
         | 
| 506 | 
            -
                              result = EmbedVariableNode.new( val[0] )
         | 
| 507 | 
            -
               result
         | 
| 508 | 
            -
              end
         | 
| 509 | 
            -
            .,.,
         | 
| 510 | 
            -
             | 
| 511 500 | 
             
             def _reduce_none( val, _values, result )
         | 
| 512 501 | 
             
              result
         | 
| 513 502 | 
             
             end
         | 
    
        data/lib/twowaysql/parser.y
    CHANGED
    
    | @@ -71,7 +71,7 @@ primary        : IDENT | |
| 71 71 | 
             
                            }
         | 
| 72 72 | 
             
                           | SPACES
         | 
| 73 73 | 
             
                            {
         | 
| 74 | 
            -
                              result =  | 
| 74 | 
            +
                              result = WhiteSpaceNode.new( val[0], @preserve_space )
         | 
| 75 75 | 
             
                            }
         | 
| 76 76 | 
             
                           | COMMA
         | 
| 77 77 | 
             
                            {
         | 
| @@ -92,11 +92,7 @@ primary        : IDENT | |
| 92 92 | 
             
                            }
         | 
| 93 93 | 
             
                           | ACTUAL_COMMENT
         | 
| 94 94 | 
             
                            {
         | 
| 95 | 
            -
                              result =  | 
| 96 | 
            -
                            }
         | 
| 97 | 
            -
                           | EOL
         | 
| 98 | 
            -
                            {
         | 
| 99 | 
            -
                              result = EolNode.new
         | 
| 95 | 
            +
                              result = ActualCommentNode.new( val[0][0] , val[0][1] )
         | 
| 100 96 | 
             
                            }
         | 
| 101 97 | 
             
                           | bind_var
         | 
| 102 98 | 
             
                           | embed_var
         | 
| @@ -140,15 +136,13 @@ require 'strscan' | |
| 140 136 |  | 
| 141 137 | 
             
            def initialize(opts={})
         | 
| 142 138 | 
             
              opts = {
         | 
| 143 | 
            -
                :debug =>  | 
| 139 | 
            +
                :debug => false,
         | 
| 144 140 | 
             
                :preserve_space => true,
         | 
| 145 | 
            -
                :preserve_comment =>  | 
| 146 | 
            -
                :preserve_eol => true
         | 
| 141 | 
            +
                :preserve_comment => false
         | 
| 147 142 | 
             
              }.merge(opts)
         | 
| 148 143 | 
             
              @yydebug = opts[:debug]
         | 
| 149 144 | 
             
              @preserve_space = opts[:preserve_space]
         | 
| 150 145 | 
             
              @preserve_comment = opts[:preserve_comment]
         | 
| 151 | 
            -
              @preserve_eol = opts[:preserve_eol]
         | 
| 152 146 | 
             
              @num_questions = 0
         | 
| 153 147 | 
             
            end
         | 
| 154 148 |  | 
| @@ -159,28 +153,30 @@ BIND_VARIABLE_PATTERN        = /\A#{BEGIN_BIND_VARIABLE}\s*/ | |
| 159 153 | 
             
            PAREN_BIND_VARIABLE_PATTERN  = /\A#{BEGIN_BIND_VARIABLE}\s*#{PAREN_EXAMPLE}/
         | 
| 160 154 | 
             
            EMBED_VARIABLE_PATTERN       = /\A(\/|\#)\*\$([^\*]+)\*\1\s*/
         | 
| 161 155 |  | 
| 162 | 
            -
            CONDITIONAL_PATTERN | 
| 163 | 
            -
            BEGIN_END_PATTERN | 
| 164 | 
            -
            STRING_LITERAL_PATTERN | 
| 165 | 
            -
            SPLIT_TOKEN_PATTERN | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 168 | 
            -
             | 
| 169 | 
            -
             | 
| 170 | 
            -
             | 
| 171 | 
            -
             | 
| 172 | 
            -
             | 
| 173 | 
            -
            LPAREN_PATTERN        = /\A\(/
         | 
| 174 | 
            -
            RPAREN_PATTERN        = /\A\)/
         | 
| 175 | 
            -
            ACTUAL_COMMENT_PATTERN          = /\A(\/|\#)\*\s+(.+)\s*\*\1/  ## start with spaces
         | 
| 156 | 
            +
            CONDITIONAL_PATTERN     = /\A(\/|\#)\*(IF)\s+([^\*]+)\s*\*\1/
         | 
| 157 | 
            +
            BEGIN_END_PATTERN       = /\A(\/|\#)\*(BEGIN|END)\s*\*\1/
         | 
| 158 | 
            +
            STRING_LITERAL_PATTERN  = /\A(\'(?:[^\']+|\'\')*\')/   ## quoted string
         | 
| 159 | 
            +
            SPLIT_TOKEN_PATTERN     = /\A(\S+?)(?=\s*(?:(?:\/|\#)\*|-{2,}|\(|\)|\,))/  ## stop on delimiters --,/*,#*,',',(,)
         | 
| 160 | 
            +
            LITERAL_PATTERN         = /\A([^;\s]+)/
         | 
| 161 | 
            +
            SPACES_PATTERN          = /\A(\s+)/
         | 
| 162 | 
            +
            QUESTION_PATTERN        = /\A\?/
         | 
| 163 | 
            +
            COMMA_PATTERN           = /\A\,/
         | 
| 164 | 
            +
            LPAREN_PATTERN          = /\A\(/
         | 
| 165 | 
            +
            RPAREN_PATTERN          = /\A\)/
         | 
| 166 | 
            +
            ACTUAL_COMMENT_PATTERN          = /\A(\/|\#)\*(\s{1,}(?:.*?))\*\1/m  ## start with spaces
         | 
| 176 167 | 
             
            SEMICOLON_AT_INPUT_END_PATTERN  = /\A\;\s*\Z/
         | 
| 177 168 | 
             
            UNMATCHED_COMMENT_START_PATTERN = /\A(?:(?:\/|\#)\*)/
         | 
| 178 169 |  | 
| 170 | 
            +
            #TODO: remove trailing spaces for S2Dao compatibility, but this spec sometimes causes SQL bugs...
         | 
| 171 | 
            +
            ELSE_PATTERN            = /\A\-{2,}\s*ELSE\s*/
         | 
| 172 | 
            +
            AND_PATTERN             = /\A(\ *AND)\b/i
         | 
| 173 | 
            +
            OR_PATTERN              = /\A(\ *OR)\b/i
         | 
| 174 | 
            +
             | 
| 179 175 |  | 
| 180 176 | 
             
            def parse( io )
         | 
| 181 177 | 
             
              @q = []
         | 
| 182 | 
            -
              io.each_line do | | 
| 183 | 
            -
                s = StringScanner.new( | 
| 178 | 
            +
              io.each_line(nil) do |whole|
         | 
| 179 | 
            +
                s = StringScanner.new(whole)
         | 
| 184 180 | 
             
                until s.eos? do
         | 
| 185 181 | 
             
                  case
         | 
| 186 182 | 
             
                  when s.scan(AND_PATTERN)
         | 
| @@ -188,7 +184,7 @@ def parse( io ) | |
| 188 184 | 
             
                  when s.scan(OR_PATTERN)
         | 
| 189 185 | 
             
                    @q.push [ :OR, s[1] ]
         | 
| 190 186 | 
             
                  when s.scan(SPACES_PATTERN)
         | 
| 191 | 
            -
                    @q.push [ :SPACES, s[1] ] | 
| 187 | 
            +
                    @q.push [ :SPACES, s[1] ]
         | 
| 192 188 | 
             
                  when s.scan(QUESTION_PATTERN)
         | 
| 193 189 | 
             
                    @q.push [ :QUESTION, nil ]
         | 
| 194 190 | 
             
                  when s.scan(COMMA_PATTERN)
         | 
| @@ -200,7 +196,7 @@ def parse( io ) | |
| 200 196 | 
             
                  when s.scan(ELSE_PATTERN)
         | 
| 201 197 | 
             
                    @q.push [ :ELSE, nil ]
         | 
| 202 198 | 
             
                  when s.scan(ACTUAL_COMMENT_PATTERN)
         | 
| 203 | 
            -
                    @q.push [ :ACTUAL_COMMENT, s[2] ] if @preserve_comment
         | 
| 199 | 
            +
                    @q.push [ :ACTUAL_COMMENT, [s[1], s[2]] ] if @preserve_comment
         | 
| 204 200 | 
             
                  when s.scan(BEGIN_END_PATTERN)
         | 
| 205 201 | 
             
                    @q.push [ s[2].intern, nil ]
         | 
| 206 202 | 
             
                  when s.scan(CONDITIONAL_PATTERN)
         | 
| @@ -226,7 +222,6 @@ def parse( io ) | |
| 226 222 | 
             
                  end
         | 
| 227 223 | 
             
                end
         | 
| 228 224 |  | 
| 229 | 
            -
                @q.push [ :EOL, nil ] if @preserve_eol
         | 
| 230 225 | 
             
              end
         | 
| 231 226 |  | 
| 232 227 | 
             
              @q.push [ false, nil ]
         | 
    
        data/lib/twowaysql/template.rb
    CHANGED
    
    | @@ -1,5 +1,3 @@ | |
| 1 | 
            -
            require 'forwardable'
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            module TwoWaySQL
         | 
| 4 2 |  | 
| 5 3 | 
             
              # TwoWaySQL::Template represents template object, acts as a Facade for this package.
         | 
| @@ -64,12 +62,36 @@ module TwoWaySQL | |
| 64 62 |  | 
| 65 63 | 
             
              # TwoWaySQL::Result represents merge result of template and data.
         | 
| 66 64 | 
             
              # it contains SQL string with placeholders, and bound variables associated with placeholders.
         | 
| 65 | 
            +
              #
         | 
| 66 | 
            +
              # === Usage
         | 
| 67 | 
            +
              #
         | 
| 68 | 
            +
              #   merged = template.merge(:job => "HOGE", :deptno => 30)
         | 
| 69 | 
            +
              #   merged.sql                #=> "SELECT * FROM emp WHERE job = ? AND deptno = ?"
         | 
| 70 | 
            +
              #   merged.bound_variables    #=> ["HOGE", 30]
         | 
| 71 | 
            +
              #
         | 
| 67 72 | 
             
              class Result
         | 
| 68 | 
            -
                extend Forwardable
         | 
| 69 73 | 
             
                def initialize(context)
         | 
| 70 74 | 
             
                  @context = context
         | 
| 71 75 | 
             
                end
         | 
| 72 | 
            -
             | 
| 76 | 
            +
             | 
| 77 | 
            +
                # return merge result SQL with placeholders (question mark).
         | 
| 78 | 
            +
                #
         | 
| 79 | 
            +
                # === Return
         | 
| 80 | 
            +
                # merge result SQL with placeholders
         | 
| 81 | 
            +
                #
         | 
| 82 | 
            +
                def sql
         | 
| 83 | 
            +
                  @context.sql
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                # return array of variables which indices are corresponding to placeholders.
         | 
| 87 | 
            +
                #
         | 
| 88 | 
            +
                # === Return
         | 
| 89 | 
            +
                # merge result SQL with placeholders
         | 
| 90 | 
            +
                #
         | 
| 91 | 
            +
                def bound_variables
         | 
| 92 | 
            +
                  @context.bound_variables
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
                alias vars bound_variables
         | 
| 73 95 | 
             
              end
         | 
| 74 96 |  | 
| 75 97 | 
             
            end
         | 
    
        data/lib/twowaysql/version.rb
    CHANGED
    
    
    
        data/spec/large_sql_spec.rb
    CHANGED
    
    | @@ -153,11 +153,26 @@ from | |
| 153 153 | 
             
              /*IF ctx[:id_list] */and id in /*ctx[:id_list]*/(3, 4, 9)/*END*/
         | 
| 154 154 | 
             
            /*END*/
         | 
| 155 155 | 
             
            EOS
         | 
| 156 | 
            -
                  template = TwoWaySQL::Template.parse(sql)
         | 
| 157 | 
            -
                  @result = template.merge(:id_list => [10, 11])
         | 
| 156 | 
            +
                  @template = TwoWaySQL::Template.parse(sql)
         | 
| 158 157 | 
             
                end
         | 
| 159 158 |  | 
| 160 | 
            -
                it " | 
| 159 | 
            +
                it "if both line is true" do
         | 
| 160 | 
            +
                  expected = <<-EOS
         | 
| 161 | 
            +
            select
         | 
| 162 | 
            +
              *
         | 
| 163 | 
            +
            from
         | 
| 164 | 
            +
              hoge
         | 
| 165 | 
            +
            where
         | 
| 166 | 
            +
              name like ?
         | 
| 167 | 
            +
              and id in (?, ?)
         | 
| 168 | 
            +
             | 
| 169 | 
            +
            EOS
         | 
| 170 | 
            +
                  @result = @template.merge(:name => 'foo%', :id_list => [10, 11])
         | 
| 171 | 
            +
                  @result.sql.should == expected
         | 
| 172 | 
            +
                  @result.bound_variables.should == ['foo%', 10, 11]
         | 
| 173 | 
            +
                end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                it "if second line is true" do
         | 
| 161 176 | 
             
                  expected = <<-EOS
         | 
| 162 177 | 
             
            select
         | 
| 163 178 | 
             
              *
         | 
| @@ -165,12 +180,60 @@ from | |
| 165 180 | 
             
              hoge
         | 
| 166 181 | 
             
            where
         | 
| 167 182 |  | 
| 168 | 
            -
             | 
| 183 | 
            +
               id in (?, ?)
         | 
| 169 184 |  | 
| 170 185 | 
             
            EOS
         | 
| 186 | 
            +
                  @result = @template.merge(:id_list => [10, 11])
         | 
| 171 187 | 
             
                  @result.sql.should == expected
         | 
| 172 188 | 
             
                  @result.bound_variables.should == [10, 11]
         | 
| 173 189 | 
             
                end
         | 
| 190 | 
            +
             | 
| 191 | 
            +
              end
         | 
| 192 | 
            +
             | 
| 193 | 
            +
             | 
| 194 | 
            +
             | 
| 195 | 
            +
             | 
| 196 | 
            +
              describe "examples in website" do
         | 
| 197 | 
            +
                it do
         | 
| 198 | 
            +
              # given SQL string with TwoWaySQL comments
         | 
| 199 | 
            +
              sql = <<-EOS
         | 
| 200 | 
            +
                SELECT * FROM emp
         | 
| 201 | 
            +
                /*BEGIN*/WHERE
         | 
| 202 | 
            +
                  /*IF ctx[:job]*/ job = /*ctx[:job]*/'CLERK' /*END*/
         | 
| 203 | 
            +
                  /*IF ctx[:deptno_list]*/ AND deptno IN /*ctx[:deptno_list]*/(20, 30) /*END*/
         | 
| 204 | 
            +
                  /*IF ctx[:age]*/ AND age > /*ctx[:age]*/30 /*END*/
         | 
| 205 | 
            +
                /*END*/
         | 
| 206 | 
            +
                /*IF ctx[:order_by] */ ORDER BY /*$ctx[:order_by]*/id /*$ctx[:order]*/ASC /*END*/
         | 
| 207 | 
            +
              EOS
         | 
| 208 | 
            +
             | 
| 209 | 
            +
             | 
| 210 | 
            +
              # parse the SQL to create template object
         | 
| 211 | 
            +
              template = TwoWaySQL::Template.parse(sql)
         | 
| 212 | 
            +
             | 
| 213 | 
            +
             | 
| 214 | 
            +
              # merge data with template
         | 
| 215 | 
            +
              data = {
         | 
| 216 | 
            +
                :age => 35,
         | 
| 217 | 
            +
                :deptno_list => [10,20,30],
         | 
| 218 | 
            +
                :order_by => 'age',
         | 
| 219 | 
            +
                :order => 'DESC'
         | 
| 220 | 
            +
              }
         | 
| 221 | 
            +
              merged = template.merge(data)
         | 
| 222 | 
            +
             | 
| 223 | 
            +
             | 
| 224 | 
            +
              expected_sql = <<-EOS
         | 
| 225 | 
            +
                SELECT * FROM emp
         | 
| 226 | 
            +
                WHERE
         | 
| 227 | 
            +
                  
         | 
| 228 | 
            +
                   deptno IN (?, ?, ?) 
         | 
| 229 | 
            +
                   AND age > ? 
         | 
| 230 | 
            +
                
         | 
| 231 | 
            +
                 ORDER BY age DESC 
         | 
| 232 | 
            +
              EOS
         | 
| 233 | 
            +
             | 
| 234 | 
            +
              merged.sql.should == expected_sql      #=> true
         | 
| 235 | 
            +
              merged.bound_variables.should == [10,20,30,35]
         | 
| 236 | 
            +
                end
         | 
| 174 237 | 
             
              end
         | 
| 175 238 |  | 
| 176 239 | 
             
            end
         |