Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / expressionevaluator / impl / grammars / DataAccessGrammarFactory.java @ 44858

History | View | Annotate | Download (13.2 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2020 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.expressionevaluator.impl.grammars;
25

    
26
import java.util.UUID;
27
import org.gvsig.expressionevaluator.Code;
28
import org.gvsig.expressionevaluator.CodeBuilder;
29
import org.gvsig.expressionevaluator.Codes;
30
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
31
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
32
import org.gvsig.expressionevaluator.Grammar;
33
import org.gvsig.expressionevaluator.Statement;
34
import org.gvsig.expressionevaluator.Statement.ArgsBuilder;
35
import org.gvsig.expressionevaluator.Statement.StatementContext;
36
import org.gvsig.expressionevaluator.impl.DALFunctions;
37
import org.gvsig.expressionevaluator.impl.DefaultCodeBuilder.BaseCodes;
38
import org.gvsig.expressionevaluator.impl.DefaultStatement;
39
import org.gvsig.expressionevaluator.impl.DefaultStatement.ArgsBuilderFromNames;
40
import org.gvsig.expressionevaluator.impl.function.dataaccess.ExistsFunction;
41
import org.gvsig.expressionevaluator.spi.AbstractGrammarFactory;
42
import static org.gvsig.fmap.dal.DataManager.FUNCTION_FOREING_VALUE;
43
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT;
44
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT_COUNT;
45
import org.gvsig.expressionevaluator.Code.Callable;
46

    
47
/**
48
 *
49
 * @author jjdelcerro
50
 */
51
public class DataAccessGrammarFactory extends AbstractGrammarFactory {
52

    
53
  private Grammar grammar;
54

    
55
  private static class ExistsStatementBuilder extends DefaultStatement.StatementBuilderBase {
56

    
57
    private final String listID;
58
    private final String existsID;
59

    
60
    public ExistsStatementBuilder(String listID, String existsID) {
61
      super(ExistsFunction.NAME, new ArgsBuilderFromNames(listID, existsID));
62
      this.listID = listID;
63
      this.existsID = existsID;
64
    }
65

    
66
    @Override
67
    public Code build(StatementContext context) {
68

    
69
      CodeBuilder codeBuilder = context.getCodeBuilder();
70
      Callable code = (Callable) super.build(context);
71
      BaseCodes args = (BaseCodes) code.parameters();
72
      if (args.size() < 2) {
73
        String exists_id = "EXISTS" + UUID.randomUUID().toString().replaceAll("-", "");
74
        args.add(codeBuilder.constant(exists_id));
75
      } else if (args.get(1) == null) {
76
        String exists_id = "EXISTS" + UUID.randomUUID().toString().replaceAll("-", "");
77
        args.set(1, codeBuilder.constant(exists_id));
78
      }
79
      code = codeBuilder.function(ExistsFunction.NAME, args);
80
      return code;
81
    }
82

    
83
  }
84

    
85
  private static class SelectArgsBuilder implements ArgsBuilder {
86

    
87
    public SelectArgsBuilder() {
88
    }
89

    
90
    @Override
91
    public String toString() {
92
      return "select_args()";
93
    }
94

    
95
    @Override
96
    public Codes build(StatementContext context) {
97
      context.trace(this.toString() + ".build");
98

    
99
      CodeBuilder codeBuilder = context.getCodeBuilder();
100
      BaseCodes args = (BaseCodes) codeBuilder.args();
101
      return build(context,args);
102
    }
103
    
104
    public Codes build(StatementContext context, BaseCodes args) {
105
      int n;
106
      BaseCodes argsX;
107
      
108
      CodeBuilder codeBuilder = context.getCodeBuilder();
109

    
110
      Code columns = context.getCode("COLUMNS");
111
      args.add(columns);
112
      
113
      Code table = context.getCode("TABLE");
114
      args.add(codeBuilder.identifier((String) ((Code.Constant) table).value()));
115

    
116
      Code where = context.getCode("WHERE");
117
      if (where == null) {
118
        args.add(codeBuilder.constant(null));
119
      } else {
120
        args.add(where);
121
      }
122

    
123
      n = 1;
124
      argsX = (BaseCodes) codeBuilder.args();
125
      while (true) {
126
        String argNameX = "ORDER" + String.valueOf(n);
127
        Code code = context.getCode(argNameX);
128
        if (code == null) {
129
          break;
130
        }
131
        argsX.add(code);
132
        n++;
133
      }
134
      args.add(codeBuilder.tuple(argsX));
135

    
136
      n = 1;
137
      argsX = (BaseCodes) codeBuilder.args();
138
      while (true) {
139
        String argNameX = "ORDER_MODE" + String.valueOf(n);
140
        Code code = context.getCode(argNameX);
141
        if (code == null) {
142
          break;
143
        }
144
        argsX.add(code);
145
        n++;
146
      }
147
      args.add(codeBuilder.tuple(argsX));
148

    
149
      Code limit = context.getCode("LIMIT");
150
      if (limit == null) {
151
        args.add(codeBuilder.constant(null));
152
      } else {
153
        args.add(limit);
154
      }
155
      return args;
156

    
157
    }
158

    
159
  }
160
  private static class InsertIntoArgsBuilder 
161
          extends SelectArgsBuilder
162
          implements ArgsBuilder 
163
  {
164

    
165
    public InsertIntoArgsBuilder() {
166
    }
167

    
168
    @Override
169
    public String toString() {
170
      return "insert_into_args()";
171
    }
172

    
173
    @Override
174
    public Codes build(StatementContext context) {
175
      context.trace(this.toString() + ".build");
176

    
177
      CodeBuilder codeBuilder = context.getCodeBuilder();
178
      BaseCodes args = (BaseCodes) codeBuilder.args();
179

    
180
      Code table = context.getCode("TARGETTABLE");
181
      args.add(codeBuilder.identifier((String) ((Code.Constant) table).value()));
182
      
183
      return build(context,args);
184
    }
185
    
186
  }
187
  
188
  private static class SelectCountArgsBuilder implements ArgsBuilder {
189

    
190
    public SelectCountArgsBuilder() {
191
    }
192

    
193
    @Override
194
    public String toString() {
195
      return "select_count_args()";
196
    }
197

    
198
    @Override
199
    public Codes build(StatementContext context) {
200
      context.trace(this.toString() + ".build");
201
      CodeBuilder codeBuilder = context.getCodeBuilder();
202
      BaseCodes args = (BaseCodes) codeBuilder.args();
203

    
204
      Code table = context.getCode("table");
205
      Code where = context.getCode("where");
206

    
207
      args.add(codeBuilder.identifier((String) ((Code.Constant) table).value()));
208

    
209
      if (where == null) {
210
        args.add(codeBuilder.constant(null));
211
      } else {
212
        args.add(where);
213
      }
214
      return args;
215
    }
216

    
217
  }
218

    
219
  public DataAccessGrammarFactory() {
220
    super(DALFunctions.GRAMMAR_NAME, true);
221
  }
222

    
223
  @Override
224
  public Grammar create(Object... parameters) {
225
    ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
226
    if (this.grammar == null) {
227
      CodeBuilder codeBuilder = manager.createCodeBuilder();
228
      Grammar theGrammar = manager.createGrammar(this.getName());
229
      
230
      Statement stmt;
231
      
232
      theGrammar.addReservedWord("EXISTS");
233
      theGrammar.addReservedWord("SELECT");
234
      theGrammar.addReservedWord("FROM");
235
      theGrammar.addReservedWord("WHERE");
236
      theGrammar.addReservedWord("ORDER");
237
      theGrammar.addReservedWord("DESC");
238
      theGrammar.addReservedWord("ASC");
239
      theGrammar.addReservedWord("BY");
240

    
241
      stmt = theGrammar.createStatement("EXISTS");
242
      stmt.addRule(stmt.require_any_token("EXISTS"));
243
      stmt.addRule(stmt.require_any_token("("));
244
      stmt.addRule(stmt.require_expression().capture_as("LIST"));
245
      stmt.addRule(stmt.optional_any_token(",")
246
              .addRuleOnTrue(stmt.require_expression().capture_as("ID"))
247
      );
248
      stmt.addRule(stmt.require_any_token(")"));
249
      stmt.builder(new ExistsStatementBuilder("LIST", "ID"));
250
      theGrammar.addStatement(stmt);
251

    
252
      stmt = theGrammar.createStatement("FOREING_VALUE");
253
      stmt.addRule(stmt.require_any_token("FOREING"));
254
      stmt.addRule(stmt.require_any_token("VALUE"));
255
      stmt.addRule(stmt.require_any_token("FROM"));
256
      stmt.addRule(stmt.require_identifiers(".").capture_as("IDENTIFIERS"));
257
      stmt.code(
258
              FUNCTION_FOREING_VALUE,
259
              stmt.args_names("IDENTIFIERS")
260
      );
261
      theGrammar.addStatement(stmt);
262

    
263
      stmt = theGrammar.createStatement("CREATE_IN_MEMORY_TABLE");
264
      stmt.addRule(stmt.require_any_token("CREATE"));
265
      stmt.addRule(stmt.require_any_token("IN"));
266
      stmt.addRule(stmt.require_any_token("MEMORY"));
267
      stmt.addRule(stmt.require_any_token("TABLE"));
268
      stmt.addRule(stmt.require_identifier().capture_as("NEWTABLE"));
269
      stmt.addRule(stmt.require_any_token("FROM"));
270
      stmt.addRule(stmt.require_identifier().capture_as("SOURCETABLE"));
271
      stmt.code(
272
              FUNCTION_FOREING_VALUE,
273
              stmt.args_names("NEWTABLE","SOURCETABLE")
274
      );
275
      theGrammar.addStatement(stmt);
276

    
277
      stmt = theGrammar.createStatement("SELECT");
278
      stmt.addRule(stmt.require_any_token("SELECT"));
279
      stmt.addRule(stmt.optional_any_token("*")
280
              .addRuleOnTrue(stmt.set_expression("COLUMNS", codeBuilder.tuple()))
281
              .addRuleOnFalse(stmt.require_identifiers(",").capture_as("COLUMNS"))
282
      );
283
      stmt.addRule(stmt.require_any_token("FROM"));
284
      stmt.addRule(stmt.require_identifier().capture_as("TABLE"));
285
      stmt.addRule(stmt.optional_any_token("WHERE")
286
              .addRuleOnTrue(stmt.require_expression().capture_as("WHERE"))
287
      );
288

    
289
      stmt.addRule(stmt.optional_any_token("ORDER")
290
              .addRuleOnTrue(stmt.require_any_token("BY"))
291
              .addRuleOnTrue(stmt.repeat()
292
                      .addRule(stmt.require_expression().capture_as("ORDER#"))
293
                      .addRule(stmt.switch_token()
294
                              .addCase("ASC", stmt.set_expression("ORDER_MODE#", true))
295
                              .addCase("DESC", stmt.set_expression("ORDER_MODE#", false))
296
                              .addDefault(stmt.set_expression("ORDER_MODE#", true))
297
                      )
298
                      .addRule(stmt.optional_any_token(",")
299
                              .addRuleOnFalse(stmt.break_loop())
300
                      )
301
              )
302
      );
303
      stmt.addRule(stmt.optional_any_token("LIMIT")
304
              .addRuleOnTrue(stmt.require_expression().capture_as("LIMIT"))
305
      );
306
      stmt.addRule(stmt.optional_any_token(";"));
307
      stmt.code(
308
              FUNCTION_SELECT,
309
              new SelectArgsBuilder()
310
      );
311
      theGrammar.addStatement(stmt);
312

    
313
      stmt = theGrammar.createStatement("INSERT_INTO");
314
      stmt.addRule(stmt.require_any_token("INSERT"));
315
      stmt.addRule(stmt.require_any_token("INTO"));
316
      stmt.addRule(stmt.require_identifier().capture_as("TARGETTABLE"));
317
      stmt.addRule(stmt.require_any_token("SELECT"));
318
      stmt.addRule(stmt.optional_any_token("*")
319
              .addRuleOnTrue(stmt.set_expression("COLUMNS", codeBuilder.tuple()))
320
              .addRuleOnFalse(stmt.require_identifiers(",").capture_as("COLUMNS"))
321
      );
322
      stmt.addRule(stmt.require_any_token("FROM"));
323
      stmt.addRule(stmt.require_identifier().capture_as("TABLE"));
324
      stmt.addRule(stmt.optional_any_token("WHERE")
325
              .addRuleOnTrue(stmt.require_expression().capture_as("WHERE"))
326
      );
327

    
328
      stmt.addRule(stmt.optional_any_token("ORDER")
329
              .addRuleOnTrue(stmt.require_any_token("BY"))
330
              .addRuleOnTrue(stmt.repeat()
331
                      .addRule(stmt.require_expression().capture_as("ORDER#"))
332
                      .addRule(stmt.switch_token()
333
                              .addCase("ASC", stmt.set_expression("ORDER_MODE#", true))
334
                              .addCase("DESC", stmt.set_expression("ORDER_MODE#", false))
335
                              .addDefault(stmt.set_expression("ORDER_MODE#", true))
336
                      )
337
                      .addRule(stmt.optional_any_token(",")
338
                              .addRuleOnFalse(stmt.break_loop())
339
                      )
340
              )
341
      );
342
      stmt.addRule(stmt.optional_any_token("LIMIT")
343
              .addRuleOnTrue(stmt.require_expression().capture_as("LIMIT"))
344
      );
345
      stmt.addRule(stmt.optional_any_token(";"));
346
      stmt.code(
347
              FUNCTION_SELECT,
348
              new InsertIntoArgsBuilder()
349
      );
350
      theGrammar.addStatement(stmt);
351

    
352
      stmt = theGrammar.createStatement("SELECT_COUNT");
353
      stmt.addRule(stmt.require_any_token("SELECT"));
354
      stmt.addRule(stmt.require_any_token("COUNT"));
355
      stmt.addRule(stmt.require_any_token("("));
356
      stmt.addRule(stmt.require_any_token("*"));
357
      stmt.addRule(stmt.require_any_token(")"));
358
      stmt.addRule(stmt.require_any_token("FROM"));
359
      stmt.addRule(stmt.require_identifier().capture_as("TABLE"));
360
      stmt.addRule(stmt.optional_any_token("WHERE")
361
              .addRuleOnTrue(stmt.require_expression().capture_as("WHERE"))
362
      );
363
      stmt.addRule(stmt.require_any_token(";"));
364
      stmt.code(
365
              FUNCTION_SELECT_COUNT,
366
              new SelectCountArgsBuilder()
367
      );
368
      theGrammar.addStatement(stmt);
369

    
370
      this.grammar = theGrammar;
371
    }
372
    return grammar;
373
  }
374

    
375
  public static final void selfRegister() {
376
    ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
377
    manager.registerGrammar(new DataAccessGrammarFactory());
378
  }
379
}