/*
 * blancoDbTutorial: blancoDbチュートリアル・サンプル<br>
 * 大量データ処理試験
 * 
 * Copyright (C) 2005 tosiki.iga@nifty.ne.jp
 */

package sql2k;

import igapyon.query.SimpleTestBlancoDbTable1ColumnColBinary100NotNullIterator;
import igapyon.query.SimpleTestBlancoDbTable1DeleteInvoker;
import igapyon.query.SimpleTestBlancoDbTable1InsertInvoker;
import igapyon.query.SimpleTestBlancoDbTable1SelectIterator;
import igapyon.query.TestBlancoDbTable1SelectAllIterator;
import igapyon.row.SimpleTestBlancoDbTable1ColumnColBinary100NotNullRow;
import igapyon.row.SimpleTestBlancoDbTable1SelectRow;
import igapyon.row.TestBlancoDbTable1SelectAllRow;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import junit.framework.TestCase;

/**
 * 注意: このクラスをコンパイルするためには、それまでの手順で自動生成したblancoDbソースコードが必要になります。
 */
public class BlancoDbTest11Sql2k extends TestCase {
    /**
     * 大量データとして挿入する行数
     */
    //public static final int MAX_ROW_COUNT = 100000;
    public static final int MAX_ROW_COUNT = 10000;

    public static final boolean IS_PROCESS_DELETEINSERT = true;

    /**
     * JDBCドライバ名を指定します。
     */
    public static final String JDBC_DRIVER = "com.microsoft.jdbc.sqlserver.SQLServerDriver";

    /**
     * JDBC接続時の文字列を指定します。 <br>
     * ポイント: SelectMethod=cursor の指定は必須です。
     */
    public static final String JDBC_URL = "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=Northwind;SelectMethod=cursor";

    /**
     * JDBC接続時のユーザ名を指定します。
     */
    public static final String JDBC_USERNAME = "sa";

    /**
     * JDBC接続時のパスワードを指定します。
     */
    public static final String JDBC_PASSWORD = "password";

