/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*
*/
package org.apache.tajo.catalog.store;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.tajo.catalog.*;
import org.apache.tajo.catalog.proto.CatalogProtos.ColumnProto;
import org.apache.tajo.catalog.proto.CatalogProtos.IndexDescProto;
import org.apache.tajo.catalog.proto.CatalogProtos.IndexMethod;
import org.apache.tajo.catalog.proto.CatalogProtos.StoreType;
import org.apache.tajo.catalog.statistics.TableStat;
import org.apache.tajo.common.TajoDataTypes.Type;
import org.apache.tajo.conf.TajoConf;
import org.apache.tajo.exception.InternalException;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class DerbyStore extends AbstractDBStore {
private static final String JDBC_DRIVER="org.apache.derby.jdbc.EmbeddedDriver";
protected Lock rlock;
protected Lock wlock;
protected String getJDBCDriverName(){
return JDBC_DRIVER;
}
public DerbyStore(final Configuration conf)
throws InternalException {
super(conf);
}
protected Connection createConnection(Configuration conf) throws SQLException {
return DriverManager.getConnection(getJDBCUri());
}
// TODO - DDL and index statements should be renamed
protected void createBaseTable() throws SQLException {
wlock.lock();
Statement stmt = null;
try {
// META
stmt = getConnection().createStatement();
String meta_ddl = "CREATE TABLE " + TB_META + " (version int NOT NULL)";
if (LOG.isDebugEnabled()) {
LOG.debug(meta_ddl);
}
stmt.executeUpdate(meta_ddl);
LOG.info("Table '" + TB_META + " is created.");
// TABLES
String tables_ddl = "CREATE TABLE "
+ TB_TABLES + " ("
+ "TID int NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), "
+ C_TABLE_ID + " VARCHAR(255) NOT NULL CONSTRAINT TABLE_ID_UNIQ UNIQUE, "
+ "path VARCHAR(1024), "
+ "store_type CHAR(16), "
+ "CONSTRAINT TABLES_PK PRIMARY KEY (TID)" +
")";
if (LOG.isDebugEnabled()) {
LOG.debug(tables_ddl);
}
stmt.addBatch(tables_ddl);
String idx_tables_tid =
"CREATE UNIQUE INDEX idx_tables_tid on " + TB_TABLES + " (TID)";
if (LOG.isDebugEnabled()) {
LOG.debug(idx_tables_tid);
}
stmt.addBatch(idx_tables_tid);
String idx_tables_name = "CREATE UNIQUE INDEX idx_tables_name on "
+ TB_TABLES + "(" + C_TABLE_ID + ")";
if (LOG.isDebugEnabled()) {
LOG.debug(idx_tables_name);
}
stmt.addBatch(idx_tables_name);
stmt.executeBatch();
LOG.info("Table '" + TB_TABLES + "' is created.");
// COLUMNS
String columns_ddl =
"CREATE TABLE " + TB_COLUMNS + " ("
+ "TID INT NOT NULL REFERENCES " + TB_TABLES + " (TID) ON DELETE CASCADE, "
+ C_TABLE_ID + " VARCHAR(255) NOT NULL REFERENCES " + TB_TABLES + "("
+ C_TABLE_ID + ") ON DELETE CASCADE, "
+ "column_id INT NOT NULL,"
+ "column_name VARCHAR(255) NOT NULL, " + "data_type CHAR(16), " + "type_length INTEGER, "
+ "CONSTRAINT C_COLUMN_ID UNIQUE (" + C_TABLE_ID + ", column_name))";
if (LOG.isDebugEnabled()) {
LOG.debug(columns_ddl);
}
stmt.addBatch(columns_ddl);
String idx_fk_columns_table_name =
"CREATE UNIQUE INDEX idx_fk_columns_table_name on "
+ TB_COLUMNS + "(" + C_TABLE_ID + ", column_name)";
if (LOG.isDebugEnabled()) {
LOG.debug(idx_fk_columns_table_name);
}
stmt.addBatch(idx_fk_columns_table_name);
stmt.executeBatch();
LOG.info("Table '" + TB_COLUMNS + " is created.");
// OPTIONS
String options_ddl =
"CREATE TABLE " + TB_OPTIONS +" ("
+ C_TABLE_ID + " VARCHAR(255) NOT NULL REFERENCES TABLES (" + C_TABLE_ID +") "
+ "ON DELETE CASCADE, "
+ "key_ VARCHAR(255) NOT NULL, value_ VARCHAR(255) NOT NULL)";
if (LOG.isDebugEnabled()) {
LOG.debug(options_ddl);
}
stmt.addBatch(options_ddl);
String idx_options_key =
"CREATE INDEX idx_options_key on " + TB_OPTIONS + " (" + C_TABLE_ID + ")";
if (LOG.isDebugEnabled()) {
LOG.debug(idx_options_key);
}
stmt.addBatch(idx_options_key);
String idx_options_table_name =
"CREATE INDEX idx_options_table_name on " + TB_OPTIONS
+ "(" + C_TABLE_ID + ")";
if (LOG.isDebugEnabled()) {
LOG.debug(idx_options_table_name);
}
stmt.addBatch(idx_options_table_name);
stmt.executeBatch();
LOG.info("Table '" + TB_OPTIONS + " is created.");
// INDEXES
String indexes_ddl = "CREATE TABLE " + TB_INDEXES +"("
+ "index_name VARCHAR(255) NOT NULL PRIMARY KEY, "
+ C_TABLE_ID + " VARCHAR(255) NOT NULL REFERENCES TABLES (" + C_TABLE_ID + ") "
+ "ON DELETE CASCADE, "
+ "column_name VARCHAR(255) NOT NULL, "
+ "data_type VARCHAR(255) NOT NULL, "
+ "index_type CHAR(32) NOT NULL, "
+ "is_unique BOOLEAN NOT NULL, "
+ "is_clustered BOOLEAN NOT NULL, "
+ "is_ascending BOOLEAN NOT NULL)";
if (LOG.isDebugEnabled()) {
LOG.debug(indexes_ddl);
}
stmt.addBatch(indexes_ddl);
String idx_indexes_key = "CREATE UNIQUE INDEX idx_indexes_key ON "
+ TB_INDEXES + " (index_name)";
if (LOG.isDebugEnabled()) {
LOG.debug(idx_indexes_key);
}
stmt.addBatch(idx_indexes_key);
String idx_indexes_columns = "CREATE INDEX idx_indexes_columns ON "
+ TB_INDEXES + " (" + C_TABLE_ID + ", column_name)";
if (LOG.isDebugEnabled()) {
LOG.debug(idx_indexes_columns);
}
stmt.addBatch(idx_indexes_columns);
stmt.executeBatch();
LOG.info("Table '" + TB_INDEXES + "' is created.");
String stats_ddl = "CREATE TABLE " + TB_STATISTICS + "("
+ C_TABLE_ID + " VARCHAR(255) NOT NULL REFERENCES TABLES (" + C_TABLE_ID + ") "
+ "ON DELETE CASCADE, "
+ "num_rows BIGINT, "
+ "num_bytes BIGINT)";
if (LOG.isDebugEnabled()) {
LOG.debug(stats_ddl);
}
stmt.addBatch(stats_ddl);
String idx_stats_fk_table_name = "CREATE INDEX idx_stats_table_name ON "
+ TB_STATISTICS + " (" + C_TABLE_ID + ")";
if (LOG.isDebugEnabled()) {
LOG.debug(idx_stats_fk_table_name);
}
stmt.addBatch(idx_stats_fk_table_name);
stmt.executeBatch();
LOG.info("Table '" + TB_STATISTICS + "' is created.");
} finally {
wlock.unlock();
CatalogUtil.closeSQLWrapper(stmt);
}
}
@Override
protected boolean isInitialized() throws SQLException {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
this.rlock = lock.readLock();
this.wlock = lock.writeLock();
wlock.lock();
ResultSet res = null;
try {
boolean found = false;
res = getConnection().getMetaData().getTables(null, null, null,
new String [] {"TABLE"});
String resName;
while (res.next() && !found) {
resName = res.getString("TABLE_NAME");
if (TB_META.equals(resName)
|| TB_TABLES.equals(resName)
|| TB_COLUMNS.equals(resName)
|| TB_OPTIONS.equals(resName)) {
return true;
}
}
} finally {
wlock.unlock();
CatalogUtil.closeSQLWrapper(res);
}
return false;
}
final boolean checkInternalTable(final String tableName) throws SQLException {
rlock.lock();
ResultSet res = null;
try {
boolean found = false;
res = getConnection().getMetaData().getTables(null, null, null,
new String [] {"TABLE"});
while(res.next() && !found) {
if (tableName.equals(res.getString("TABLE_NAME")))
found = true;
}
return found;
} finally {
rlock.unlock();
CatalogUtil.closeSQLWrapper(res);
}
}
@Override
public final void addTable(final TableDesc table) throws IOException {
Statement stmt = null;
ResultSet res = null;
String sql =
"INSERT INTO " + TB_TABLES + " (" + C_TABLE_ID + ", path, store_type) "
+ "VALUES('" + table.getName() + "', "
+ "'" + table.getPath() + "', "
+ "'" + table.getMeta().getStoreType() + "'"
+ ")";
wlock.lock();
try {
stmt = getConnection().createStatement();
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
stmt.executeUpdate(sql);
sql = "SELECT TID from " + TB_TABLES + " WHERE " + C_TABLE_ID
+ " = '" + table.getName() + "'";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
res = stmt.executeQuery(sql);
if (!res.next()) {
throw new IOException("ERROR: there is no tid matched to "
+ table.getName());
}
int tid = res.getInt("TID");
String colSql;
int columnId = 0;
for (Column col : table.getMeta().getSchema().getColumns()) {
colSql = columnToSQL(tid, table, columnId, col);
if (LOG.isDebugEnabled()) {
LOG.debug(colSql);
}
stmt.addBatch(colSql);
columnId++;
}
Iterator<Entry<String,String>> it = table.getMeta().toMap().entrySet().iterator();
String optSql;
while (it.hasNext()) {
optSql = keyvalToSQL(table, it.next());
if (LOG.isDebugEnabled()) {
LOG.debug(optSql);
}
stmt.addBatch(optSql);
}
stmt.executeBatch();
if (table.getMeta().getStat() != null) {
sql = "INSERT INTO " + TB_STATISTICS + " (" + C_TABLE_ID + ", num_rows, num_bytes) "
+ "VALUES ('" + table.getName() + "', "
+ table.getMeta().getStat().getNumRows() + ","
+ table.getMeta().getStat().getNumBytes() + ")";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
stmt.executeUpdate(sql);
}
} catch (SQLException se) {
throw new IOException(se.getMessage(), se);
} finally {
wlock.unlock();
CatalogUtil.closeSQLWrapper(res, stmt);
}
}
private String columnToSQL(final int tid, final TableDesc desc,
final int columnId, final Column col) {
String sql =
"INSERT INTO " + TB_COLUMNS
+ " (tid, " + C_TABLE_ID + ", column_id, column_name, data_type, type_length) "
+ "VALUES("
+ tid + ","
+ "'" + desc.getName() + "',"
+ columnId + ", "
+ "'" + col.getColumnName() + "',"
+ "'" + col.getDataType().getType().name() + "',"
+ (col.getDataType().hasLength() ? col.getDataType().getLength() : 0)
+ ")";
return sql;
}
private String keyvalToSQL(final TableDesc desc,
final Entry<String,String> keyVal) {
String sql =
"INSERT INTO " + TB_OPTIONS
+ " (" + C_TABLE_ID + ", key_, value_) "
+ "VALUES("
+ "'" + desc.getName() + "',"
+ "'" + keyVal.getKey() + "',"
+ "'" + keyVal.getValue() + "'"
+ ")";
return sql;
}
@Override
public final boolean existTable(final String name) throws IOException {
StringBuilder sql = new StringBuilder();
sql.append("SELECT " + C_TABLE_ID + " from ")
.append(TB_TABLES)
.append(" WHERE " + C_TABLE_ID + " = '")
.append(name)
.append("'");
Statement stmt = null;
ResultSet res = null;
boolean exist = false;
rlock.lock();
try {
stmt = getConnection().createStatement();
if (LOG.isDebugEnabled()) {
LOG.debug(sql.toString());
}
res = stmt.executeQuery(sql.toString());
exist = res.next();
} catch (SQLException se) {
throw new IOException(se);
} finally {
rlock.unlock();
CatalogUtil.closeSQLWrapper(res, stmt);
}
return exist;
}
@Override
public final void deleteTable(final String name) throws IOException {
Statement stmt = null;
String sql = null;
try {
wlock.lock();
stmt = getConnection().createStatement();
try {
sql = "DELETE FROM " + TB_COLUMNS +
" WHERE " + C_TABLE_ID + " = '" + name + "'";
LOG.info(sql);
stmt.execute(sql);
} catch (SQLException se) {
throw new IOException(se);
}
try {
sql = "DELETE FROM " + TB_OPTIONS +
" WHERE " + C_TABLE_ID + " = '" + name + "'";
LOG.info(sql);
stmt.execute(sql);
} catch (SQLException se) {
throw new IOException(se);
}
try {
sql = "DELETE FROM " + TB_STATISTICS +
" WHERE " + C_TABLE_ID + " = '" + name + "'";
LOG.info(sql);
stmt.execute(sql);
} catch (SQLException se) {
throw new IOException(se);
}
try {
sql = "DELETE FROM " + TB_TABLES +
" WHERE " + C_TABLE_ID +" = '" + name + "'";
LOG.info(sql);
stmt.execute(sql);
} catch (SQLException se) {
throw new IOException(se);
}
} catch (SQLException se) {
throw new IOException(se);
} finally {
wlock.unlock();
CatalogUtil.closeSQLWrapper(stmt);
}
}
@Override
public final TableDesc getTable(final String name) throws IOException {
ResultSet res = null;
Statement stmt = null;
String tableName = null;
Path path = null;
StoreType storeType = null;
Options options;
TableStat stat = null;
try {
rlock.lock();
stmt = getConnection().createStatement();
try {
String sql =
"SELECT " + C_TABLE_ID + ", path, store_type from " + TB_TABLES
+ " WHERE " + C_TABLE_ID + "='" + name + "'";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
res = stmt.executeQuery(sql);
if (!res.next()) { // there is no table of the given name.
return null;
}
tableName = res.getString(C_TABLE_ID).trim();
path = new Path(res.getString("path").trim());
storeType = CatalogUtil.getStoreType(res.getString("store_type").trim());
} catch (SQLException se) {
throw new IOException(se);
} finally {
CatalogUtil.closeSQLWrapper(res);
}
Schema schema = null;
try {
String sql = "SELECT column_name, data_type, type_length from " + TB_COLUMNS
+ " WHERE " + C_TABLE_ID + "='" + name + "' ORDER by column_id asc";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
res = stmt.executeQuery(sql);
schema = new Schema();
while (res.next()) {
String columnName = tableName + "."
+ res.getString("column_name").trim();
Type dataType = getDataType(res.getString("data_type")
.trim());
int typeLength = res.getInt("type_length");
if (typeLength > 0) {
schema.addColumn(columnName, dataType, typeLength);
} else {
schema.addColumn(columnName, dataType);
}
}
} catch (SQLException se) {
throw new IOException(se);
} finally {
CatalogUtil.closeSQLWrapper(res);
}
options = Options.create();
try {
String sql = "SELECT key_, value_ from " + TB_OPTIONS
+ " WHERE " + C_TABLE_ID + "='" + name + "'";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
res = stmt.executeQuery(sql);
while (res.next()) {
options.put(
res.getString("key_"),
res.getString("value_"));
}
} catch (SQLException se) {
throw new IOException(se);
} finally {
CatalogUtil.closeSQLWrapper(res);
}
try {
String sql = "SELECT num_rows, num_bytes from " + TB_STATISTICS
+ " WHERE " + C_TABLE_ID + "='" + name + "'";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
res = stmt.executeQuery(sql);
if (res.next()) {
stat = new TableStat();
stat.setNumRows(res.getLong("num_rows"));
stat.setNumBytes(res.getLong("num_bytes"));
}
} catch (SQLException se) {
throw new IOException(se);
} finally {
CatalogUtil.closeSQLWrapper(res);
}
TableMeta meta = new TableMetaImpl(schema, storeType, options);
if (stat != null) {
meta.setStat(stat);
}
TableDesc table = new TableDescImpl(tableName, meta, path);
return table;
} catch (SQLException se) {
throw new IOException(se);
} finally {
rlock.unlock();
CatalogUtil.closeSQLWrapper(stmt);
}
}
private Type getDataType(final String typeStr) {
try {
return Enum.valueOf(Type.class, typeStr);
} catch (IllegalArgumentException iae) {
LOG.error("Cannot find a matched type aginst from '" + typeStr + "'");
return null;
}
}
@Override
public final List<String> getAllTableNames() throws IOException {
String sql = "SELECT " + C_TABLE_ID + " from " + TB_TABLES;
Statement stmt = null;
ResultSet res = null;
List<String> tables = new ArrayList<String>();
rlock.lock();
try {
stmt = getConnection().createStatement();
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
res = stmt.executeQuery(sql);
while (res.next()) {
tables.add(res.getString(C_TABLE_ID).trim());
}
} catch (SQLException se) {
throw new IOException(se);
} finally {
rlock.unlock();
CatalogUtil.closeSQLWrapper(res, stmt);
}
return tables;
}
public final void addIndex(final IndexDescProto proto) throws IOException {
String sql =
"INSERT INTO indexes (index_name, " + C_TABLE_ID + ", column_name, "
+"data_type, index_type, is_unique, is_clustered, is_ascending) VALUES "
+"(?,?,?,?,?,?,?,?)";
PreparedStatement stmt = null;
wlock.lock();
try {
stmt = getConnection().prepareStatement(sql);
stmt.setString(1, proto.getName());
stmt.setString(2, proto.getTableId());
stmt.setString(3, proto.getColumn().getColumnName());
stmt.setString(4, proto.getColumn().getDataType().getType().name());
stmt.setString(5, proto.getIndexMethod().toString());
stmt.setBoolean(6, proto.hasIsUnique() && proto.getIsUnique());
stmt.setBoolean(7, proto.hasIsClustered() && proto.getIsClustered());
stmt.setBoolean(8, proto.hasIsAscending() && proto.getIsAscending());
stmt.executeUpdate();
if (LOG.isDebugEnabled()) {
LOG.debug(stmt.toString());
}
} catch (SQLException se) {
throw new IOException(se);
} finally {
wlock.unlock();
CatalogUtil.closeSQLWrapper(stmt);
}
}
public final void delIndex(final String indexName) throws IOException {
String sql =
"DELETE FROM " + TB_INDEXES
+ " WHERE index_name='" + indexName + "'";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
Statement stmt = null;
wlock.lock();
try {
stmt = getConnection().createStatement();
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
stmt.executeUpdate(sql);
} catch (SQLException se) {
throw new IOException(se);
} finally {
wlock.unlock();
CatalogUtil.closeSQLWrapper(stmt);
}
}
public final IndexDescProto getIndex(final String indexName)
throws IOException {
ResultSet res = null;
PreparedStatement stmt = null;
IndexDescProto proto = null;
rlock.lock();
try {
String sql =
"SELECT index_name, " + C_TABLE_ID + ", column_name, data_type, "
+ "index_type, is_unique, is_clustered, is_ascending FROM indexes "
+ "where index_name = ?";
stmt = getConnection().prepareStatement(sql);
stmt.setString(1, indexName);
if (LOG.isDebugEnabled()) {
LOG.debug(stmt.toString());
}
res = stmt.executeQuery();
if (!res.next()) {
throw new IOException("ERROR: there is no index matched to " + indexName);
}
proto = resultToProto(res);
} catch (SQLException se) {
} finally {
rlock.unlock();
CatalogUtil.closeSQLWrapper(res, stmt);
}
return proto;
}
public final IndexDescProto getIndex(final String tableName,
final String columnName) throws IOException {
ResultSet res = null;
PreparedStatement stmt = null;
IndexDescProto proto = null;
rlock.lock();
try {
String sql =
"SELECT index_name, " + C_TABLE_ID + ", column_name, data_type, "
+ "index_type, is_unique, is_clustered, is_ascending FROM indexes "
+ "where " + C_TABLE_ID + " = ? AND column_name = ?";
stmt = getConnection().prepareStatement(sql);
stmt.setString(1, tableName);
stmt.setString(2, columnName);
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
res = stmt.executeQuery();
if (!res.next()) {
throw new IOException("ERROR: there is no index matched to "
+ tableName + "." + columnName);
}
proto = resultToProto(res);
} catch (SQLException se) {
new IOException(se);
} finally {
rlock.unlock();
CatalogUtil.closeSQLWrapper(res, stmt);
}
return proto;
}
public final boolean existIndex(final String indexName) throws IOException {
String sql = "SELECT index_name from " + TB_INDEXES
+ " WHERE index_name = ?";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
PreparedStatement stmt = null;
ResultSet res = null;
boolean exist = false;
rlock.lock();
try {
stmt = getConnection().prepareStatement(sql);
stmt.setString(1, indexName);
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
res = stmt.executeQuery();
exist = res.next();
} catch (SQLException se) {
} finally {
rlock.unlock();
CatalogUtil.closeSQLWrapper(res, stmt);
}
return exist;
}
@Override
public boolean existIndex(String tableName, String columnName)
throws IOException {
String sql = "SELECT index_name from " + TB_INDEXES
+ " WHERE " + C_TABLE_ID + " = ? AND COLUMN_NAME = ?";
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
PreparedStatement stmt = null;
ResultSet res = null;
boolean exist = false;
rlock.lock();
try {
stmt = getConnection().prepareStatement(sql);
stmt.setString(1, tableName);
stmt.setString(2, columnName);
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
res = stmt.executeQuery();
exist = res.next();
} catch (SQLException se) {
} finally {
rlock.unlock();
CatalogUtil.closeSQLWrapper(res, stmt);
}
return exist;
}
public final IndexDescProto [] getIndexes(final String tableName)
throws IOException {
ResultSet res = null;
PreparedStatement stmt = null;
List<IndexDescProto> protos = new ArrayList<IndexDescProto>();
rlock.lock();
try {
String sql = "SELECT index_name, " + C_TABLE_ID + ", column_name, data_type, "
+ "index_type, is_unique, is_clustered, is_ascending FROM indexes "
+ "where " + C_TABLE_ID + "= ?";
stmt = getConnection().prepareStatement(sql);
stmt.setString(1, tableName);
if (LOG.isDebugEnabled()) {
LOG.debug(sql);
}
res = stmt.executeQuery();
while (res.next()) {
protos.add(resultToProto(res));
}
} catch (SQLException se) {
} finally {
rlock.unlock();
CatalogUtil.closeSQLWrapper(res, stmt);
}
return protos.toArray(new IndexDescProto [protos.size()]);
}
private IndexDescProto resultToProto(final ResultSet res) throws SQLException {
IndexDescProto.Builder builder = IndexDescProto.newBuilder();
builder.setName(res.getString("index_name"));
builder.setTableId(res.getString(C_TABLE_ID));
builder.setColumn(resultToColumnProto(res));
builder.setIndexMethod(getIndexMethod(res.getString("index_type").trim()));
builder.setIsUnique(res.getBoolean("is_unique"));
builder.setIsClustered(res.getBoolean("is_clustered"));
builder.setIsAscending(res.getBoolean("is_ascending"));
return builder.build();
}
private ColumnProto resultToColumnProto(final ResultSet res) throws SQLException {
ColumnProto.Builder builder = ColumnProto.newBuilder();
builder.setColumnName(res.getString("column_name"));
builder.setDataType(CatalogUtil.newSimpleDataType(
getDataType(res.getString("data_type").trim())));
return builder.build();
}
private IndexMethod getIndexMethod(final String typeStr) {
if (typeStr.equals(IndexMethod.TWO_LEVEL_BIN_TREE.toString())) {
return IndexMethod.TWO_LEVEL_BIN_TREE;
} else {
LOG.error("Cannot find a matched type aginst from '"
+ typeStr + "'");
// TODO - needs exception handling
return null;
}
}
@Override
public final void addFunction(final FunctionDesc func) throws IOException {
// TODO - not implemented yet
}
@Override
public final void deleteFunction(final FunctionDesc func) throws IOException {
// TODO - not implemented yet
}
@Override
public final void existFunction(final FunctionDesc func) throws IOException {
// TODO - not implemented yet
}
@Override
public final List<String> getAllFunctionNames() throws IOException {
// TODO - not implemented yet
return null;
}
@Override
public final void close() {
try {
DriverManager.getConnection("jdbc:derby:;shutdown=true");
} catch (SQLException e) {
// TODO - to be fixed
//LOG.error(e.getMessage(), e);
}
LOG.info("Shutdown database (" + jdbcUri + ")");
}
public static void main(final String[] args) throws IOException {
@SuppressWarnings("unused")
DerbyStore store = new DerbyStore(new TajoConf());
}
}