/**
* 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.qp.row.Row;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Collections;
import java.util.Map;
public class PostgresServerCacheIT extends PostgresServerFilesITBase
{
public static final String QUERY = "SELECT id FROM t1 WHERE id = %d";
public static final String PQUERY = "SELECT id FROM t1 WHERE id = ?";
public static final int NROWS = 100;
public static final String CAPACITY = "10";
private int hitsBase;
private int missesBase;
@Override
protected Map<String, String> startupConfigProperties() {
return Collections.singletonMap("fdbsql.postgres.statementCacheCapacity", CAPACITY);
}
@Before
public void createData() throws Exception {
int tid = createTable(SCHEMA_NAME, "t1", "id int not null primary key");
Row[] rows = new Row[NROWS];
for (int i = 0; i < NROWS; i++) {
rows[i] = row(tid, i);
}
writeRows(rows);
hitsBase = server().getStatementCacheHits();
missesBase = server().getStatementCacheMisses();
}
@Test
public void testRepeated() throws Exception {
Statement stmt = getConnection().createStatement();
for (int i = 0; i < 1000; i++) {
query(stmt, i / NROWS);
}
stmt.close();
assertEquals("Cache hits matches", 990, server().getStatementCacheHits() - hitsBase);
assertEquals("Cache misses matches", 10, server().getStatementCacheMisses() - missesBase);
}
@Test
public void testSequential() throws Exception {
Statement stmt = getConnection().createStatement();
for (int i = 0; i < 1000; i++) {
query(stmt, i % NROWS);
}
stmt.close();
assertEquals("Cache hits matches", 0, server().getStatementCacheHits() - hitsBase);
assertEquals("Cache misses matches", 1000, server().getStatementCacheMisses() - missesBase);
}
@Test
public void testPreparedRepeated() throws Exception {
PreparedStatement stmt = getConnection().prepareStatement(PQUERY);
for (int i = 0; i < 1000; i++) {
pquery(stmt, i / NROWS);
}
stmt.close();
assertEquals("Cache hits matches", 4, server().getStatementCacheHits() - hitsBase);
assertEquals("Cache misses matches", 1, server().getStatementCacheMisses() - missesBase);
}
@Test
public void testPreparedSequential() throws Exception {
PreparedStatement stmt = getConnection().prepareStatement(PQUERY);
for (int i = 0; i < 1000; i++) {
pquery(stmt, i % NROWS);
}
stmt.close();
assertEquals("Cache hits matches", 4, server().getStatementCacheHits() - hitsBase);
assertEquals("Cache misses matches", 1, server().getStatementCacheMisses() - missesBase);
}
protected void query(Statement stmt, int n) throws Exception {
ResultSet rs = stmt.executeQuery(String.format(QUERY, n));
if (rs.next()) {
assertEquals("Query result matches", n, rs.getInt(1));
}
else {
fail("No query results");
}
}
protected void pquery (PreparedStatement stmt, int n) throws Exception {
stmt.setInt(1, n);
stmt.execute();
ResultSet rs = stmt.getResultSet();
if (rs.next()) {
assertEquals("Query Result Matches", n, rs.getInt(1));
} else {
fail ("No Query results");
}
}
}