/* * Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com) and * JR Boyens <gnu-jrb[remove] at gmx dot net> * Licensed under the Apache License, Version 2.0 (the "License") * $Id: com_mysql_jdbc_Driver.java 3918 2008-04-14 17:35:35Z gbevin $ */ package com.uwyn.rife.database.querymanagers.generic.databasedrivers; import com.uwyn.rife.database.*; import com.uwyn.rife.database.exceptions.DatabaseException; import com.uwyn.rife.database.exceptions.ExecutionErrorException; import com.uwyn.rife.database.queries.CreateTable; import com.uwyn.rife.database.queries.Insert; import com.uwyn.rife.database.queries.Select; import com.uwyn.rife.database.queries.Update; import com.uwyn.rife.database.querymanagers.generic.Callbacks; import com.uwyn.rife.database.querymanagers.generic.GenericQueryManager; import java.sql.Types; public class com_mysql_jdbc_Driver<BeanType> extends generic<BeanType> implements GenericQueryManager<BeanType> { private CreateTable mCreateTableMysql = null; private Insert mSaveMysql = null; private Select mLastIdMysql = null; public com_mysql_jdbc_Driver(Datasource datasource, String tableName, String primaryKey, Class<BeanType> beanClass, boolean hasIdentifier) throws DatabaseException { super(datasource, tableName, primaryKey, beanClass, hasIdentifier); } protected CreateTable getInternalCreateTableQuery() { if (null == mCreateTableMysql) { CreateTable query = new CreateTable(getDatasource()) .table(mTableName) .columns(mBaseClass); if (!isIdentifierSparse()) { query .customAttribute(mPrimaryKey, "AUTO_INCREMENT"); } if (!mHasIdentifier) { query .primaryKey(mPrimaryKey); } addCreateTableManyToOneColumns(query); mCreateTableMysql = query; } return mCreateTableMysql; } protected Insert getInternalSaveQuery() { if (null == mSaveMysql) { Insert query = new Insert(getDatasource()) .into(mTableName); if (!isIdentifierSparse()) { query .fieldsParametersExcluded(mBaseClass, new String[]{mPrimaryKey}); } else { query .fieldsParameters(mBaseClass); } addSaveManyToOneFields(query); mSaveMysql = query; } return mSaveMysql; } protected Select getInternalLastIdQuery() { if (null == mLastIdMysql) { Select query = new Select(getDatasource()) .from(mTableName) .field("LAST_INSERT_ID()"); mLastIdMysql = query; } return mLastIdMysql; } public void install() throws DatabaseException { executeUpdate(getInternalCreateTableQuery()); installManyToMany(); fireInstalled(); } public void install(CreateTable query) throws DatabaseException { executeUpdate(query); installManyToMany(); fireInstalled(); } public void remove() throws DatabaseException { removeManyToMany(); executeUpdate(getInternalDropTableQuery()); fireRemoved(); } public int save(BeanType bean) throws DatabaseException { return _save(getInternalLastIdQuery(), getInternalSaveQuery(), getInternalSaveUpdateQuery(), bean); } public int insert(BeanType bean) throws DatabaseException { return _insert(getInternalLastIdQuery(), getInternalSaveQuery(), bean); } protected int _insert(final Select lastId, final Insert save, final BeanType bean) { // handle before callback Callbacks callbacks = getCallbacks(bean); if (callbacks != null && !callbacks.beforeInsert(bean)) { return -1; } // perform insert int result = _insertWithoutCallbacks(lastId, save, bean); // handle after callback if (callbacks != null) { callbacks.afterInsert(bean, result != -1); } return result; } protected int _insertWithoutCallbacks(final Select lastId, final Insert save, final BeanType bean) throws DatabaseException { int result = -1; result = ((Integer)inTransaction(new DbTransactionUser() { public Integer useTransaction() { // reserving the connection inside the transaction user // since there are versions of MySQL that don't support tranactions // and in that case the thread connection isn't reserved to obtain // the generated primary key return reserveConnection(new DbConnectionUser() { public Integer useConnection(DbConnection connection) { storeManyToOne(bean); executeUpdate(save, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement.setBean(bean); if (!isIdentifierSparse() && save.getFields().containsKey(getIdentifierName())) { statement.setNull(getIdentifierName(), Types.INTEGER); } setManyToOneJoinParameters(statement, bean); } }); Integer primary_key_id; if (isIdentifierSparse()) { primary_key_id = new Integer(getIdentifierValue(bean)); } else { primary_key_id = new Integer(executeGetFirstInt(lastId)); } storeManyToOneAssociations(bean, primary_key_id); storeManyToMany(bean, primary_key_id); return primary_key_id; } }); } })).intValue(); if (result != -1) { try { mSetPrimaryKeyMethod.invoke(bean, new Object[] {new Integer(result)}); } catch (Throwable e) { throw new DatabaseException(e); } } // handle listeners if (result != -1) { fireInserted(bean); } return result; } protected int _save(final Select lastId, final Insert save, final Update saveUpdate, final BeanType bean) throws DatabaseException { int value = -1; // handle before callback final Callbacks callbacks = getCallbacks(bean); if (callbacks != null && !callbacks.beforeSave(bean)) { return -1; } boolean update = false; try { int id = getIdentifierValue(bean); if (id >= 0) { value = id; update = true; } } catch (Throwable e) { throw new DatabaseException(e); } if (isIdentifierSparse()) { // handle before callback if (callbacks != null && !callbacks.beforeInsert(bean)) { return -1; } // try to perform the insert try { value = _insertWithoutCallbacks(lastId, save, bean); } catch (ExecutionErrorException e) { value = -1; } // handle after callback if (callbacks != null && !callbacks.afterInsert(bean, value != -1)) { return value; } if (-1 == value) { // handle before callback if (callbacks != null && !callbacks.beforeUpdate(bean)) { return -1; } value = _updateWithoutCallbacks(saveUpdate, bean); // handle after callback if (callbacks != null && !callbacks.afterUpdate(bean, value != -1)) { return value; } } } else { if (update) { // handle before callback if (callbacks != null && !callbacks.beforeUpdate(bean)) { return -1; } value = _updateWithoutCallbacks(saveUpdate, bean); // handle after callback if (callbacks != null && !callbacks.afterUpdate(bean, value != -1)) { return value; } } if (-1 == value) { // handle before callback if (callbacks != null && !callbacks.beforeInsert(bean)) { return -1; } value = _insertWithoutCallbacks(lastId, save, bean); // handle after callback if (callbacks != null && !callbacks.afterInsert(bean, value != -1)) { return value; } } } // handle after callback if (callbacks != null) { callbacks.afterSave(bean, value != -1); } return value; } }