/* HSQLDB.java - Created: January 16, 2007
* Copyright (C) 2007, 2008 Clayton Carter
*
* This file is part of the project "Crop Planning Software". For more
* information:
* website: https://github.com/claytonrcarter/cropplanning
* email: cropplanning@gmail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package CPS.Core.DB;
import CPS.Data.*;
import CPS.Module.CPSConfigurable;
import CPS.Module.CPSDataModelSQL;
import CPS.Module.CPSDataModelConstants;
import CPS.Module.CPSGlobalSettings;
import CPS.Module.CPSWizardPage;
import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.UniqueList;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.List;
import java.util.Map;
import javax.swing.JPanel;
import net.sf.persist.*;
/**
*
* @author Clayton
*/
public class HSQLDB extends CPSDataModelSQL implements CPSConfigurable {
private static final boolean DEBUG = true;
static final String CROP_VAR_TABLE = "CROPS_VARIETIES";
static final String CROP_PLAN_TABLE = "CROP_PLANS";
static final String CPS_META_TABLE = "CPS_METADATA";
protected static final boolean ESCAPE_WITH_SINGLE_QUOTES = true;
protected static final boolean ESCAPE_WITH_DOUBLE_QUOTES = false;
private String hsqlDriver = "org.hsqldb.jdbcDriver";
private String dbDir = System.getProperty("user.dir");
private String dbFile = "CPSdb";
private ResultSet rsListCache = null;
private ResultSet rsCropCache = null;
private ResultSet rsPlantCache = null;
public String state = null;
private HSQLColumnMap columnMap;
private HSQLQuerier query;
private Persist p;
HSQLSettings localSettings;
public HSQLDB() {
super();
setModuleName( "HSQLDB" );
setModuleDescription( "A full featured DataModel based on HSQLDB.");
setModuleVersion( CPSGlobalSettings.getVersion() );
localSettings = new HSQLSettings();
}
@Override
public int init () {
// enable Persist logging
// org.apache.log4j.BasicConfigurator.configure();
if ( true || localSettings.getUseGlobalDir() )
dbDir = CPSGlobalSettings.getDataOutputDir();
else
dbDir = localSettings.getCustomOutDir();
debug( "attempting to connect to the db" );
Connection con = HSQLConnect.getConnection( dbDir, dbFile, hsqlDriver );
try {
// if the db DNE
if ( con == null ) {
debug( "connection failed, presumably the db DNE" );
p = HSQLConnect.createDB( dbDir, dbFile, getModuleVersionAsLongInt() );
}
else
p = new Persist( con );
/* only needed when we're using a server mode db */
if ( false && HSQLConnect.dbIsEmpty( con ) ) {
debug( "The db seems to be empty." );
HSQLDBCreator.createTables( p, getModuleVersionAsLongInt() );
}
} catch ( Exception e ) {
e.printStackTrace();
}
HSQLUpdate.updateDB( p, getModuleVersionAsLongInt() );
// TODO Persist port HERE
query = new HSQLQuerier( p.getConnection() );
columnMap = new HSQLColumnMap();
return 0;
}
//****************************************************************************//
// Unique value methods
//****************************************************************************//
public synchronized List<String> getFlatSizeList( String planName ) {
// if the plan doesn't exist, then don't get the mapping, just return an empty list
if ( ! HSQLConnect.tableExists( p.getConnection(), planName ))
return new ArrayList<String>();
TableMapping tm = (TableMapping) p.getMapping( CPSPlanting.class, planName );
String plantColName = tm.getColumnNameForMethod( "getFlatSize" );
tm = (TableMapping) p.getMapping( CPSCrop.class, CROP_VAR_TABLE );
String cropColName = tm.getColumnNameForMethod( "getFlatSize" );
return getDistinctValsFromCVAndPlan( planName, plantColName, cropColName );
}
public synchronized List<String> getFieldNameList( String planName ) {
// if the plan doesn't exist, then don't get the mapping, just return an empty list
if ( ! HSQLConnect.tableExists( p.getConnection(), planName ))
return new ArrayList<String>();
TableMapping tm = (TableMapping) p.getMapping( CPSPlanting.class, planName );
// TODO should this query all crop plans, or just one. Just one for now.
return HSQLQuerier.getDistinctValuesForColumn( p.getConnection(),
planName,
tm.getColumnNameForMethod( "getLocation" ) );
}
public synchronized List<String> getCropNameList() {
TableMapping tm = (TableMapping) p.getMapping( CPSCrop.class, CROP_VAR_TABLE );
return HSQLQuerier.getDistinctValuesForColumn( p.getConnection(),
CROP_VAR_TABLE,
tm.getColumnNameForMethod( "getCropName" ) );
}
public synchronized List<String> getVarietyNameList( String crop_name, String planName ) {
// if the plan doesn't exist, then don't get the mapping, just return an empty list
if ( ! HSQLConnect.tableExists( p.getConnection(), planName ))
return new ArrayList<String>();
TableMapping tm = (TableMapping) p.getMapping( CPSPlanting.class, planName );
String plantColName = tm.getColumnNameForMethod( "getVarietyName" );
tm = (TableMapping) p.getMapping( CPSCrop.class, CROP_VAR_TABLE );
String cropColName = tm.getColumnNameForMethod( "getVarietyName" );
return getDistinctValsFromCVAndPlan( planName, plantColName, cropColName );
}
// TODO port to Persist
private synchronized List<String> getDistinctValsFromCVAndPlan( String planName, String planColName, String cropColName ) {
ArrayList<String> l = new ArrayList<String>();
Set set = new HashSet();
if ( planName != null )
l.addAll( HSQLQuerier.getDistinctValuesForColumn( p.getConnection(),
planName,
planColName ) );
l.addAll( HSQLQuerier.getDistinctValuesForColumn( p.getConnection(),
CROP_VAR_TABLE,
cropColName ) );
// list now contains all values, possibly some duplicates
// this ensures that the values are unique
set.addAll ( l );
l.clear();
l.addAll( set );
return l;
}
public synchronized List<String> getFamilyNameList() {
TableMapping tm = (TableMapping) p.getMapping( CPSCrop.class, CROP_VAR_TABLE );
return HSQLQuerier.getDistinctValuesForColumn( p.getConnection(),
CROP_VAR_TABLE,
tm.getColumnNameForMethod( "getFamilyName" ));
}
public synchronized List<String> getListOfCropPlans() {
// read from the table into a List of Map objects
List<Map<String,Object>> plansMap =
p.readMapList( "SELECT plan_name, year" +
" FROM " + CROP_PLAN_TABLE +
" ORDER BY year DESC" );
List<String> plansList = new ArrayList<String>( plansMap.size() );
// convert the Map into just a List of Strings
for ( Map<String,Object> m : plansMap )
plansList.add( (String) m.get("plan_name") );
return plansList;
}
@Override
public List<String> getRequirementsForPlan( String planName ) {
List<CPSPlanting> cropPlan = getCropPlan( planName );
BasicEventList<String> reqs = new BasicEventList<String>();
for ( CPSPlanting pl : cropPlan ) {
reqs.addAll( Arrays.asList( pl.getOtherRequirements().split(" ") ));
}
return new UniqueList<String>(reqs);
}
//****************************************************************************//
/* COLUMN NAMES */
//****************************************************************************//
public List<Integer> getCropDefaultProperties() {
return columnMap.getDefaultCropPropertyList();
}
public List<Integer> getCropDisplayableProperties() {
return columnMap.getCropPropertyList();
}
public List<String> getCropDefaultPropertyNames() {
return columnMap.getDefaultCropColumnList();
}
public List<String> getCropDisplayablePropertyNames() {
return columnMap.getCropDisplayableColumns();
}
public List<String[]> getCropPrettyNames() {
return columnMap.getCropPrettyNameMapping();
}
public List<Integer> getPlantingDefaultProperties() {
return columnMap.getDefaultPlantingPropertyList();
}
public List<Integer> getPlantingDisplayableProperties() {
return columnMap.getPlantingPropertyList();
}
public List<String> getPlantingDefaultPropertyNames() {
return columnMap.getDefaultPlantingColumnList();
}
public List<String> getPlantingDisplayablePropertyNames() {
return columnMap.getPlantingDisplayableColumns();
}
public List<String[]> getPlantingPrettyNames() {
return columnMap.getPlantingPrettyNameMapping();
}
public List<String[]> getPlantingShortNames() {
return columnMap.getPlantingShortNameMapping();
}
/* END COLUMN NAMES */
/*
* CROP LIST METHODS
*/
public List<CPSCrop> getCropList() {
TableMapping tm = (TableMapping) p.getMapping( CPSCrop.class, CROP_VAR_TABLE);
String selectSQL = tm.getSelectWhereSql() + tm.getColumnNameForMethod( "getVarietyName" ) + " is null";
return p.readList( CPSCrop.class, selectSQL );
}
public List<CPSCrop> getVarietyList() {
TableMapping tm = (TableMapping) p.getMapping( CPSCrop.class, CROP_VAR_TABLE);
String selectSQL = tm.getSelectWhereSql() + tm.getColumnNameForMethod( "getVarietyName" ) + " is not null";
List<CPSCrop> vars = p.readList( CPSCrop.class, selectSQL );
for ( CPSCrop v : vars)
performInheritanceForCropVar( v );
return vars;
}
public List<CPSCrop> getCropAndVarietyList() {
List<CPSCrop> crops = p.readList( CROP_VAR_TABLE, CPSCrop.class );
for ( CPSCrop c : crops)
performInheritanceForCropVar( c );
return crops;
}
/*
* CROP PLAN METHODS
*/
public void createCropPlan( String planName, int year, String desc ) {
HSQLDBCreator.createCropPlan( p, planName, year, desc );
updateDataListeners();
}
public void updateCropPlan( String planName, int year, String desc ) {
HSQLDBCreator.updateCropPlan( p, planName, year, desc );
// TODO commented out because I can't imagine a time (yet) when
// we'll need to update when a plan changes metadata
// updateDataListeners();
}
public void deleteCropPlan( String planName ) {
HSQLDBCreator.deleteCropPlan( p, planName );
updateDataListeners();
}
public int getCropPlanYear( String planName ) {
return HSQLQuerier.getCropPlanYear( p.getConnection(), planName );
}
public String getCropPlanDescription( String planName ) {
return HSQLQuerier.getCropPlanDescription( p.getConnection(), planName );
}
public void finalizeCropPlan( String planName ) {
List<CPSPlanting> plan = getCropPlan(planName);
for ( CPSPlanting pl : plan ) {
if ( pl.getID() % 20 == 0 )
// TODO what is this all about?
System.out.println( "\n" + pl + "\n" );
p.update( planName, pl );
}
}
@Override
public boolean cropPlanExists( String planName ) {
return HSQLConnect.tableExists( p.getConnection(), planName );
}
public List<CPSPlanting> getCropPlan(String plan_name) {
debug( "Retrieving crop plan: " + plan_name );
List<CPSPlanting> cropPlan = p.readList( plan_name, CPSPlanting.class );
debug( "Crop plan contains " + cropPlan.size() + " plantings." );
for ( CPSPlanting planting : cropPlan ) {
performInheritanceForPlanting( planting );
}
return cropPlan;
}
/**
* Returns the summation of certain data for a particular crop plan. DEPRECATED after version .1.5 Beta1.
* @param plan_name Name of plan to sum on.
* @param filter Tilter to apply to the plan before summing happens.
* @return a CPSPlanting object whose columns are filled with the sums from the crop plan.
* @deprecated
*/
public CPSPlanting getSumsForCropPlan( String plan_name, CPSComplexPlantingFilter filter ) {
return new CPSPlanting();
}
/* ***************************************************************** */
/* CROP AND VARIETY METHODS */
/* ***************************************************************** */
public CPSPlanting getCommonInfoForPlantings( String plan_name, List<Integer> plantingIDs ) {
TableMapping tm = (TableMapping) p.getMapping( CPSPlanting.class, plan_name);
// TODO maybe this should more elegantly handle situations w/ more than 1 primary key
CPSPlanting planting = p.read( CPSPlanting.class, query.buildCommonInfoQuery( plan_name, tm.getPrimaryKeys()[0], tm.getNotPrimaryKeys(), plantingIDs ) );
performInheritanceForPlanting(planting);
planting.setCommonIDs( plantingIDs );
return planting;
}
public CPSCrop getCommonInfoForCrops( List<Integer> cropIDs ) {
TableMapping tm = (TableMapping) p.getMapping( CPSCrop.class, CROP_VAR_TABLE);
CPSCrop crop = p.read( CPSCrop.class, query.buildCommonInfoQuery( CROP_VAR_TABLE, tm.getPrimaryKeys()[0], tm.getNotPrimaryKeys(), cropIDs ) );
crop.setCommonIDs( cropIDs );
return crop;
}
public CPSCrop getCropInfo( int id ) {
CPSCrop c;
if ( id != -1 )
c = p.readByPrimaryKey( CROP_VAR_TABLE, CPSCrop.class, id );
else
c = new CPSCrop();
performInheritanceForCropVar( c );
return c;
}
public CPSCrop getVarietyInfo( String cropName, String varName ) {
if ( cropName == null || cropName.equalsIgnoreCase("null") || cropName.equals("") )
return new CPSCrop();
TableMapping tm = (TableMapping) p.getMapping( CPSCrop.class, CROP_VAR_TABLE);
String condExp = tm.getColumnNameForMethod( "getCropName" ) + " = " + escapeValue( cropName );
varName = escapeValue( varName );
if ( varName == null || varName.equalsIgnoreCase( "null" ) || varName.equals("") )
condExp += " AND " + tm.getColumnNameForMethod( "getVarietyName" ) + " IS NULL";
else
condExp += " AND " + tm.getColumnNameForMethod( "getVarietyName" ) + " = " + varName;
String selectSQL = tm.getSelectWhereSql() + condExp;
List<CPSCrop> l = p.readList( CPSCrop.class, selectSQL );
CPSCrop c;
if ( l.isEmpty() ) {
c = new CPSCrop();
} else {
if ( l.size() > 1 )
System.err.println( "ERROR: found more than one entry matching: " + condExp );
c = l.get(0);
performInheritanceForCropVar( c );
}
return c;
}
public void updateCrop( CPSCrop crop ) {
HSQLDBCreator.updateCrop( p, crop );
// we have to do this because it may (will?) change the inheritance stuff
updateDataListeners();
}
public void updateCrops( CPSCrop changes, List<Integer> ids ) {
HSQLDBCreator.updateCrops( p, columnMap, changes, ids );
updateDataListeners();
}
public CPSCrop createCrop(CPSCrop crop) {
int newID = HSQLDBCreator.insertCrop( p, crop );
if ( newID == -1 )
return new CPSCrop();
else
return getCropInfo( newID );
}
public void deleteCrop( int cropID ) {
CPSCrop c = p.readByPrimaryKey( CROP_VAR_TABLE, CPSCrop.class, cropID );
if ( c != null )
p.delete( CROP_VAR_TABLE, c );
// updateDataListeners();
}
protected void performInheritanceForCropVar( CPSCrop crop ) {
if ( crop == null ) return;
if ( crop.isVariety() ) {
CPSCrop parent = getCropInfo( crop.getCropName() );
if ( parent != null && parent.getID() != -1 ) {
crop.inheritFrom( parent );
}
}
}
/* ********************************************************************************************************* */
/* Planting methods */
/* ********************************************************************************************************* */
public void deletePlanting( String planName, int plantingID ) {
CPSPlanting planting = p.readByPrimaryKey( planName, CPSPlanting.class, plantingID );
p.delete( planName, planting );
// updateDataListeners();
}
// also called with "empty" or new CPSPlantings, so should handle case where
// the "cropID" is not valid
public CPSPlanting createPlanting( String planName, CPSPlanting planting ) {
int newID = HSQLDBCreator.insertPlanting( p, planName, planting );
// updateDataListeners();
if ( newID == -1 )
return new CPSPlanting();
else
return getPlanting( planName, newID );
}
public CPSPlanting getPlanting( String planName, int id ) {
CPSPlanting planting;
TableMapping tm = (TableMapping) p.getMapping( CPSPlanting.class, planName );
if ( id != -1 )
planting = p.read( CPSPlanting.class, tm.getSelectSql(), new Object[]{ new Integer( id ) } );
else
return new CPSPlanting(); // inheriting not necessary
performInheritanceForPlanting( planting );
return planting;
}
public void updatePlanting( String planName, CPSPlanting planting ) {
HSQLDBCreator.updatePlanting( p, planName, planting );
}
public void updatePlantings( String planName, CPSPlanting changes, List<Integer> changedIDs ) {
debug( "saving changes to plan " + planName + ": " + changes.toString() );
HSQLDBCreator.updatePlantings( p, columnMap, planName, changes, changedIDs );
updateDataListeners();
}
protected void performInheritanceForPlanting( CPSPlanting planting ) {
if ( planting == null ) return;
// clumsy!! TODO fix this to be more elegant
TableMapping tm = (TableMapping) p.getMapping( CPSCrop.class, CROP_VAR_TABLE );
String selectSQL = tm.getSelectWhereSql();
selectSQL += tm.getColumnNameForMethod( "getCropName" ) + " = " + escapeValue( planting.getCropName() );
selectSQL += " AND ( " + tm.getColumnNameForMethod( "getVarietyName" ) + " = " + escapeValue( planting.getVarietyName() );
selectSQL += " OR " + tm.getColumnNameForMethod( "getVarietyName" ) + " IS NULL ) ";
List<CPSCrop> vars = p.readList( CPSCrop.class, selectSQL );
CPSCrop parent = null;
if ( vars.isEmpty() ) {
// no inheritance to do
return;
} else if ( vars.size() > 1 ) {
// multiple matches == there is a crop && a variety
// so we need to remove the crop
CPSCrop c = null;
for ( CPSCrop v : vars)
if ( v.isCrop() )
c = v;
if ( c != null )
vars.remove(c);
if ( vars.size() == 1 )
parent = vars.get(0);
else {
debug( "More than one crop/var match: " + vars.toString() );
parent = vars.get(0);
}
if ( parent != null && c != null )
parent.inheritFrom( c );
} else {
// only one match, so there is nothing to inherit from
parent = vars.get(0);
}
if ( parent != null && parent.getID() != -1 ) {
planting.inheritFrom( parent );
}
}
/* ********************************************************************************************************* */
/* Utility methods */
/* ********************************************************************************************************* */
/**
* SQL distinguishes between values that are NULL and those that are just
* blank. This method is meant to capture our default values
* and format them properly so that we might detect proper null values
* upon read. We use this to distinguish between null values and just
* data with no entry.
*
* OK, so what constitutes a null value, blank value, and one that is
* just a default value? Let's try to answer that for different data types:
* Object: only 'null' objects are SQL NULL
* String: a string "null" is read as SQL NULL
* anything else is considered a valid entry
* Therefore we must decide when to pass back "null" vs "" when
* strings w/o entries are encountered.
* Integer: a value of -1 is an SQL NULL
* anything else is valid
* Float: a value of -1.0 is an SQL NULL, all else valid
* Date: a millisecond date of 0 is an SQL NULL
* anything else is valid
*
* @param o The object to test and format.
* @return A string representing the SQL value of Object o.
*/
/* Currently handles: null, String, Integer, CPSCrop, CPSPlanting */
public static String escapeValue( Object o ) {
// if the datum doesn't exist, use NULL
if ( o == null )
return "NULL";
// if the datum is a string and is only "", use NULL, else escape it
else if ( o instanceof String )
if ( ((String) o).equalsIgnoreCase( "null" ) || ((String) o).equals( "" ) )
return "NULL";
else {
String val = o.toString();
val = val.replaceAll( "'", "''" );
// val = val.replaceAll( "\"", "\"\"" );
return "'" + val + "'";
}
// if the datum is an int whose value is -1, use NULL
else if ( o instanceof Integer && ((Integer) o).intValue() == -1 )
return "NULL";
else if ( o instanceof Float && ((Float) o).floatValue() == -1.0 )
return "NULL";
else if ( o instanceof java.util.Date || o instanceof java.sql.Date ) {
// cast to util.Date to cover all of our bases, sql.Date is in scope
// here, so we must use fully qualified name
if ( ((java.util.Date) o).getTime() == 0 )
return "NULL";
else {
// TODO figure how to make the date format more flexible
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return "'" + sdf.format((java.util.Date) o) + "'";
}
}
/* Not entirely sure what these are here for. Actually, the CPSCrop
* case is probably for data cascading. Planting case might not be
* appropriate */
else if ( o instanceof CPSCrop )
return escapeValue( ((CPSCrop) o).getCropName() );
else if ( o instanceof CPSPlanting )
return escapeValue( ((CPSPlanting) o).getCropName() );
else
return o.toString();
}
public static String escapeTableName( String t ) {
return escapeTableName( t, ESCAPE_WITH_DOUBLE_QUOTES );
}
public static String escapeTableName( String t, boolean useSingleQuotes ) {
// if the "table" is an embedded select statement (enclosed in "()")
// then don't quote it
if ( t.trim().matches( "\\(.*\\)" ))
return t;
else {
// if the string contains a quotation mark, escape all quotation marks
if ( t.matches( ".*\".*" ) )
t = t.replaceAll( "\\\"", "\"\"" );
if ( useSingleQuotes )
return "'" + t + "'";
else
return "\"" + t + "\"";
}
}
/** captureValue methods are opposite of escapeValue method.
* Takes an SQL value and converts it to the correct "default" or "null"
* value for our program.
*/
public static Date captureDate( Date d ) {
if ( d == null )
// PENDING this is totally bogus and needs to have a sane "default" date
return new Date( 0 );
else
return d;
}
public static float getFloat( ResultSet rs, String columnName ) throws SQLException {
float f = rs.getFloat( columnName );
if ( rs.wasNull() )
f = -1f;
return captureFloat( f );
}
public static float captureFloat( float f ) {
// if ( f <= 0 )
if ( f == -1 )
return (float) -1.0;
else
return f;
}
public static int getInt( ResultSet rs, String columnName ) throws SQLException {
// captureInt( rs.getInt( "time_to_tp" ) );
int i = rs.getInt( columnName );
if ( rs.wasNull() )
i = -1;
return captureInt( i );
}
public static int captureInt( int i ) {
// if ( i <= 0 )
if ( i == -1 )
return -1;
else
return i;
}
public static String captureString( String s ) {
if ( s == null || s.equalsIgnoreCase("null") || s.equals("") )
return null;
else
return s;
}
/**
* Create a comma delimited string of integers from an List of Integers.
* @param ids List<Integer> to convert
* @return comma delimited string of integers
*/
public static String intListToIDString( List<Integer> ids ) {
String idString = "";
for ( Integer i : ids )
idString += i.toString() + ", ";
idString = idString.substring( 0, idString.lastIndexOf( ", " ));
return idString;
}
public static String listToCSVString( List l ) {
String s = "";
for ( Object o : l )
s += o.toString() + ", ";
s = s.substring( 0, s.lastIndexOf( ", " ));
return s;
}
private String sortColumnFromPropertyNum( int recordType, int prop ) {
String sortCol = " asc";
if ( prop < 0 ) {
sortCol = " desc";
prop = -1 * prop;
}
if ( recordType == CPSDataModelConstants.RECORD_TYPE_CROP )
sortCol = columnMap.getCropColumnNameForProperty(prop) + sortCol;
else if ( recordType == CPSDataModelConstants.RECORD_TYPE_PLANTING )
sortCol = columnMap.getPlantingColumnNameForProperty(prop) + sortCol;
else
sortCol = "";
return sortCol;
}
public String propNameFromPropNum( int recordType, int propertyNum ) {
if ( recordType == CPSDataModelConstants.RECORD_TYPE_CROP )
return columnMap.getCropColumnNameForProperty( propertyNum );
else if ( recordType == CPSDataModelConstants.RECORD_TYPE_PLANTING )
return columnMap.getPlantingColumnNameForProperty( propertyNum );
else
return "UnknownProperty";
}
public int propNumFromPropName( int recordType, String propertyName ) {
if ( recordType == CPSDataModelConstants.RECORD_TYPE_CROP )
return columnMap.getCropPropertyNumFromName( propertyName );
else if ( recordType == CPSDataModelConstants.RECORD_TYPE_PLANTING )
return columnMap.getPlantingPropertyNumFromName( propertyName );
else
return 0;
}
public String propertyNumListToColumnString( int recordType, List<Integer> props ) {
String cols = "";
for ( Integer prop : props )
if ( recordType == CPSDataModelConstants.RECORD_TYPE_CROP )
cols += columnMap.getCropColumnNameForProperty( prop ) + ", ";
else if ( recordType == CPSDataModelConstants.RECORD_TYPE_PLANTING )
cols += columnMap.getPlantingColumnNameForProperty( prop ) + ", ";
cols = cols.substring( 0, cols.lastIndexOf( ", " ));
return cols;
}
public int shutdown() {
try {
// TODO check to see which which mode we're in: if server, don't do the following
// TODO port to Persist in a better manner, perhaps add a shutdown() method to Persist?
Statement st = p.getConnection().createStatement();
st.execute("SHUTDOWN");
p.getConnection().close();
}
catch ( SQLException ex ) {
ex.printStackTrace();
}
return 0;
}
@Override
protected void updateDataListeners() {
super.updateDataListeners();
}
@Override
protected int saveState() { throw new UnsupportedOperationException( "Not supported yet." ); }
public JPanel getConfigurationDisplay () { return null; }
public CPSWizardPage[] getConfigurationWizardPages () {
return new CPSWizardPage[] { new NewPlanWizardPage( this ),
new CreateRecordsWizardPage() };
}
public void resetConfiguration () {}
public void resetConfigurationToDefaults () {}
public void saveConfiguration () {}
private static String toXML(ResultSet rs) throws SQLException {
ResultSetMetaData rsmd = rs.getMetaData();
int colCount = rsmd.getColumnCount();
StringBuffer xml = new StringBuffer();
xml.append("<Results>\n");
while (rs.next())
{
xml.append(" <Row>\n");
for (int i = 1; i <= colCount; i++)
{
String columnName = rsmd.getColumnName( i );
Object value = rs.getObject( i );
if ( rs.wasNull() )
continue;
xml.append( " <" + columnName + ">" );
xml.append( value.toString().trim() );
xml.append( "</" + columnName + ">\n" );
}
xml.append(" </Row>\n");
}
xml.append("</Results>\n");
return xml.toString();
}
}