Package com.foundationdb.sql.pg

Source Code of com.foundationdb.sql.pg.PostgresServerPreparedStatementIT

/**
* Copyright (C) 2009-2013 FoundationDB, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.foundationdb.sql.pg;

import com.foundationdb.ais.model.TableName;
import com.foundationdb.server.error.ErrorCode;
import org.junit.Before;
import org.junit.Test;
import com.foundationdb.sql.jdbc.PGStatement;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.List;

public class PostgresServerPreparedStatementIT extends PostgresServerITBase {
    private static final String SCHEMA = "test";
    private static final String TABLE = "t";
    private static final TableName TABLE_NAME = new TableName(SCHEMA, TABLE);
    private static final int ROW_COUNT = 5;

    @Before
    public void createAndInsert() {
        int tid = createTable(TABLE_NAME, "id int not null primary key, x int");
        for(long i = 1; i <= ROW_COUNT; ++i) {
            writeRow(tid, i, i*10);
        }
    }

    PreparedStatement newDropTable() throws Exception {
        return getConnection().prepareStatement("DROP TABLE "+TABLE_NAME);
    }

    PreparedStatement newCreateTable() throws Exception {
        return getConnection().prepareStatement("CREATE TABLE "+TABLE_NAME+"2(id int)");
    }

    PreparedStatement newCreateIndex() throws Exception {
        return getConnection().prepareStatement("CREATE INDEX x ON "+TABLE_NAME+"(x)");
    }

    PreparedStatement newDropIndex() throws Exception {
        return getConnection().prepareStatement("DROP INDEX x");
    }

    PreparedStatement newScan() throws Exception {
        PreparedStatement p = getConnection().prepareStatement("SELECT * FROM "+TABLE_NAME);
        // driver has lower bound of usage before fully using a named statement, this drops that
        if(p instanceof PGStatement) {
            PGStatement pgp = (PGStatement) p;
            pgp.setPrepareThreshold(1);
        }
        return p;
    }

    PreparedStatement newInsert() throws Exception {
        return getConnection().prepareStatement("INSERT INTO "+TABLE_NAME+" VALUES (100,1000)");
    }

    private static int countRows(ResultSet rs) throws SQLException {
        int count = 0;
        while(rs.next()) {
            ++count;
        }
        rs.close();
        return count;
    }

    private static List<List<Object>> listRows(ResultSet rs, int ncols) throws SQLException {
        List<List<Object>> rows = new ArrayList<>();
        while (rs.next()) {
            List<Object> row = new ArrayList<>(ncols);
            for (int i = 0; i < ncols; i++) {
                row.add(rs.getObject(i+1));
            }
            rows.add(row);
        }
        rs.close();
        return rows;
    }

    private static void expectStale(PreparedStatement p) {
        try {
            p.executeQuery();
            fail("Expected exception");
        } catch(SQLException e) {
            assertEquals("Error code from exception", ErrorCode.STALE_STATEMENT.getFormattedValue(), e.getSQLState());
        }
    }

    @Test
    public void fullScan() throws Exception {
        PreparedStatement p = newScan();
        ResultSet rs = p.executeQuery();
        assertEquals("Scanned row count", ROW_COUNT, countRows(rs));
        p.close();
    }

    @Test
    public void singleRowInsert() throws Exception {
        PreparedStatement p = newInsert();
        int count = p.executeUpdate();
        assertEquals("Inserted count", 1, count);
        p.close();
    }

    @Test
    public void createIndex() throws Exception {
        PreparedStatement p = newCreateIndex();
        int count = p.executeUpdate();
        assertEquals("Count from create index", 0, count);
        assertNotNull("Found new index", ais().getTable(TABLE_NAME).getIndex("x"));
    }

    @Test
    public void dropIndex() throws Exception {
        createIndex(SCHEMA, TABLE, "x", "x");
        PreparedStatement p = newDropIndex();
        int count = p.executeUpdate();
        assertEquals("Count from drop index", 0, count);
        assertNull("Index is gone", ais().getTable(TABLE_NAME).getIndex("x"));
    }

    @Test
    public void dropTableInvalidates() throws Exception {
        PreparedStatement pScan = newScan();
        PreparedStatement pDrop = newDropTable();
        assertEquals("Row count from scan1", ROW_COUNT, countRows(pScan.executeQuery()));
        int count = pDrop.executeUpdate();
        assertEquals("Count from drop table", 0, count);
        expectStale(pScan);
        pScan.close();
        pDrop.close();
    }

    //
    // Two below aren't exactly desirable, but confirming expected behavior
    //

    @Test
    public void createTableInvalidates() throws Exception {
        PreparedStatement pScan = newScan();
        PreparedStatement pCreate = newCreateTable();
        assertEquals("Row count from scan1", ROW_COUNT, countRows(pScan.executeQuery()));
        int count = pCreate.executeUpdate();
        assertEquals("Count from create table", 0, count);
        expectStale(pScan);
        pScan.close();
        pCreate.close();
    }

    @Test
    public void createIndexInvalidates() throws Exception {
        PreparedStatement pScan = newScan();
        PreparedStatement pCreate = newCreateIndex();
        assertEquals("Row count from scan1", ROW_COUNT, countRows(pScan.executeQuery()));
        int count = pCreate.executeUpdate();
        assertEquals("Count from create index", 0, count);
        expectStale(pScan);
        pScan.close();
        pCreate.close();
    }

    @Test
    public void fetchSize() throws Exception {
        boolean ac = getConnection().getAutoCommit();
        getConnection().setAutoCommit(false);
        PreparedStatement p = newScan();
        ResultSet rs = p.executeQuery();
        List<List<Object>> rows = listRows(rs, 2);
        p.setFetchSize(2);
        rs = p.executeQuery();
        assertEquals("Rows with fetch size 2", rows, listRows(rs, 2));
        getConnection().setAutoCommit(ac);
    }
}
TOP

Related Classes of com.foundationdb.sql.pg.PostgresServerPreparedStatementIT

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.