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 @ 44752

History | View | Annotate | Download (10.4 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.apache.commons.lang3.StringUtils;
28
import org.gvsig.expressionevaluator.Code;
29
import org.gvsig.expressionevaluator.CodeBuilder;
30
import org.gvsig.expressionevaluator.Codes;
31
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
32
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
33
import org.gvsig.expressionevaluator.ExpressionSyntaxException;
34
import org.gvsig.expressionevaluator.Grammar;
35
import org.gvsig.expressionevaluator.Statement;
36
import org.gvsig.expressionevaluator.Statement.ArgsBuilder;
37
import org.gvsig.expressionevaluator.Statement.StatementContext;
38
import org.gvsig.expressionevaluator.impl.DALFunctions;
39
import org.gvsig.expressionevaluator.impl.DefaultCodeBuilder.BaseCodes;
40
import org.gvsig.expressionevaluator.impl.DefaultStatement;
41
import org.gvsig.expressionevaluator.impl.DefaultStatement.ArgsBuilderFromNames;
42
import org.gvsig.expressionevaluator.impl.function.dataaccess.ExistsFunction;
43
import org.gvsig.expressionevaluator.spi.AbstractGrammarFactory;
44
import static org.gvsig.fmap.dal.DataManager.FUNCTION_FOREING_VALUE;
45
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT;
46
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT_COUNT;
47
import org.gvsig.expressionevaluator.Code.Callable;
48

    
49
/**
50
 *
51
 * @author jjdelcerro
52
 */
53
public class DataAccessGrammarFactory extends AbstractGrammarFactory {
54

    
55
  private Grammar grammar;
56

    
57
  private static class ExistsStatementBuilder extends DefaultStatement.StatementBuilderBase {
58

    
59
    private final String listID;
60
    private final String existsID;
61

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

    
68
    @Override
69
    public Code build(StatementContext context) {
70

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

    
85
  }
86

    
87
  private static class SelectArgsBuilder implements ArgsBuilder {
88

    
89
    public SelectArgsBuilder() {
90
    }
91

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

    
97
    @Override
98
    public Codes build(StatementContext context) {
99
      context.trace(this.toString() + ".build");
100
      CodeBuilder codeBuilder = context.getCodeBuilder();
101
      BaseCodes args = (BaseCodes) codeBuilder.args();
102

    
103
      Code columns = context.getCode("COLUMNS");
104
      Code table = context.getCode("TABLE");
105
      Code where = context.getCode("WHERE");
106
//      Code order = context.getCode("ORDER");
107
//      Code order_mode = context.getCode("ORDER_MODE");
108
      Code limit = context.getCode("LIMIT");
109

    
110
      if (columns == null) {
111
        throw new ExpressionSyntaxException();
112
      }
113
      Callable tuple = codeBuilder.tuple();
114
      args.add(tuple);
115
      String s = (String) ((Code.Constant) columns).value();
116
      if (!StringUtils.equalsIgnoreCase(s, "*")) {
117
        ((BaseCodes) (tuple.parameters())).add(codeBuilder.constant(1));
118
      }
119
      
120
      args.add(codeBuilder.identifier((String) ((Code.Constant) table).value()));
121

    
122
      if (where == null) {
123
        args.add(codeBuilder.constant(null));
124
      } else {
125
        args.add(where);
126
      }
127

    
128
      int n = 1;
129
      BaseCodes argsX = (BaseCodes) codeBuilder.args();
130
      while (true) {
131
        String argNameX = "ORDER" + String.valueOf(n);
132
        Code code = context.getCode(argNameX);
133
        if (code == null) {
134
          break;
135
        }
136
        argsX.add(code);
137
        n++;
138
      }
139
      args.add(codeBuilder.tuple(argsX));
140

    
141
      n = 1;
142
      argsX = (BaseCodes) codeBuilder.args();
143
      while (true) {
144
        String argNameX = "ORDER_MODE" + String.valueOf(n);
145
        Code code = context.getCode(argNameX);
146
        if (code == null) {
147
          break;
148
        }
149
        argsX.add(code);
150
        n++;
151
      }
152
      args.add(codeBuilder.tuple(argsX));
153

    
154
      if (limit == null) {
155
        args.add(codeBuilder.constant(null));
156
      } else {
157
        args.add(limit);
158
      }
159
      return args;
160

    
161
    }
162

    
163
  }
164

    
165
  private static class SelectCountArgsBuilder implements ArgsBuilder {
166

    
167
    public SelectCountArgsBuilder() {
168
    }
169

    
170
    @Override
171
    public String toString() {
172
      return "select_count_args()";
173
    }
174

    
175
    @Override
176
    public Codes build(StatementContext context) {
177
      context.trace(this.toString() + ".build");
178
      CodeBuilder codeBuilder = context.getCodeBuilder();
179
      BaseCodes args = (BaseCodes) codeBuilder.args();
180

    
181
      Code table = context.getCode("table");
182
      Code where = context.getCode("where");
183

    
184
      args.add(codeBuilder.identifier((String) ((Code.Constant) table).value()));
185

    
186
      if (where == null) {
187
        args.add(codeBuilder.constant(null));
188
      } else {
189
        args.add(where);
190
      }
191
      return args;
192
    }
193

    
194
  }
195

    
196
  public DataAccessGrammarFactory() {
197
    super(DALFunctions.GRAMMAR_NAME, true);
198
  }
199

    
200
  @Override
201
  public Grammar create(Object... parameters) {
202
    ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
203
    if (this.grammar == null) {
204
      Grammar theGrammar = manager.createGrammar(this.getName());
205
      Statement stmt;
206

    
207
      theGrammar.addReservedWord("EXISTS");
208
      theGrammar.addReservedWord("SELECT");
209
      theGrammar.addReservedWord("FROM");
210
      theGrammar.addReservedWord("WHERE");
211
      theGrammar.addReservedWord("ORDER");
212
      theGrammar.addReservedWord("DESC");
213
      theGrammar.addReservedWord("ASC");
214
      theGrammar.addReservedWord("BY");
215

    
216
      stmt = theGrammar.createStatement("EXISTS");
217
      stmt.addRule(stmt.require_any_token("EXISTS"));
218
      stmt.addRule(stmt.require_any_token("("));
219
      stmt.addRule(stmt.require_expression().capture_as("LIST"));
220
      stmt.addRule(stmt.optional_any_token(",")
221
              .addRuleOnTrue(stmt.require_expression().capture_as("ID"))
222
      );
223
      stmt.addRule(stmt.require_any_token(")"));
224
      stmt.builder(new ExistsStatementBuilder("LIST", "ID"));
225
      theGrammar.addStatement(stmt);
226

    
227
      stmt = theGrammar.createStatement("FOREING_VALUE");
228
      stmt.addRule(stmt.require_any_token("FOREING"));
229
      stmt.addRule(stmt.require_any_token("VALUE"));
230
      stmt.addRule(stmt.require_any_token("FROM"));
231
      stmt.addRule(stmt.require_identifiers(".").capture_as("IDENTIFIERS"));
232
      stmt.code(
233
              FUNCTION_FOREING_VALUE,
234
              stmt.args_names("IDENTIFIERS")
235
      );
236
      theGrammar.addStatement(stmt);
237

    
238
      stmt = theGrammar.createStatement("SELECT");
239
      stmt.addRule(stmt.require_any_token("SELECT"));
240
      stmt.addRule(stmt.switch_token()
241
              .addCase("*", stmt.set_expression("COLUMNS", "*"))
242
              .addCase("1", stmt.set_expression("COLUMNS", "1"))
243
              .addDefault(stmt.fail())
244
      );
245
      stmt.addRule(stmt.require_any_token("FROM"));
246
      stmt.addRule(stmt.require_identifier().capture_as("TABLE"));
247
      stmt.addRule(stmt.optional_any_token("WHERE")
248
              .addRuleOnTrue(stmt.require_expression().capture_as("WHERE"))
249
      );
250

    
251
      stmt.addRule(stmt.optional_any_token("ORDER")
252
              .addRuleOnTrue(stmt.require_any_token("BY"))
253
              .addRuleOnTrue(stmt.repeat()
254
                      .addRule(stmt.require_expression().capture_as("ORDER#"))
255
                      .addRule(stmt.switch_token()
256
                              .addCase("ASC", stmt.set_expression("ORDER_MODE#", true))
257
                              .addCase("DESC", stmt.set_expression("ORDER_MODE#", false))
258
                              .addDefault(stmt.set_expression("ORDER_MODE#", true))
259
                      )
260
                      .addRule(stmt.optional_any_token(",")
261
                              .addRuleOnFalse(stmt.break_loop())
262
                      )
263
              )
264
      );
265
      stmt.addRule(stmt.optional_any_token("LIMIT")
266
              .addRuleOnTrue(stmt.require_expression().capture_as("LIMIT"))
267
      );
268
      stmt.addRule(stmt.optional_any_token(";"));
269
      stmt.code(
270
              FUNCTION_SELECT,
271
              new SelectArgsBuilder()
272
      );
273
      theGrammar.addStatement(stmt);
274

    
275
      stmt = theGrammar.createStatement("SELECT_COUNT");
276
      stmt.addRule(stmt.require_any_token("SELECT"));
277
      stmt.addRule(stmt.require_any_token("COUNT"));
278
      stmt.addRule(stmt.require_any_token("("));
279
      stmt.addRule(stmt.require_any_token("*"));
280
      stmt.addRule(stmt.require_any_token(")"));
281
      stmt.addRule(stmt.require_any_token("FROM"));
282
      stmt.addRule(stmt.require_identifier().capture_as("TABLE"));
283
      stmt.addRule(stmt.optional_any_token("WHERE")
284
              .addRuleOnTrue(stmt.require_expression().capture_as("WHERE"))
285
      );
286
      stmt.addRule(stmt.require_any_token(";"));
287
      stmt.code(
288
              FUNCTION_SELECT_COUNT,
289
              new SelectCountArgsBuilder()
290
      );
291
      theGrammar.addStatement(stmt);
292

    
293
      this.grammar = theGrammar;
294
    }
295
    return grammar;
296
  }
297

    
298
  public static final void selfRegister() {
299
    ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
300
    manager.registerGrammar(new DataAccessGrammarFactory());
301
  }
302
}