/*
 * blancoDb Enterprise Edition
 * Copyright (C) 2005 Tosiki Iga
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.db.expander.query.iterator;

import java.sql.SQLException;

import blanco.db.conf.BlancoDbSetting;
import blanco.db.definition.QueryIterator;
import blanco.db.exception.IntegrityConstraintException;
import blanco.db.expander.implementor.BlancoDbImplementor;
import blanco.db.generator.TypeFactory;
import blanco.db.properties.GenerationProperties;
import blanco.db.util.BlancoDbObjectStorage;
import blanco.ig.expander.Type;
import blanco.ig.expander.Value;
import blanco.ig.expander.implementor.Call;
import blanco.ig.expander.implementor.Receiver;
import blanco.ig.expander.method.MethodExpander;

/**
 * @author Tosiki Iga
 */
public class UpdateRowMethod extends MethodExpander {
    private Value _resultSet = null;

    private Value _statement = null;

    private BlancoDbSetting _setting = null;

    private QueryIterator _iterator = null;

    private GenerationProperties _properties = null;

    public UpdateRowMethod(QueryIterator iterator) {
        super("updateRow");

        _iterator = iterator;

        BlancoDbObjectStorage storage = BlancoDbObjectStorage.getInstance();
        _setting = storage.getSetting();
        _properties = storage.getGenerationProperties();
    }

    public void setupSignature() {
        Type integrityConstraintException = new Type(_setting
                .getRootNameSpace()
                + ".exception.IntegrityConstraintException");
        addException(integrityConstraintException);
        addUsingType(integrityConstraintException);

        addException(SQLException.class);

        if (_properties.isGenerateJavaDoc()) {
            getJavaDoc().addLine("現在の行の新しい内容でデータベースを更新します<br>");
            getJavaDoc()
                    .addLine(
                            "データベース制約違反が発生した場合には IntegrityConstraintException 例外が発生します。");
        }
    }

    /**
     * コメント <br>
     * 
     * PostgreSQLにおいて FOR UPDATEカーソルでupdateRowを呼び出した際に 制約違反の際には、SQLState[23505],
     * ErrorCode [0] が発生します。 <br>
     * java.sql.SQLException: ERROR: duplicate key violates unique constraint
     * "ract007_ketsugo_model_pkey" at
     * org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1471)
     */
    public void implement() {
        BlancoDbImplementor i = new BlancoDbImplementor(getData());
        TypeFactory typeFactory = BlancoDbObjectStorage.getInstance()
                .getTypeFactory();

        _resultSet = getField("ResultSet");

        Receiver r = null;
        Call c = null;
        r = new Receiver(_resultSet);

        i.openTry();
        c = r.call("updateRow");

        i.addStatement(r);

        Value e = new Value(SQLException.class, "e");
        i.addCatch(e);
        Type exceptionType = typeFactory
                .createRuntime(IntegrityConstraintException.class);
        i.throwIntegrityConstraintException(e, exceptionType);

        i.closeTry();

        if (_setting.isEnabledLogging()) {
            i.outLog(_statement);
        }
    }
}