All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.cayenne.dba.openbase.OpenBasePkGenerator Maven / Gradle / Ivy

There is a newer version: 2.0.4
Show newest version
/*****************************************************************
 *   Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 ****************************************************************/

package org.apache.cayenne.dba.openbase;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.access.DataNode;
import org.apache.cayenne.access.QueryLogger;
import org.apache.cayenne.dba.JdbcPkGenerator;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DerivedDbEntity;

/**
 * @author Mike Kienenberger
 * @author Andrei Adamchik
 * @since 1.1
 */
public class OpenBasePkGenerator extends JdbcPkGenerator {

    /**
     * @deprecated Since 1.2 corresponding interface method is unused and deprecated.
     */
    public String generatePkForDbEntityString(DbEntity ent) {
        return newIDString(ent);
    }

    /**
     * Returns a non-repeating primary key for a given entity. Since OpenBase-specific
     * mechanism is used, key caching is disabled. Instead a database operation is
     * performed on every call.
     */
    public Object generatePkForDbEntity(DataNode node, DbEntity entity) throws Exception {
        // check for binary pk
        Object binPK = binaryPK(entity);
        if (binPK != null) {
            return binPK;
        }
        return new Integer(pkFromDatabase(node, entity));
    }

    /**
     * Generates new (unique and non-repeating) primary key for specified DbEntity.
     * Executed SQL looks like this:
     * 
     * 
     * NEWID FOR Table Column
     * 
* * COLUMN must be marked as UNIQUE in order for this to work properly. */ protected int pkFromDatabase(DataNode node, DbEntity entity) throws Exception { String sql = newIDString(entity); QueryLogger.logQuery(sql, Collections.EMPTY_LIST); Connection con = node.getDataSource().getConnection(); try { Statement st = con.createStatement(); try { ResultSet rs = st.executeQuery(sql); try { // Object pk = null; if (!rs.next()) { throw new CayenneRuntimeException( "Error generating pk for DbEntity " + entity.getName()); } return rs.getInt(1); } finally { rs.close(); } } finally { st.close(); } } finally { con.close(); } } /** * Returns SQL string that can generate new (unique and non-repeating) primary key for * specified DbEntity. No actual database operations are performed. * * @since 1.2 */ protected String newIDString(DbEntity ent) { if ((null == ent.getPrimaryKey()) || (1 != ent.getPrimaryKey().size())) { throw new CayenneRuntimeException("Error generating pk for DbEntity " + ent.getName() + ": pk must be single attribute"); } DbAttribute primaryKeyAttribute = (DbAttribute) ent.getPrimaryKey().get(0); StringBuffer buf = new StringBuffer("NEWID FOR "); buf.append(ent.getName()).append(' ').append(primaryKeyAttribute.getName()); return buf.toString(); } public void createAutoPk(DataNode node, List dbEntities) throws Exception { // looks like generating a PK on top of an existing one does not // result in errors... // create needed sequences Iterator it = dbEntities.iterator(); while (it.hasNext()) { DbEntity entity = (DbEntity) it.next(); // the caller must take care of giving us the right entities // but lets check anyway if (!canCreatePK(entity)) { continue; } runUpdate(node, createPKString(entity)); runUpdate(node, createUniquePKIndexString(entity)); } } /** * */ public List createAutoPkStatements(List dbEntities) { List list = new ArrayList(2 * dbEntities.size()); Iterator it = dbEntities.iterator(); while (it.hasNext()) { DbEntity entity = (DbEntity) it.next(); // the caller must take care of giving us the right entities // but lets check anyway if (!canCreatePK(entity)) { continue; } list.add(createPKString(entity)); list.add(createUniquePKIndexString(entity)); } return list; } protected boolean canCreatePK(DbEntity entity) { if (entity instanceof DerivedDbEntity) { return false; } List pk = entity.getPrimaryKey(); if (pk == null || pk.size() == 0) { return false; } return true; } /** * */ public void dropAutoPk(DataNode node, List dbEntities) throws Exception { // there is no simple way to do that... probably requires // editing metadata tables... // Good thing is that it doesn't matter, since PK support // is attached to the table itself, so if a table is dropped, // it will be dropped as well } /** * Returns an empty list, since OpenBase doesn't support this operation. */ public List dropAutoPkStatements(List dbEntities) { return Collections.EMPTY_LIST; } /** * Returns a String to create PK support for an entity. */ protected String createPKString(DbEntity entity) { List pk = entity.getPrimaryKey(); if (pk == null || pk.size() == 0) { throw new CayenneRuntimeException("Entity '" + entity.getName() + "' has no PK defined."); } StringBuffer buffer = new StringBuffer(); buffer.append("CREATE PRIMARY KEY ").append(entity.getName()).append(" ("); Iterator it = pk.iterator(); // at this point we know that there is at least on PK column DbAttribute firstColumn = (DbAttribute) it.next(); buffer.append(firstColumn.getName()); while (it.hasNext()) { DbAttribute column = (DbAttribute) it.next(); buffer.append(", ").append(column.getName()); } buffer.append(")"); return buffer.toString(); } /** * Returns a String to create a unique index on table primary key columns per OpenBase * recommendations. */ protected String createUniquePKIndexString(DbEntity entity) { List pk = entity.getPrimaryKey(); if (pk == null || pk.size() == 0) { throw new CayenneRuntimeException("Entity '" + entity.getName() + "' has no PK defined."); } StringBuffer buffer = new StringBuffer(); // compound PK doesn't work well with UNIQUE index... // create a regular one in this case buffer.append(pk.size() == 1 ? "CREATE UNIQUE INDEX " : "CREATE INDEX ").append( entity.getName()).append(" ("); Iterator it = pk.iterator(); // at this point we know that there is at least on PK column DbAttribute firstColumn = (DbAttribute) it.next(); buffer.append(firstColumn.getName()); while (it.hasNext()) { DbAttribute column = (DbAttribute) it.next(); buffer.append(", ").append(column.getName()); } buffer.append(")"); return buffer.toString(); } public void reset() { // noop } /** * Returns zero, since PK caching is not feasible with OpenBase PK generation * mechanism. */ public int getPkCacheSize() { return 0; } public void setPkCacheSize(int pkCacheSize) { // noop, no PK caching } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy