/*
 * Copyright 2004 Piotr Maj
 *
 * Licensed 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 pl.kernelpanic.dbmonster.misc;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import pl.kernelpanic.dbmonster.DBMonster;
import pl.kernelpanic.dbmonster.DBMonsterContext;
import pl.kernelpanic.dbmonster.connection.ConnectionProvider;
import pl.kernelpanic.dbmonster.connection.Transaction;
import pl.kernelpanic.dbmonster.generator.Initializable;
import pl.kernelpanic.dbmonster.generator.KeyGenerator;
import pl.kernelpanic.dbmonster.schema.Column;
import pl.kernelpanic.dbmonster.schema.Key;
import pl.kernelpanic.dbmonster.schema.Table;


/**
 * @author Piotr Maj &lt;ant@kernelpanic.pl&gt;
 *
 * $Revision: 1.1 $ $Date: 2004/06/11 10:37:59 $
 */
public class CompositeKeyGenerator implements KeyGenerator, Initializable {

    private Key key;
    private DBMonsterContext context;
    private Column firstColumn;
    private Column secondColumn;
    private List columns;
    private ConnectionProvider connProvider;

    public void setKey(Key key) {
        this.key = key;
    }

    public List getColumns() {
        if (columns == null) {
            columns = new ArrayList();
            columns.add(firstColumn);
            columns.add(secondColumn);
        }
        return columns;
    }

    public List generate() throws Exception {
        
        // first: be sure that table invoices is
        //        already generated
        Table invTable = key.getTable().getSchema().findTable("invoices");
        invTable.generate();

        // Transaction is user-friendly wraper for pure JDBC obscure methods.
        Transaction tx = null;
        try {
            tx = new Transaction(connProvider);
            tx.begin();

            //second: get the random invoice id from the invoices
            //        table.
            ResultSet rs = tx.executeQuery("SELECT invno FROM invoices ORDER BY random() LIMIT 1");
            rs.next();
            int invno = rs.getInt("invno"); // this is our random invoice id

            // third: generate itemno using MAX + 1 strategy
            rs = tx.executeQuery("SELECT max(itemno) + 1 FROM invoice_items where invno = " + invno);
            int itemno = 1;
            if (rs.next()) {
                itemno = rs.getInt(1);
            }

            // we have all what we need so just set the column values
            firstColumn.setValue(new Integer(invno));
            secondColumn.setValue(new Integer(itemno));

            tx.commit();
        } catch (Exception e) {
            throw e;
        } finally {
            tx.close();
        }

        return getColumns();
    }

    public void initialize(DBMonsterContext ctx) throws Exception {
        context = ctx;
        connProvider = (ConnectionProvider) context.getProperty(DBMonster.CONNECTION_PROVIDER_KEY);
    }

    public void setFirstColumn(String name) {
        firstColumn = new Column();
        firstColumn.setName(name);
        firstColumn.reset();
    }
    public String getFirstColumn() {
        if (firstColumn != null) {
            return firstColumn.getName();
        }
        return null;
    }

    public void setSecondColumn(String name) {
        secondColumn = new Column();
        secondColumn.setName(name);
        secondColumn.reset();
    }
    public String getSecondColumn() {
        if (secondColumn != null) {
            return secondColumn.getName();
        }
        return null;
    }

}
