/*
* ToroDB
* Copyright © 2014 8Kdata Technology (www.8kdata.com)
*
* 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.torodb.backend.derby;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.torodb.backend.AbstractStructureInterface;
import com.torodb.backend.InternalField;
import com.torodb.backend.SqlBuilder;
import com.torodb.backend.SqlHelper;
import com.torodb.backend.converters.jooq.DataTypeForKv;
import com.torodb.core.backend.IdentifierConstraints;
import org.jooq.DSLContext;
import org.jooq.lambda.tuple.Tuple2;
import java.util.Collection;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
*
*/
@Singleton
public class DerbyStructureInterface extends AbstractStructureInterface {
@Inject
public DerbyStructureInterface(DerbyDbBackend dbBackend,
DerbyMetaDataReadInterface metaDataReadInterface,
SqlHelper sqlHelper,
IdentifierConstraints identifierConstraints) {
super(dbBackend, metaDataReadInterface, sqlHelper, identifierConstraints);
}
@Override
protected String getDropTableStatement(String schemaName, String tableName) {
return "DROP TABLE \"" + schemaName + "\".\"" + tableName + "\"";
}
@Override
protected String getRenameTableStatement(String fromSchemaName, String fromTableName,
String toTableName) {
return "RENAME TABLE \"" + fromSchemaName + "\".\"" + fromTableName + "\" TO \"" + toTableName
+ "\"";
}
@Override
protected String getRenameIndexStatement(String fromSchemaName, String fromIndexName,
String toIndexName) {
return "SET SCHEMA = \"" + fromSchemaName + "\"; RENAME INDEX \"" + fromIndexName + "\" TO \""
+ toIndexName + "\"";
}
@Override
protected String getSetTableSchemaStatement(String fromSchemaName, String fromTableName,
String toSchemaName) {
throw new UnsupportedOperationException();
}
@Override
protected String getDropSchemaStatement(String schemaName) {
return "DROP SCHEMA \"" + schemaName + "\" RESTRICT";
}
@Override
protected String getCreateIndexStatement(String indexName, String schemaName, String tableName,
List<Tuple2<String, Boolean>> columnList, boolean unique) {
StringBuilder sb = new StringBuilder()
.append(unique ? "CREATE UNIQUE INDEX " : "CREATE INDEX ")
.append("\"").append(indexName).append("\"")
.append(" ON ")
.append("\"").append(schemaName).append("\"")
.append(".")
.append("\"").append(tableName).append("\"")
.append(" (");
for (Tuple2<String, Boolean> columnEntry : columnList) {
sb.append("\"").append(columnEntry.v1()).append("\" ")
.append(columnEntry.v2() ? "ASC," : "DESC,");
}
sb.setCharAt(sb.length() - 1, ')');
String statement = sb.toString();
return statement;
}
@Override
protected String getDropIndexStatement(String schemaName, String indexName) {
StringBuilder sb = new StringBuilder()
.append("DROP INDEX \"")
.append(schemaName)
.append("\".\"")
.append(indexName)
.append('"');
return sb.toString();
}
@Override
protected String getCreateSchemaStatement(String schemaName) {
return "CREATE SCHEMA \"" + schemaName + "\"";
}
@Override
protected String getCreateDocPartTableStatement(String schemaName, String tableName,
Collection<InternalField<?>> fields) {
SqlBuilder sb = new SqlBuilder("CREATE TABLE ");
sb.table(schemaName, tableName)
.append(" (");
if (!fields.isEmpty()) {
for (InternalField<?> field : fields) {
sb.quote(field.getName()).append(' ')
.append(field.getDataType().getCastTypeName());
if (!field.isNullable()) {
sb.append(" NOT NULL");
}
sb.append(',');
}
sb.setLastChar(')');
} else {
sb.append(')');
}
return sb.toString();
}
@Override
protected String getAddDocPartTablePrimaryKeyStatement(String schemaName, String tableName,
Collection<InternalField<?>> primaryKeyFields) {
SqlBuilder sb = new SqlBuilder("ALTER TABLE ");
sb.table(schemaName, tableName)
.append(" ADD PRIMARY KEY (");
for (InternalField<?> field : primaryKeyFields) {
sb.quote(field.getName()).append(',');
}
sb.setLastChar(')');
return sb.toString();
}
@Override
protected String getAddDocPartTableForeignKeyStatement(String schemaName, String tableName,
Collection<InternalField<?>> referenceFields, String foreignTableName,
Collection<InternalField<?>> foreignFields) {
Preconditions.checkArgument(referenceFields.size() == foreignFields.size());
SqlBuilder sb = new SqlBuilder("ALTER TABLE ");
sb.table(schemaName, tableName)
.append(" ADD FOREIGN KEY (");
for (InternalField<?> field : referenceFields) {
sb.quote(field.getName()).append(',');
}
sb.setLastChar(')')
.append(" REFERENCES ")
.table(schemaName, foreignTableName)
.append(" (");
for (InternalField<?> field : foreignFields) {
sb.quote(field.getName()).append(',');
}
sb.setLastChar(')');
return sb.toString();
}
@Override
protected String getCreateDocPartTableIndexStatement(String schemaName, String tableName,
Collection<InternalField<?>> indexFields) {
Preconditions.checkArgument(!indexFields.isEmpty());
SqlBuilder sb = new SqlBuilder("CREATE INDEX ");
String fieldPartName = Joiner.on("")
.join(indexFields.stream()
.map(field -> field.getName()).iterator()
);
sb.quote(tableName + fieldPartName + "_idx");
sb.append(" ON ");
sb.table(schemaName, tableName)
.append(" (");
for (InternalField<?> field : indexFields) {
sb.quote(field.getName()).append(',');
}
sb.setLastChar(')');
return sb.toString();
}
@Override
protected String getAddColumnToDocPartTableStatement(String schemaName, String tableName,
String columnName,
DataTypeForKv<?> dataType) {
SqlBuilder sb = new SqlBuilder("ALTER TABLE ")
.table(schemaName, tableName)
.append(" ADD COLUMN ")
.quote(columnName)
.append(" ")
.append(dataType.getCastTypeName());
return sb.toString();
}
@Override
protected void dropDatabase(DSLContext dsl, String dbIdentifier) {
//TODO: The general implementation is not implemented yet, as it
//requires several reads to the metadata
throw new UnsupportedOperationException("It is not defined yet how to "
+ "drop all user databases on a general way");
}
}