提交 5a2c152e authored 作者: Thomas Mueller's avatar Thomas Mueller

Linked tables that point to the same database now share the connection.

上级 272423cb
......@@ -49,6 +49,7 @@ import org.h2.table.IndexColumn;
import org.h2.table.MetaTable;
import org.h2.table.Table;
import org.h2.table.TableData;
import org.h2.table.TableLinkConnection;
import org.h2.table.TableView;
import org.h2.tools.DeleteDbFiles;
import org.h2.tools.Server;
......@@ -160,6 +161,7 @@ public class Database implements DataHandler {
private boolean autoServerMode;
private Object reserveMemory;
private Server server;
private HashMap linkConnections;
public Database(String name, ConnectionInfo ci, String cipher) throws SQLException {
this.compareMode = new CompareMode(null, null, 0);
......@@ -2054,4 +2056,20 @@ public class Database implements DataHandler {
reserveMemory = null;
}
/**
* Open a new connection or get an existing connection to another database.
*
* @param driver the database driver or null
* @param url the database URL
* @param user the user name
* @param password the password
* @return the connection
*/
public TableLinkConnection getLinkConnection(String driver, String url, String user, String password) throws SQLException {
if (linkConnections == null) {
linkConnections = new HashMap();
}
return TableLinkConnection.open(linkConnections, driver, url, user, password);
}
}
......@@ -67,6 +67,7 @@ public class LinkedIndex extends BaseIndex {
}
buff.append(')');
String sql = buff.toString();
synchronized (link.getConnection()) {
try {
PreparedStatement prep = link.getPreparedStatement(sql);
for (int i = 0, j = 0; i < row.getColumnCount(); i++) {
......@@ -82,6 +83,7 @@ public class LinkedIndex extends BaseIndex {
throw wrapException(sql, e);
}
}
}
public Cursor find(Session session, SearchRow first, SearchRow last) throws SQLException {
StringBuffer buff = new StringBuffer();
......@@ -114,6 +116,7 @@ public class LinkedIndex extends BaseIndex {
}
buff.insert(0, "SELECT * FROM " + targetTableName + " T");
String sql = buff.toString();
synchronized (link.getConnection()) {
try {
PreparedStatement prep = link.getPreparedStatement(sql);
int j = 0;
......@@ -137,6 +140,7 @@ public class LinkedIndex extends BaseIndex {
throw wrapException(sql, e);
}
}
}
private void addParameter(StringBuffer buff, Column col) {
if (col.getType() == Value.STRING_FIXED && link.isOracle()) {
......@@ -202,6 +206,7 @@ public class LinkedIndex extends BaseIndex {
}
}
String sql = buff.toString();
synchronized (link.getConnection()) {
try {
PreparedStatement prep = link.getPreparedStatement(sql);
for (int i = 0, j = 0; i < row.getColumnCount(); i++) {
......@@ -217,6 +222,7 @@ public class LinkedIndex extends BaseIndex {
throw wrapException(sql, e);
}
}
}
/**
* Update a row using a UPDATE statement. This method is to be called if the
......@@ -251,6 +257,7 @@ public class LinkedIndex extends BaseIndex {
}
}
String sql = buff.toString();
synchronized (link.getConnection()) {
try {
int j = 1;
PreparedStatement prep = link.getPreparedStatement(sql);
......@@ -272,6 +279,7 @@ public class LinkedIndex extends BaseIndex {
throw wrapException(sql, e);
}
}
}
private SQLException wrapException(String sql, SQLException e) {
return Message.getSQLException(ErrorCode.ERROR_ACCESSING_LINKED_TABLE_2, new String[] { sql, e.toString() }, e);
......
......@@ -6,7 +6,6 @@
*/
package org.h2.table;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
......@@ -40,7 +39,7 @@ import org.h2.value.DataType;
public class TableLink extends Table {
private String driver, url, user, password, originalSchema, originalTable, qualifiedTableName;
private Connection conn;
private TableLinkConnection conn;
private HashMap prepared = new HashMap();
private final ObjectArray indexes = new ObjectArray();
private final boolean emitUpdates;
......@@ -77,8 +76,20 @@ public class TableLink extends Table {
}
private void connect() throws SQLException {
conn = JdbcUtils.getConnection(driver, url, user, password);
DatabaseMetaData meta = conn.getMetaData();
conn = database.getLinkConnection(driver, url, user, password);
synchronized (conn) {
try {
readMetaData();
} catch (SQLException e) {
conn.close();
conn = null;
throw e;
}
}
}
private void readMetaData() throws SQLException {
DatabaseMetaData meta = conn.getConnection().getMetaData();
storesLowerCase = meta.storesLowerCaseIdentifiers();
storesMixedCase = meta.storesMixedCaseIdentifiers();
supportsMixedCaseIdentifiers = meta.supportsMixedCaseIdentifiers();
......@@ -129,7 +140,7 @@ public class TableLink extends Table {
// check if the table is accessible
Statement stat = null;
try {
stat = conn.createStatement();
stat = conn.getConnection().createStatement();
rs = stat.executeQuery("SELECT * FROM " + qualifiedTableName + " T WHERE 1=0");
if (columnList.size() == 0) {
// alternative solution
......@@ -359,7 +370,7 @@ public class TableLink extends Table {
}
PreparedStatement prep = (PreparedStatement) prepared.get(sql);
if (prep == null) {
prep = conn.prepareStatement(sql);
prep = conn.getConnection().prepareStatement(sql);
prepared.put(sql, prep);
}
return prep;
......@@ -399,7 +410,6 @@ public class TableLink extends Table {
database.removeMeta(session, getId());
driver = null;
url = user = password = originalTable = null;
conn = null;
prepared = null;
invalidate();
}
......@@ -457,4 +467,8 @@ public class TableLink extends Table {
this.readOnly = readOnly;
}
public TableLinkConnection getConnection() {
return conn;
}
}
......@@ -195,4 +195,14 @@ public class ObjectUtils {
}
}
/**
* Calculate the hash code of the given object. The object may be null.
*
* @param the object
* @return the hash code, or 0 if the object is null
*/
public static int hashCode(Object o) {
return o == null ? 0 : o.hashCode();
}
}
......@@ -276,8 +276,6 @@ java org.h2.test.TestAll timer
test on linux
main methods for the tests and make that work
TestMVCC:
Concurrent update in table test: another transaction has updated or
deleted the same row when exactly does it occur in other databases
......
......@@ -41,7 +41,7 @@ public abstract class TestBase {
*/
protected TestAll config;
private long start;
protected long start;
/**
* Get the test directory for this test.
......
......@@ -73,6 +73,7 @@ public class TestLinkedTable extends TestBase {
sa.execute("CREATE SCHEMA P");
sa.execute("CREATE TABLE P.TEST(X INT)");
sa.execute("INSERT INTO TEST VALUES(1)");
sa.execute("INSERT INTO P.TEST VALUES(2)");
try {
sb.execute("CREATE LINKED TABLE T(NULL, 'jdbc:h2:mem:one', 'sa', 'sa', 'TEST')");
fail();
......@@ -81,6 +82,8 @@ public class TestLinkedTable extends TestBase {
}
sb.execute("CREATE LINKED TABLE T(NULL, 'jdbc:h2:mem:one', 'sa', 'sa', 'PUBLIC', 'TEST')");
sb.execute("CREATE LINKED TABLE T2(NULL, 'jdbc:h2:mem:one', 'sa', 'sa', 'P', 'TEST')");
assertSingleValue(sb, "SELECT * FROM T", 1);
assertSingleValue(sb, "SELECT * FROM T2", 2);
sa.execute("DROP ALL OBJECTS");
sb.execute("DROP ALL OBJECTS");
ca.close();
......
......@@ -21,7 +21,7 @@ import org.h2.util.JdbcUtils;
*/
public class TestListener extends TestBase implements DatabaseEventListener {
private long last, start;
private long last;
private int lastState = -1;
private String url;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论