/* * Update a single column. * * @param column the column name * @param value the String value with which update the column * @see tinySQLTable#UpdateCol * */ public override void UpdateCol(String colName, String value) //throws TinySQLException { String shortColumnName; try { /* * If it's the pseudo column _DELETED, return */ if (colName.equals("_DELETED")) { return; } /* * Retrieve the TsColumn object which corresponds to this column. */ shortColumnName = TinySQLGlobals.getShortName(colName); TsColumn column = (TsColumn)column_info.get(shortColumnName); if (column == null) { throw new TinySQLException("Can't update field=" + colName); } if (Utils.isDateColumn(column.type)) { /* * Convert non-blank dates to the standard YYYYMMDD format. */ if (value.trim().length() > 0) { value = UtilString.dateValue(value); } } /* * Seek the starting offset of the current record, * as indicated by currentRecordNumber */ ftbl.seek(dbfHeader.headerLength + (currentRecordNumber - 1) * dbfHeader.recordLength + column.position); /* * Enforce the correct column length, transform to byte and write to file */ value = Utils.forceToSize(value, column.size, " "); byte[] b = value.getBytes(Utils.encode); ftbl.write(b); dbfHeader.setTimestamp(ftbl); } catch (Exception e) { throw new TinySQLException(e.getMessage()); } }
/* * Get a column object for the named column. */ public TsColumn getColumn(String colName) //throws TinySQLException { int foundDot; String columnName; columnName = colName; foundDot = columnName.indexOf("."); if (foundDot > -1) { columnName = columnName.substring(foundDot + 1); } columnName = TinySQLGlobals.getShortName(columnName); TsColumn coldef = (TsColumn)column_info.get(columnName); if (coldef == (TsColumn)null) { throw new TinySQLException("Column " + columnName + " does not" + " exist in table " + table); } return(coldef); }
/* * Parse out the column definition for a CREATE statement. */ public TsColumn parseColumnDefn(String columnDefn) //throws TinySQLException { TsColumn createColumn; int i; FieldTokenizer ft; String columnName, colTypeStr, colTypeSpec; ft = new FieldTokenizer(columnDefn.toUpperCase(), ' ', false); /* * A column definition must consist of a column name followed by a * column specification. */ if (ft.countFields() < 2) { throwException(2); } columnName = ft.getField(0); /* * Check for quotes around a column name that may contain blanks. */ if (columnName.charAt(0) == '"' & columnName.charAt(columnName.length() - 1) == '"') { columnName = columnName.substring(1, columnName.length() - 1); } if (columnName.length() > 11) { columnName = TinySQLGlobals.getShortName(columnName); } createColumn = new TsColumn(columnName); colTypeStr = ""; for (i = 1; i < ft.countFields(); i++) { colTypeStr += ft.getField(1); } ft = new FieldTokenizer(colTypeStr, '(', false); colTypeStr = ft.getField(0); createColumn.size = 10; createColumn.decimalPlaces = 0; if (colTypeStr.equals("FLOAT")) { createColumn.size = 12; createColumn.decimalPlaces = 2; } colTypeSpec = ft.getField(1); if (!colTypeSpec.equals("NULL")) { /* * Parse out the scale and precision if supplied. */ ft = new FieldTokenizer(colTypeSpec, ',', false); createColumn.size = ft.getInt(0, 8); createColumn.decimalPlaces = ft.getInt(1, 0); } createColumn.type = java.lang.Integer.MIN_VALUE; for (i = 0; i < colTypeNames.Length; i++) { if (colTypeStr.equals(colTypeNames[i])) { createColumn.type = colTypes[i]; } } if (createColumn.type == java.lang.Integer.MIN_VALUE) { throwException(8); } if (TinySQLGlobals.PARSER_DEBUG) { java.lang.SystemJ.outJ.println("Column " + createColumn.name + ", type is " + createColumn.type + ",size is " + createColumn.size + ",precision is " + createColumn.decimalPlaces); } return(createColumn); }
/* * This method sets up particular phrase elements for the SQL command. * Examples would be a list of selected columns and tables for a SELECT * statement, or a list of column definitions for a CREATE TABLE * statement. These phrase elements will be added to the action list * once the entire statement has been parsed. */ public void setPhrase(String inputKeyWord, String inputString) //throws TinySQLException { String nextField, upperField, fieldString, tempString, columnName, columnAlias; java.lang.StringBuffer concatBuffer; FieldTokenizer ft1, ft2, ft3; TsColumn createColumn; /* * Handle compound keywords. */ if (inputString == (String)null) { lastKeyWord = inputKeyWord; return; } else if (inputString.trim().length() == 0) { lastKeyWord = inputKeyWord; return; } if (TinySQLGlobals.PARSER_DEBUG) { java.lang.SystemJ.outJ.println("setPhrase " + inputString); } ft1 = new FieldTokenizer(inputString, ',', false); while (ft1.hasMoreFields()) { nextField = ft1.nextField().trim(); if (TinySQLGlobals.PARSER_DEBUG) { java.lang.SystemJ.outJ.println(inputKeyWord + " field is " + nextField); } upperField = nextField.toUpperCase(); if (inputKeyWord.equals("SELECT")) { /* * Check for the keyword DISTINCT */ if (nextField.toUpperCase().startsWith("DISTINCT")) { distinct = true; nextField = nextField.substring(9).trim(); } /* * Check for and set column alias. */ ft2 = new FieldTokenizer(nextField, ' ', false); columnName = ft2.getField(0); columnAlias = (String)null; /* * A column alias can be preceded by the keyword AS which will * be ignored by tinySQL. */ if (ft2.countFields() == 2) { columnAlias = ft2.getField(1); } else if (ft2.countFields() == 3) { columnAlias = ft2.getField(2); } /* * Check for column concatenation using the | symbol */ ft2 = new FieldTokenizer(columnName, '|', false); if (ft2.countFields() > 1) { concatBuffer = new java.lang.StringBuffer("CONCAT("); while (ft2.hasMoreFields()) { if (concatBuffer.length() > 7) { concatBuffer.append(","); } concatBuffer.append(ft2.nextField()); } columnName = concatBuffer.toString() + ")"; } columnList.addElement(columnName); columnAliasList.addElement(columnAlias); contextList.addElement(inputKeyWord); } else if (inputKeyWord.equals("TABLE")) { /* * If the input keyword is TABLE, update the statement type to be a * compound type such as CREATE_TABLE, DROP_TABLE, or ALTER_TABLE. */ if (!statementType.equals("INSERT")) { statementType = statementType + "_TABLE"; } if (statementType.equals("CREATE_TABLE")) { /* * Parse out the column definition. */ ft2 = new FieldTokenizer(nextField, '(', false); if (ft2.countFields() != 2) { throwException(1); } tableName = ft2.getField(0); fieldString = ft2.getField(1); ft2 = new FieldTokenizer(fieldString, ',', false); while (ft2.hasMoreFields()) { tempString = ft2.nextField(); createColumn = parseColumnDefn(tempString); if (createColumn != (TsColumn)null) { columnList.addElement(createColumn); } } } else if (statementType.equals("DROP_TABLE")) { /* * Handle dropping of non-existent tables */ tableName = upperField; try { validateTable(upperField, true); } catch (Exception) { throw new TinySQLException("Table " + tableName + " does not exist."); } } else { tableName = upperField; validateTable(upperField, true); } } else if (inputKeyWord.equals("BY")) { /* * Set up Group by and Order by columns. */ if (lastKeyWord == (String)null) { throwException(6); } else { ft3 = new FieldTokenizer(upperField, ' ', false); columnList.addElement(ft3.getField(0)); if (ft3.countFields() == 2) { /* * ASC or DESC are the only allowable directives after GROUP BY */ if (ft3.getField(1).startsWith("ASC") | ft3.getField(1).startsWith("DESC")) { orderType = ft3.getField(1); } else { throwException(7); } } if (lastKeyWord.equals("ORDER")) { defaultOrderBy = false; } contextList.addElement(lastKeyWord); } } else if (inputKeyWord.equals("DROP")) { /* * Parse list of columns to be dropped. */ statementType = "ALTER_DROP"; ft2 = new FieldTokenizer(upperField, ' ', false); while (ft2.hasMoreFields()) { columnList.addElement(UtilString.removeQuotes(ft2.nextField())); } } else if (inputKeyWord.equals("RENAME")) { /* * Parse old and new column name. */ statementType = "ALTER_RENAME"; ft2 = new FieldTokenizer(upperField, ' ', false); oldColumnName = ft2.getField(0); newColumnName = ft2.getField(1); if (newColumnName.equals("TO") & ft2.countFields() == 3) { newColumnName = ft2.getField(2); } if (newColumnName.length() > 11) { newColumnName = TinySQLGlobals.getShortName(newColumnName); } } else if (inputKeyWord.equals("ADD")) { /* * Parse definition of columns to be added. */ statementType = "ALTER_ADD"; createColumn = parseColumnDefn(nextField); if (createColumn != (TsColumn)null) { columnList.addElement(createColumn); } } else if (inputKeyWord.equals("FROM")) { /* * Check for valid table */ tableName = upperField; validateTable(tableName); } else if (inputKeyWord.equals("INTO")) { ft2 = new FieldTokenizer(nextField, '(', false); if (ft2.countFields() != 2) { throwException(3); } tableName = ft2.getField(0).toUpperCase(); validateTable(tableName); fieldString = ft2.getField(1).toUpperCase(); ft2 = new FieldTokenizer(fieldString, ',', false); while (ft2.hasMoreFields()) { tempString = UtilString.removeQuotes(ft2.nextField()); columnList.addElement(tempString); contextList.addElement(inputKeyWord); } } else if (inputKeyWord.equals("VALUES")) { ft2 = new FieldTokenizer(nextField, '(', false); fieldString = ft2.getField(0); ft2 = new FieldTokenizer(fieldString, ',', false); while (ft2.hasMoreFields()) { tempString = UtilString.removeQuotes(ft2.nextField()); tempString = UtilString.replaceAll(tempString, "''", "'"); valueList.addElement(tempString); } } else if (inputKeyWord.equals("UPDATE")) { tableName = nextField.toUpperCase(); validateTable(tableName); } else if (inputKeyWord.equals("SET")) { /* * Parse the update column name/value pairs */ ft2 = new FieldTokenizer(nextField, '=', false); if (ft2.countFields() != 2) { throwException(4); } columnList.addElement(ft2.getField(0)); contextList.addElement(inputKeyWord); valueList.addElement(UtilString.removeQuotes(ft2.getField(1))); } else if (inputKeyWord.equals("WHERE")) { whereClause = new TinySQLWhere(nextField, tables); } else if (!inputKeyWord.equals("TABLE")) { throwException(10); } } lastKeyWord = inputKeyWord; }
internal TsColumn(String s, java.util.Hashtable <Object, Object> tableDefs, String inputContext) //throws tinySQLException { FieldTokenizer ft, ftArgs; int j, numericType, nameLength, dotAt, argIndex; String upperName, checkName, nextArg; TinySQLTable jtbl; TsColumn tcol; java.util.Vector <Object> t; java.util.Enumeration <Object> col_keys; name = s; longName = name; nameLength = name.length(); contextList = new java.util.Vector <Object>(); contextList.addElement(inputContext); ft = new FieldTokenizer(name, '(', false); if (ft.countFields() == 2) { /* * This is a function rather than a simple column or constant */ functionName = ft.getField(0).toUpperCase(); if (functionName.equals("COUNT")) { type = java.sql.Types.INTEGER; size = 10; intValue = java.lang.Integer.MIN_VALUE; groupedColumn = true; } else if (functionName.equals("SUM")) { type = java.sql.Types.FLOAT; size = 10; groupedColumn = true; } else if (functionName.equals("TO_DATE")) { type = java.sql.Types.DATE; size = 10; } else if (functionName.equals("CONCAT") | functionName.equals("UPPER") | functionName.equals("SUBSTR") | functionName.equals("TRIM")) { type = java.sql.Types.CHAR; } functionArgString = ft.getField(1); ftArgs = new FieldTokenizer(functionArgString, ',', false); functionArgs = new java.util.Vector <Object>(); argIndex = 0; while (ftArgs.hasMoreFields()) { nextArg = ftArgs.nextField(); tcol = new TsColumn(nextArg, tableDefs, inputContext); if (tcol.isGroupedColumn()) { groupedColumn = true; } /* * MAX and MIN functions can be either FLOAT or CHAR types * depending upon the type of the argument. */ if (functionName.equals("MAX") | functionName.equals("MIN")) { if (argIndex > 0) { throw new TinySQLException("Function can only have 1 argument"); } groupedColumn = true; type = tcol.type; size = tcol.size; } else if (functionName.equals("CONCAT")) { type = java.sql.Types.CHAR; size += tcol.size; } else if (functionName.equals("UPPER")) { type = java.sql.Types.CHAR; size = tcol.size; } else if (functionName.equals("TO_DATE")) { type = java.sql.Types.DATE; size = 10; } else if (functionName.equals("TRIM")) { type = java.sql.Types.CHAR; size = tcol.size; } else if (functionName.equals("SUBSTR")) { type = java.sql.Types.CHAR; if (argIndex == 0 & tcol.type != java.sql.Types.CHAR) { throw new TinySQLException("SUBSTR first argument must be character"); } else if (argIndex == 1) { if (tcol.type != java.sql.Types.INTEGER | tcol.intValue < 1) { throw new TinySQLException("SUBSTR second argument " + tcol.getString() + " must be integer > 0"); } } else if (argIndex == 2) { if (tcol.type != java.sql.Types.INTEGER | tcol.intValue < 1) { throw new TinySQLException("SUBSTR third argument " + tcol.getString() + " must be integer > 0"); } size = tcol.intValue; } } argIndex++; functionArgs.addElement(tcol); } } else { /* * Check for SYSDATE */ if (name.toUpperCase().equals("SYSDATE")) { isConstant = true; type = java.sql.Types.DATE; size = 10; notNull = true; valueSet = true; //Basties mote: not really SimpleDateFormat needed... - need yyyy-MM-dd // stringValue = fmtyyyyMMdd.format(today.getTime()); stringValue = System.DateTime.Today.ToString("yyyy-MM-dd"); /* * Check for a quoted string */ } else if (UtilString.isQuotedString(name)) { isConstant = true; type = java.sql.Types.CHAR; stringValue = UtilString.removeQuotes(name); if (stringValue != (String)null) { size = stringValue.length(); notNull = true; valueSet = true; } } else { /* * Check for a numeric constant */ numericType = UtilString.getValueType(name); if (numericType == java.sql.Types.INTEGER) { intValue = java.lang.Integer.valueOf(name).intValue(); size = 10; type = numericType; isConstant = true; notNull = true; valueSet = true; } else if (numericType == java.sql.Types.FLOAT) { floatValue = java.lang.Float.valueOf(name).floatValue(); size = 10; type = numericType; isConstant = true; notNull = true; valueSet = true; } else { /* * This should be a column name. */ columnTable = (TinySQLTable)null; upperName = name.toUpperCase(); if (TinySQLGlobals.DEBUG) { java.lang.SystemJ.outJ.println("Trying to find table for " + upperName); } dotAt = upperName.indexOf("."); if (dotAt > -1) { tableName = upperName.substring(0, dotAt); if (tableDefs != (java.util.Hashtable <Object, Object>)null & tableName.indexOf("->") < 0) { t = (java.util.Vector <Object>)tableDefs.get("TABLE_SELECT_ORDER"); tableName = UtilString.findTableAlias(tableName, t); } upperName = upperName.substring(dotAt + 1); /* * Check to see if this column name has a short equivalent. */ if (upperName.length() > 11) { longName = name; upperName = TinySQLGlobals.getShortName(upperName); } columnTable = (TinySQLTable)tableDefs.get(tableName); } else if (tableDefs != (java.util.Hashtable <Object, Object>)null) { /* * Check to see if this column name has a short equivalent. */ if (upperName.length() > 11) { longName = name; upperName = TinySQLGlobals.getShortName(upperName); } /* * Use an enumeration to go through all of the tables to find * this column. */ t = (java.util.Vector <Object>)tableDefs.get("TABLE_SELECT_ORDER"); for (j = 0; j < t.size(); j++) { tableName = (String)t.elementAt(j); jtbl = (TinySQLTable)tableDefs.get(tableName); col_keys = jtbl.column_info.keys(); /* * Check all columns. */ while (col_keys.hasMoreElements()) { checkName = (String)col_keys.nextElement(); if (checkName.equals(upperName)) { upperName = checkName; columnTable = jtbl; break; } } if (columnTable != (TinySQLTable)null) { break; } } } else { if (TinySQLGlobals.DEBUG) { java.lang.SystemJ.outJ.println("No table definitions."); } } if (columnTable != (TinySQLTable)null) { name = columnTable.table + "->" + columnTable.tableAlias + "." + upperName; type = columnTable.ColType(upperName); size = columnTable.ColSize(upperName); decimalPlaces = columnTable.ColDec(upperName); tableName = columnTable.table + "->" + columnTable.tableAlias; } } } } }