Package org.jooq.impl

Source Code of org.jooq.impl.TableRecordImpl

/**
* Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
*   list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
*   this list of conditions and the following disclaimer in the documentation
*   and/or other materials provided with the distribution.
*
* . Neither the name "jOOQ" nor the names of its contributors may be
*   used to endorse or promote products derived from this software without
*   specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jooq.impl;

import static org.jooq.impl.Factory.val;

import java.util.Collection;
import java.util.LinkedHashSet;

import org.jooq.ConditionProvider;
import org.jooq.DeleteQuery;
import org.jooq.Field;
import org.jooq.Identity;
import org.jooq.InsertQuery;
import org.jooq.SimpleSelectQuery;
import org.jooq.StoreQuery;
import org.jooq.Table;
import org.jooq.TableField;
import org.jooq.TableRecord;
import org.jooq.UpdateQuery;
import org.jooq.exception.InvalidResultException;

/**
* A record implementation for a record originating from a single table
* <p>
* This type is for JOOQ INTERNAL USE only. Do not reference directly
*
* @author Lukas Eder
*/
public class TableRecordImpl<R extends TableRecord<R>> extends TypeRecord<Table<R>> implements TableRecord<R> {

    /**
     * Generated UID
     */
    private static final long serialVersionUID = 3216746611562261641L;

    public TableRecordImpl(Table<R> table) {
        super(table);
    }

    /*
     * This method is overridden covariantly by UpdatableRecordImpl
     */
    @Override
    public Table<R> getTable() {
        return getType0();
    }

    @Override
    public final int storeUsing(TableField<R, ?>... keys) {
        boolean executeUpdate = false;

        for (TableField<R, ?> field : keys) {

            // If any primary key value is null or changed, execute an insert
            if (getValue(field) == null || getValue0(field).isChanged()) {
                executeUpdate = false;
                break;
            }

            // If primary key values are unchanged, updates are possible
            else {
                executeUpdate = true;
            }
        }

        int result = 0;

        if (executeUpdate) {
            result = storeUpdate(keys);
        }
        else {
            result = storeInsert();
        }

        for (Value<?> value : getValues()) {
            value.setChanged(false);
        }

        return result;
    }

    @SuppressWarnings("unchecked")
    private final int storeInsert() {
        InsertQuery<R> insert = create().insertQuery(getTable());

        for (Field<?> field : getFields()) {
            if (getValue0(field).isChanged()) {
                addValue(insert, (TableField<R, ?>) field);
            }
        }

        // [#814] Refresh identity and/or main unique key values
        // [#1002] Consider also identity columns of non-updatable records
        Collection<Field<?>> key = getReturning();
        insert.setReturning(key);
        int result = insert.execute();

        // If an insert was successful try fetching the generated IDENTITY value
        if (!key.isEmpty() && result > 0) {
            if (insert.getReturnedRecord() != null) {
                for (Field<?> field : key) {
                    setValue0(field, new Value<Object>(insert.getReturnedRecord().getValue(field)));
                }
            }
        }

        return result;
    }

    /**
     * Subclasses may override this method to provide an identity
     */
    Collection<Field<?>> getReturning() {
        Collection<Field<?>> result = new LinkedHashSet<Field<?>>();

        Identity<R, ?> identity = getTable().getIdentity();
        if (identity != null) {
            result.add(identity.getField());
        }

        return result;
    }

    @SuppressWarnings("unchecked")
    private final int storeUpdate(TableField<R, ?>... keys) {
        UpdateQuery<R> update = create().updateQuery(getTable());

        for (Field<?> field : getFields()) {
            if (getValue0(field).isChanged()) {
                addValue(update, (TableField<R, ?>) field);
            }
        }

        for (Field<?> field : keys) {
            addCondition(update, field);
        }

        return update.execute();
    }

    @Override
    public final int deleteUsing(TableField<R, ?>... keys) {
        try {
            DeleteQuery<R> delete = create().deleteQuery(getTable());

            for (Field<?> field : keys) {
                addCondition(delete, field);
            }

            return delete.execute();
        }

        // [#673] If store() is called after delete(), a new INSERT should
        // be executed and the record should be recreated
        finally {
            for (Field<?> field : getFields()) {
                getValue0(field).setChanged(true);
            }
        }
    }

    @Override
    public final void refreshUsing(TableField<R, ?>... keys) {
        SimpleSelectQuery<R> select = create().selectQuery(getTable());

        for (Field<?> field : keys) {
            addCondition(select, field);
        }

        if (select.execute() == 1) {
            AbstractRecord record = (AbstractRecord) select.getResult().get(0);

            for (Field<?> field : getFields()) {
                setValue0(field, record.getValue0(field));
            }
        }
        else {
            throw new InvalidResultException("Exactly one row expected for refresh. Record does not exist in database.");
        }
    }

    /**
     * Extracted method to ensure generic type safety.
     */
    @SuppressWarnings("unchecked")
    private final <T> void setValue0(Field<T> field, Value<?> value) {
        setValue(field, (Value<T>) value);
    }

    /**
     * Extracted method to ensure generic type safety.
     */
    private final <T> void addCondition(ConditionProvider provider, Field<T> field) {
        provider.addConditions(field.equal(getValue(field)));
    }

    /**
     * Extracted method to ensure generic type safety.
     */
    private final <T> void addValue(StoreQuery<?> store, Field<T> field) {
        store.addValue(field, val(getValue(field), field));
    }
}
TOP

Related Classes of org.jooq.impl.TableRecordImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.