Class SDriver

java.lang.Object
simpleorm.sessionjdbc.SDriver
Direct Known Subclasses:
SDriverDB2, SDriverDerby, SDriverHSQLH2, SDriverInformix, SDriverInterbase, SDriverMSSQL, SDriverMySQL, SDriverOracle, SDriverPostgres, SDriverSapDB, SDriverSybase, SQLiteDriver

public class SDriver extends Object
This is the internal generic database driver that contains database dependent code. Specific SimpleORM drivers extend this class and specialize its methods as required. The driver type is infered from the jdbc connection's meta data.

(Profiling suggests that memoising these generaters could produce a 5-10% improvement in bulk updates.)

There is now one driver instance per connection so one can say SSession.getDriver().setMyFavouriteParam(...)

SQL 92 standard data types, I think:- boolean, Character(n), character varying(n), date, float(p), real, double precission, smallint, int | integer, decimal(p,s), numeric(p,s), time, interval, timestamp with timezone,

  • Constructor Details

    • SDriver

      protected SDriver()
  • Method Details

    • registerDriver

      public void registerDriver()
      Add driver to the list of possible drivers that can be found by SSession.attach. The key is returned by driverName.
    • driverName

      protected String driverName()
      The driver name to be compared to getMetaData().getDriverName()
    • queryExecuteFactory

      protected simpleorm.sessionjdbc.SQueryExecute queryExecuteFactory(SSessionJdbc session, SQuery query)
    • appendQuotedIdentifier

      protected void appendQuotedIdentifier(String ident, StringBuffer buf)
      Wraps identifiers in "s to avoid reserved word issues. (Override this for dbs that use different chars, eg [xxx] for MS-SQL. We do quote these days to avoid the endless problems with reserved words.
    • appendQuotedIdentifier

      protected void appendQuotedIdentifier(String ident, StringBuffer buf, char quote)
    • appendColumnName

      public void appendColumnName(SFieldScalar field, StringBuffer buf)
      name appended, quoted iff appropriate.
    • appendTableName

      public void appendTableName(SRecordMeta table, StringBuffer buf)
      name, quoted iff appropriate.
    • maxIdentNameLength

      public int maxIdentNameLength()
      The maximum size for table names and foreign key constraint names.
    • supportsLocking

      public boolean supportsLocking()
      True if exclusive locks are properly supported. Otherwise optimistic locks are always used.

    • alterTableAddColumnSQL

      public String alterTableAddColumnSQL(SFieldScalar field)
      These alow you to create a new SFieldMeta object at runtime and then update the table to include it. Eg. for end user customizations. ## Ideally this could be further automated so that the SRecordMeta and JDBC meta data for a table could be compared and the table automatically altered.
    • alterTableDropColumnSQL

      public String alterTableDropColumnSQL(SFieldScalar field)
    • createTableSQL

      public String createTableSQL(SRecordMeta<?> meta)
      Returns a CREATE TABLE for this table. Delegated from SRecord. This is split up into many sub-methods so that they can be selectively specialized by other drivers.
    • clauseSeparator

      protected String clauseSeparator(String indent)
      Normally newline and indent to separate clauses of large SQL statement
    • wholeColumnSQL

      protected String wholeColumnSQL(SFieldScalar fld)
      Returns MY_COL VARCHAR(13) NOT NULL.
      See Also:
      • #SMANDATORY
    • addNull

      protected void addNull(StringBuffer sql, SFieldScalar fld)
    • columnTypeSQL

      protected String columnTypeSQL(SFieldScalar field, String defalt)
      Used to override the default. ONLY called if no fld.defaultSqlDataType has been specified, ie. only used to override the SFieldScalar.defaultSqlDataType.
    • postColumnSQL

      protected String postColumnSQL(SFieldMeta field)
      After NOT NULL but before the ",", ie column specific annotations.
    • primaryKeySQL

      protected String primaryKeySQL(SRecordMeta<?> meta)
      Return PRIMARY KEY(KCOL, KCOL) appended to end.
    • indexKeySQL

      protected String indexKeySQL(SRecordMeta meta)
      Needed for MySQL to create indexes on foreign keys
    • foreignKeysSQL

      protected String foreignKeysSQL(SRecordMeta meta)
      Returns FOREIGN KEY (FKCOL, FKCOL) REFERENCES FTABLE (KCOL, KCOL) appended to end.
    • mapForeignKeys

      protected String mapForeignKeys(SRecordMeta<?> meta, boolean foreignKey)
    • makeForeignKeyIndexSQL

      protected void makeForeignKeyIndexSQL(SRecordMeta meta, int fx, SFieldReference fldRef, StringBuffer sbFkey, StringBuffer sbRefed, StringBuffer fkey)
    • postTablePreParenSQL

      protected String postTablePreParenSQL(SRecordMeta meta)
      Any other text to be added before the final ")"
    • postTablePostParenSQL

      protected String postTablePostParenSQL(SRecordMeta meta)
      Any other text to be added after the final ")". No ";".
    • selectSQL

      protected String selectSQL(SFieldScalar[] select, SRecordMeta from, SFieldScalar[] where, String orderBy, boolean forUpdate, simpleorm.sessionjdbc.SQueryExecute sps)
      Returns the SQL statement for a SELECT in a structured way. Used by findOrInsert. select and where are arrays of SFieldMetas. Returns SQL statement as a string.

      This now quotes table and column names so that they become case independent.

      sps is links to the SPreparedStatement object. It can have arbitrary properties set to provide fine control over the query. Examples include limits.

    • selectSQL

      protected String selectSQL(SFieldScalar[] select, SRecordMeta<?> from, String join, String where, String orderBy, boolean forUpdate, simpleorm.sessionjdbc.SQueryExecute sps)
    • forUpdateSQL

      protected String forUpdateSQL(boolean forUpdate)
      Returns update clause, may not be valid in certain lock modes etc. Right at the end of the query.

      Oracle, Postgresql, and new in MS SQL 2005 support data versioning or snapshots. This means that repeatable read is achieved by caching the previous value read instead of using read locks. This approach makes it critical to add FOR UPDATE where appropriate or there is effectively no locking.

      Indeed, in Oracle, you are guaranteed that several SELECTS will return the same value, but a subsequent SELECT FOR UPDATE in the same transaction may return a different value.

    • limitSQL

      protected String limitSQL(long offset, long limit)
      Drivers that choose to implement a QUERY offset strategy should return the limit statment here
      Parameters:
      offset - number of rows to skip
      limit - number of rows to retrieve
      Returns:
      LIMIT + OFFSET string statment
    • fromSQL

      protected void fromSQL(SRecordMeta from, SRecordMeta[] joinTables, StringBuffer res)
      Returns the FROM Table, Table... clause
    • joinSQL

      protected String joinSQL(SRecordMeta[] joinTables)
    • postFromSQL

      protected String postFromSQL(boolean forUpdate)
      For MSSQL. Just after all the tables in the From clause.
    • updateSQL

      protected String updateSQL(ArrayList<SFieldScalar> updates, SRecordMeta from, ArrayList<SFieldScalar> where, SRecordInstance instance, Object[] keyMetaValues)
      Returns the SQL statement for an UPDATE in a structured way. Used by flush(). updates and where are SSArrayLists of SFieldMetas. Returns SQL statement as a string.
    • insertSQL

      protected String insertSQL(ArrayList<SFieldScalar> updates, SRecordMeta from)
      Returns the SQL statement for an INSERT in a structured way. Used by flush(). updates and where are SSArrayLists of SFieldMetas. Returns SQL statement as a string.
    • deleteSQL

      protected String deleteSQL(SRecordMeta from, ArrayList where, SRecordInstance instance, Object[] keyMetaValues)
      Returns the SQL statement for an DELETE in a structured way. Used by flush(). where are SSArrayLists of SFieldMetas. Returns SQL statement as a string.
    • whereSQL

      protected void whereSQL(StringBuffer ret, ArrayList<SFieldScalar> where, SRecordInstance instance, Object[] keyMetaValues)
      Produces the WHERE clause of UPDATE and DELETE statements. Needs to know the instance values so that it can use the IS NULL test (for optimisitic locking).
    • getOffsetStrategy

      protected SDriver.OffsetStrategy getOffsetStrategy()
      JDBC prefered, if jdbc driver has a sensible scrollable resultset implemntation QUERY if database would handle it better via some proprietary sql extension (eg. LIMIT) BULK Simpleorm will get the whole resultset and skip de first row. Worst case scenario :(

      Defaults to BULK

    • generateKeySelectMax

      protected long generateKeySelectMax(SRecordMeta rec, SFieldScalar keyFld)
      Generates a new key using SELECT MAX+1. This will (hopefully) be specialized for each database driver to be correct. Note that there is a global counter kept so it will actually work OK if all the updates are from one JVM. Amazing that there is still no standard way to do this in SQL.

      ## (There is scope to optimize this at some point so that one JDBC call can both generate the sequence number and insert a new record. But that means that the new record's key is not available until insert time which causes problems for foreign keys. Alternatively one can get batches of 10 (say) sequences at a time and then use an internal counter, but this will leave big holes in the sequence. Defer this to version 1.)

    • generateKeySequence

      protected long generateKeySequence(SRecordMeta<?> rec, SFieldScalar keyFld)
    • supportsKeySequences

      public boolean supportsKeySequences()
    • createSequenceDDL

      protected String createSequenceDDL(String name)
    • dropSequenceDDL

      protected String dropSequenceDDL(String name)
    • dropTableNoError

      public void dropTableNoError(String table)
      Utility routine for dropping tables called by SSession. Driver specific versions should only hide table non existent errors (and not warn about them).
    • getSession

      public SSessionJdbc getSession()
    • getLogger

      public SLog getLogger()