/*
 * blanco Framework
 * Copyright (C) 2004-2006 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.cg.BlancoCgObjectFactory;
import blanco.cg.valueobject.BlancoCgSourceFile;
import blanco.commons.util.BlancoNameAdjuster;
import blanco.db.common.expander.BlancoDbAbstractClass;
import blanco.db.common.util.BlancoDbUtil;
import blanco.db.common.valueobject.BlancoDbSetting;
import blanco.db.common.valueobject.BlancoDbSqlInfoStructure;
import blanco.db.expander.query.GetQueryMethodPhp;
import blanco.db.expander.query.GetStatementMethodPhp;
import blanco.db.expander.query.PrepareStatementMethod2Php;
import blanco.db.expander.query.PrepareStatementMethodPhp;
import blanco.db.expander.query.QueryConstructorPhp;
import blanco.db.expander.query.field.ConnectionFieldPhp;
import blanco.db.expander.query.field.StatementFieldPhp;
import blanco.db.expander.query.iterator.SetInputParameterMethodPhp;

/**
 * 個別のクラスを展開するためのクラス。
 */
public class QueryInvokerClassPhp extends BlancoDbAbstractClass {

    public QueryInvokerClassPhp(final BlancoDbSetting argDbSetting,
            final BlancoDbSqlInfoStructure argSqlInfo,
            final BlancoCgObjectFactory argCgFactory) {
        super(argDbSetting, argSqlInfo, argCgFactory);
    }

    public BlancoCgSourceFile expand() {
        final String className = BlancoNameAdjuster.toClassName(fSqlInfo
                .getName())
                + "Invoker";

        fCgSourceFile = fCgFactory.createSourceFile(fDbSetting.getBasePackage()
                + ".query", "This code is generated by blanco Framework.");
        fCgClass = fCgFactory.createClass(className, className + "クラス");
        fCgSourceFile.getClassList().add(fCgClass);

        fCgSourceFile.getImportList().add("pdo.PDO");

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

        fCgSourceFile.getImportList().add(
                BlancoDbUtil.getRuntimePackage(fDbSetting)
                        + ".exception.IntegrityConstraintException");

        new ConnectionFieldPhp(fDbSetting, fSqlInfo, fCgFactory, fCgSourceFile,
                fCgClass).expand();
        new StatementFieldPhp(fDbSetting, fSqlInfo, fCgFactory, fCgSourceFile,
                fCgClass).expand();

        new QueryConstructorPhp(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();

        new GetQueryMethodPhp(fDbSetting, fSqlInfo, fCgFactory, fCgSourceFile,
                fCgClass).expand();

        // Closeは先に存在しておく必要があります。
        new CloseMethodPhp(fDbSetting, fSqlInfo, fCgFactory, fCgSourceFile,
                fCgClass).expand();

        new PrepareStatementMethod2Php(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();
        new PrepareStatementMethodPhp(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();

        // 入力パラメータがある場合にのみbindします。
        if (fSqlInfo.getInParameterList().size() > 0) {
            new SetInputParameterMethodPhp(fDbSetting, fSqlInfo, fCgFactory,
                    fCgSourceFile, fCgClass).expand();
        }
        new ExecuteUpdateMethodPhp(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();
        if (fSqlInfo.getSingle()) {
            new ExecuteSingleUpdateMethodPhp(fDbSetting, fSqlInfo, fCgFactory,
                    fCgSourceFile, fCgClass).expand();
        }

        new GetStatementMethodPhp(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();

        return fCgSourceFile;
    }
}