/*
 * blancoDb Enterprise Edition
 * Copyright (C) 2004-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.invoker;

import java.sql.SQLException;

import blanco.db.conf.BlancoDbSetting;
import blanco.db.definition.QueryInvoker;
import blanco.db.exception.NoRowModifiedException;
import blanco.db.exception.TooManyRowsModifiedException;
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.Receiver;
import blanco.ig.expander.implementor.Statement;
import blanco.ig.expander.method.MethodExpander;

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

    private TypeFactory _typeFactory = null;

    private BlancoDbSetting _setting = null;

    private QueryInvoker _invoker = null;

    private GenerationProperties _properties = null;

    public ExecuteSingleUpdateMethod(QueryInvoker invoker) {
        super("executeSingleUpdate");

        _invoker = invoker;

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

    }

    public void setupSignature() {
        Type resultType = new Type(void.class);

        setReturnType(resultType);

        Type noRowModifiedException = new Type(_setting.getRootNameSpace()
                + ".exception.NoRowModifiedException");
        addException(noRowModifiedException);
        addUsingType(noRowModifiedException);
        Type tooManyRowsModifiedException = new Type(_setting
                .getRootNameSpace()
                + ".exception.TooManyRowsModifiedException");
        addException(tooManyRowsModifiedException);
        addUsingType(tooManyRowsModifiedException);

        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>");

            getJavaDoc().addLine("");
            getJavaDoc().addLine("single属性が有効<br>");
            getJavaDoc().addLine("実行結果が1件以外の場合には、NotSingleRowExceptionクラスを");
            getJavaDoc().addLine("派生したクラスの例外が発生します。");
        }
    }

    public void implement() {
        BlancoDbImplementor i = new BlancoDbImplementor(getData());

        Value result = new Value(int.class, "result");
        _statement = getField("Statement");

        i.declare(result, new Statement(int.class, "0"));

        Receiver r = null;

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

        i.addStatement("result = executeUpdate()");

        i.emptyLine();

        Type noModified = _typeFactory
                .createRuntime(NoRowModifiedException.class);
        Type tooMeny = _typeFactory
                .createRuntime(TooManyRowsModifiedException.class);
        i.checkSingleRowUpdated(result, noModified, tooMeny);
    }

}