/*
 * blanco Framework
 * Copyright (C) 2004-2005 IGA Tosiki
 * 
 * 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 blanco.db.definition.QueryInvokerDotNet;
import blanco.db.expander.query.FinalizeDotNet;
import blanco.db.expander.query.GetQueryMethodDotNet;
import blanco.db.expander.query.GetStatementMethodDotNet;
import blanco.db.expander.query.PrepareStatementMethod2DotNet;
import blanco.db.expander.query.PrepareStatementMethodDotNet;
import blanco.db.expander.query.QueryConstructor2DotNet;
import blanco.db.expander.query.QueryConstructorDotNet;
import blanco.db.expander.query.field.ConnectionFieldDotNet;
import blanco.db.expander.query.field.StatementFieldDotNet;
import blanco.db.expander.query.field.TransactionFieldDotNet;
import blanco.db.util.BlancoDbObjectStorageDotNet;
import blanco.ig.expander.ClassExpander;
import blanco.ig.expander.IgType;
import blanco.ig.expander.field.FieldExpander;
import blanco.ig.expander.implementor.IgStatement;

/**
 * @author Yasuo Nakanishi
 */
public class QueryInvokerClassDotNet extends ClassExpander {
    private BlancoDbObjectStorageDotNet storage = null;

    private QueryInvokerDotNet _invoker = null;

    public QueryInvokerClassDotNet(final BlancoDbObjectStorageDotNet storage,
            final IgType type, final QueryInvokerDotNet invoker) {
        super(type);
        _invoker = invoker;
        this.storage = storage;

        addImport(new IgType("System.String"));
        addImport(new IgType("System.Data.SqlDbType"));

        getJavaDoc().addLine(type.getName() + "クラス");
        getJavaDoc().addLine("QueryInvokerに属するクラスです。");
        getJavaDoc().addLine("実行型SQL文をラッピングして各種アクセサを提供します。");
        if (invoker.isSingle()) {
            getJavaDoc().addLine("シングル属性: 有効 (期待する処理件数は1件)");
        }
    }

    protected void expandClassStruct() {
        addField(new ConnectionFieldDotNet());
        // .NET Frameworkの場合にはトランザクションオブジェクトが必要です。
        addField(new TransactionFieldDotNet());
        addField(new StatementFieldDotNet());

        if (storage.getSetting().isLogging()) {
            addImport(new IgType("org.apache.commons.logging.LogFactory"));
            final FieldExpander field1 = new FieldExpander(new IgType(
                    "org.apache.commons.logging.Log"), "fLog") {
                protected boolean isStatic() {
                    return true;
                }
            };
            field1.getJavaDoc().addLine("ロギングのためのオブジェクト");
            field1.getJavaDoc().addLine("※static finalの状態で維持されます");
            field1.setDefaultStatement(new IgStatement("LogFactory.getLog("
                    + getName() + ".class)"));
            addField(field1);
        }

        addMethod(new QueryConstructorDotNet(getType()));
        addMethod(new QueryConstructor2DotNet(getType()));

        addMethod(new GetQueryMethodDotNet(_invoker.getQuery()));

        addMethod(new PrepareStatementMethodDotNet(storage));
        // t.iga
        addMethod(new PrepareStatementMethod2DotNet(storage, null));

        // 入力パラメータがある場合にのみbindします。
        if (_invoker.getInParameterIterator().hasNext()) {
            addMethod(new SetInvokerInputParameterMethodDotNet(storage,
                    _invoker));
        }
        addMethod(new ExecuteUpdateMethodDotNet(storage, _invoker));
        if (_invoker.isSingle()) {
            addMethod(new ExecuteSingleUpdateMethodDotNet(storage, _invoker));
        }

        addMethod(new GetStatementMethodDotNet(storage));

        addMethod(new CloseMethodDotNet(storage));

        addMethod(new FinalizeDotNet(storage, getName()));
    }
}