    public void testProcess01() throws Exception {
        Class.forName(JDBC_DRIVER);
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(JDBC_URL, JDBC_USERNAME,
                    JDBC_PASSWORD);
            conn.setAutoCommit(false);

            if (IS_PROCESS_DELETEINSERT) {
                // まず空の状態にします。
                processDeleteAll(conn);
                processInsert(conn);
            }

            processScrollCursor(conn);

            conn.commit();
            System.out.println("全ての処理終了しました.");
        } finally {
            conn.rollback();
            conn.close();
            conn = null;
        }
    }

    public void processDeleteAll(Connection conn) throws SQLException {
        System.out.println("不要な行を一括削除します。");
        TestBlancoDbTable1SelectAllIterator iterator = new TestBlancoDbTable1SelectAllIterator(
                conn);
        SimpleTestBlancoDbTable1DeleteInvoker invoker = new SimpleTestBlancoDbTable1DeleteInvoker(
                conn);
        try {
            for (int deleteCount = 0; iterator.next(); deleteCount++) {
                TestBlancoDbTable1SelectAllRow row = iterator.getRow();
                invoker.prepareStatement();
                invoker.setInputParameter(row.getColIntNotNull());
                //System.out.println("行[" + row.getColIntNotNull() + "]を削除");
                invoker.executeSingleUpdate();

                if (deleteCount % 1000 == 999) {
                    conn.commit();
                    System.out.println("" + (deleteCount + 1)
                            + "件 削除処理されました。コミットします。");
                }
            }
        } finally {
            invoker.close();
            iterator.close();
        }
    }

    public void processInsert(Connection conn) throws SQLException, IOException {
        System.out.println("行の挿入を試みます");
        SimpleTestBlancoDbTable1InsertInvoker invoker = new SimpleTestBlancoDbTable1InsertInvoker(
                conn);
        SimpleTestBlancoDbTable1SelectIterator iterator = new SimpleTestBlancoDbTable1SelectIterator(
                conn);
        SimpleTestBlancoDbTable1ColumnColBinary100NotNullIterator iteratorCol = new SimpleTestBlancoDbTable1ColumnColBinary100NotNullIterator(
                conn);
        try {
            for (int index = 0; index < MAX_ROW_COUNT; index++) {
                invoker.setInputParameter((index + 1), new Integer(index + 1),
                        (short) 3, new Short((short) 4), (long) 5, new Long(6),
                        (float) 7.1, new Float(8.2), 9.3, new Double(10.4),
                        new BigDecimal("11"), new BigDecimal("12"),
                        new BigDecimal("13"), new BigDecimal("14"),
                        new BigDecimal("15.2"), new BigDecimal("16.4"), false,
                        new Boolean(true), new ByteArrayInputStream("ABC123"
                                .getBytes()), 6, new ByteArrayInputStream(
                                "DEF456".getBytes()), 6,
                        new ByteArrayInputStream("GHI789".getBytes()), 6,
                        new ByteArrayInputStream("JKL012".getBytes()), 6, "1",
                        "2", "34", "56", "7890", "1234", "5678", "9012",
                        "3456", "7890", "1234", "5678", "12345678", "12345678",
                        "colNVarchar255Null", new StringReader("ABC"), 3,
                        new Date(), new Date());
                invoker.executeSingleUpdate();

                if (index % 1000 == 999) {
                    conn.commit();
                    System.out.println("" + (index + 1)
                            + "件 挿入処理されました。コミットします。");
                }
            }

            // 挿入の成功をチェックします。
            iterator.setInputParameter(5);
            iterator.next();
            SimpleTestBlancoDbTable1SelectRow row = iterator.getRow();
            assertTrue(row.getColDecimal153Null().compareTo(
                    new BigDecimal("16.4")) == 0);

            iteratorCol.setInputParameter(5);
            assertTrue(iteratorCol.next());
            SimpleTestBlancoDbTable1ColumnColBinary100NotNullRow rowBinary = iteratorCol
                    .getRow();
            InputStream inStream = rowBinary.getColBinary100NotNull();
            for (;;) {
                int iRead = inStream.read();
                if (iRead < 0)
                    break;
            }
        } finally {
            iteratorCol.close();
            iterator.close();
            invoker.close();
        }
    }

    public void processScrollCursor(Connection conn) throws SQLException,
            IOException {
        System.out.println("行のスクロールを試みます");
        TestBlancoDbTable1SelectAllIterator iterator = new TestBlancoDbTable1SelectAllIterator(
                conn);
        try {
            iterator.prepareStatement(iterator.getQuery(),
                    ResultSet.TYPE_SCROLL_INSENSITIVE,
                    ResultSet.CONCUR_READ_ONLY);

            System.out.println("最初の行へ位置づけ. (結果セットの作成を伴うので、意外にここで時間がかかります.)");
            assertTrue(iterator.next());
            System.out.println("9000行へジャンプ");
            assertTrue(iterator.absolute(9000));
            System.out.println("5000行から10行を取得");
            List list = iterator.getList(5000, 10);
            for (int count = 0; count < list.size(); count++) {
                TestBlancoDbTable1SelectAllRow row = (TestBlancoDbTable1SelectAllRow) list
                        .get(count);
                assertEquals(row.getColIntNotNull(), 5000 + count);
            }

            System.out.println("8000行へジャンプ");
            assertTrue(iterator.absolute(8000));
            list = iterator.getList(8000, 10);
            for (int count = 0; count < list.size(); count++) {
                TestBlancoDbTable1SelectAllRow row = (TestBlancoDbTable1SelectAllRow) list
                        .get(count);
                assertEquals(row.getColIntNotNull(), 8000 + count);
            }

            System.out.println("終端である" + MAX_ROW_COUNT + "行へジャンプ");
            assertTrue(iterator.absolute(MAX_ROW_COUNT));
            TestBlancoDbTable1SelectAllRow row = iterator.getRow();
            assertEquals(row.getColIntNotNull(), MAX_ROW_COUNT);
            assertFalse(iterator.absolute(MAX_ROW_COUNT + 1));

            System.out.println("3000行へジャンプ");
            assertTrue(iterator.absolute(3000));
            row = iterator.getRow();
            assertEquals(row.getColIntNotNull(), 3000);

            System.out.println("2997行へジャンプ");
            assertTrue(iterator.relative(-3));
            row = iterator.getRow();
            assertEquals(row.getColIntNotNull(), 2997);

        } finally {
            iterator.close();
        }

    }
}