public void create(String oql) throws QueryException { _fieldNum = 0; _expr = null; _spCall = null; // Separate parser for CALL-type queries (using stored procedured) if (oql.startsWith("CALL ")) { createCall(oql); return; } Lexer lexer = new Lexer(oql); Parser parser = new Parser(lexer); ParseTreeNode parseTree = parser.getParseTree(); _dbEngine = _dbImpl.getPersistenceEngine(); if (_dbEngine == null) throw new QueryException("Could not get a persistence engine"); ParseTreeWalker walker = new ParseTreeWalker(_dbEngine, parseTree, _dbImpl.getClassLoader()); _objClass = walker.getObjClass(); _clsDesc = walker.getClassDescriptor(); _expr = walker.getQueryExpression(); _paramInfo = walker.getParamInfo(); _projectionType = walker.getProjectionType(); _pathInfo = walker.getPathInfo(); // port param info types back to the format of old bind types. // first get the maximum SQL param. int max = 0; for (Enumeration e = _paramInfo.elements(); e.hasMoreElements(); ) { ParamInfo info = (ParamInfo) e.nextElement(); for (Enumeration f = info.getParamMap().elements(); f.hasMoreElements(); ) { int paramIndex = ((Integer) f.nextElement()).intValue(); if (paramIndex > max) max = paramIndex; } } // then create the types array and fill it _bindTypes = new Class[max]; for (Enumeration e = _paramInfo.elements(); e.hasMoreElements(); ) { ParamInfo info = (ParamInfo) e.nextElement(); for (Enumeration f = info.getParamMap().elements(); f.hasMoreElements(); ) { int paramIndex = ((Integer) f.nextElement()).intValue(); _bindTypes[paramIndex - 1] = f.getClass(); } } }
/** The simple parser for CALL-type queries (using stored procedured) */ public void createCall(String oql) throws QueryException { StringBuffer sql; int as; int leftParen; int rightParen; int paramCnt; String objType; ParamInfo info; StringBuffer sb; Integer paramNo; if (!oql.startsWith("CALL ")) { throw new QueryException("Stored procedure call must start with CALL"); } as = oql.indexOf(" AS "); if (as < 0) { throw new QueryException("Stored procedure call must end with \"AS <class-name>\""); } leftParen = oql.indexOf("("); rightParen = oql.indexOf(")"); sql = new StringBuffer(); paramCnt = 0; _paramInfo = new Hashtable(); if (leftParen < 0 && rightParen < 0) { sql.append(oql.substring(5, as)); } else { if ((leftParen < 0 && rightParen >= 0) || (leftParen > rightParen)) { throw new QueryException("Syntax error: parenthesis"); } sql.append(oql.substring(5, leftParen)); sql.append('('); for (int i = leftParen + 1; i < rightParen; i++) { if (oql.charAt(i) == '$') { // get parameter number if given sb = new StringBuffer(); for (int j = i + 1; j < rightParen; j++) { char c; c = oql.charAt(j); if (c < '0' || c > '9') { break; } sb.append(c); } if (sb.length() > 0) { paramNo = Integer.valueOf(sb.toString()); } else { paramNo = new Integer(paramCnt + 1); } info = (ParamInfo) _paramInfo.get(paramNo); if (info == null) { info = new ParamInfo("", "java.lang.Object"); } info.mapToSQLParam(paramCnt + 1); _paramInfo.put(paramNo, info); paramCnt++; } } for (int i = 0; i < paramCnt; i++) { sql.append('?'); if (i < paramCnt - 1) sql.append(','); } sql.append(')'); } _spCall = sql.toString(); _projectionType = ParseTreeWalker.PARENT_OBJECT; _bindTypes = new Class[paramCnt]; for (int i = 0; i < paramCnt; i++) _bindTypes[i] = Object.class; objType = oql.substring(as + 4).trim(); if (objType.length() == 0) { throw new QueryException("Missing object name"); } try { if (_dbImpl.getClassLoader() == null) _objClass = Class.forName(objType); else _objClass = _dbImpl.getClassLoader().loadClass(objType); } catch (ClassNotFoundException except) { throw new QueryException("Could not find class " + objType); } _dbEngine = _dbImpl.getPersistenceEngine(); if (_dbEngine == null || _dbEngine.getPersistence(_objClass) == null) throw new QueryException("Could not find an engine supporting class " + objType); }