com.qwazr.database.TableManager Maven / Gradle / Ivy
/*
* Copyright 2015-2018 Emmanuel Keller / QWAZR
*
* Licensed 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 com.qwazr.database;
import com.qwazr.database.model.*;
import com.qwazr.database.store.*;
import com.qwazr.server.ServerException;
import com.qwazr.utils.ExceptionUtils;
import com.qwazr.utils.FileUtils;
import com.qwazr.utils.concurrent.ReadWriteLock;
import org.roaringbitmap.RoaringBitmap;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.stream.Stream;
public class TableManager {
private final ReadWriteLock rwl = ReadWriteLock.stamped();
private final ExecutorService executorService;
private final Path tablesDirectory;
private final TableServiceInterface service;
public TableManager(final ExecutorService executorService, final Path tablesDirectory) throws ServerException {
this.executorService = executorService;
this.tablesDirectory = tablesDirectory;
service = new TableServiceImpl(this);
}
public static Path checkTablesDirectory(final Path dataDirectory) throws IOException {
final Path tablesDirectory = dataDirectory.resolve(TableServiceInterface.SERVICE_NAME);
if (!Files.exists(tablesDirectory))
Files.createDirectory(tablesDirectory);
return tablesDirectory;
}
public TableServiceInterface getService() {
return service;
}
private Table getTable(final String tableName) {
final Path tableDirectory = tablesDirectory.resolve(tableName);
if (!Files.exists(tableDirectory))
throw new ServerException(Response.Status.NOT_FOUND, "Table not found: " + tableName);
return Tables.getInstance(executorService, tableDirectory.toFile(), null);
}
public void createTable(final String tableName, final KeyStore.Impl storeImpl) throws IOException {
rwl.writeEx(() -> {
final Path tableDirectory = tablesDirectory.resolve(tableName);
if (Files.exists(tableDirectory))
throw new ServerException(Response.Status.CONFLICT, "The table already exists: " + tableName);
Files.createDirectory(tableDirectory);
if (!Files.exists(tableDirectory))
throw new ServerException(Response.Status.INTERNAL_SERVER_ERROR,
"The directory cannot be created: " + tableDirectory.toAbsolutePath().toString());
Tables.getInstance(executorService, tableDirectory.toFile(), storeImpl);
});
}
public SortedSet getNameSet() {
return rwl.read(() -> {
final TreeSet names = new TreeSet<>();
try (final Stream stream = Files.list(tablesDirectory)) {
stream.filter(p -> Files.isDirectory(p))
.filter(p -> ExceptionUtils.bypass(() -> !Files.isHidden(p)))
.forEach(p -> names.add(p.getFileName().toString()));
}
return names;
});
}
public TableStatus getStatus(final String tableName) throws IOException {
return rwl.readEx(() -> {
final Table table = getTable(tableName);
final TableDefinition definition = new TableDefinition(table.getImplementation(), table.getColumns());
return new TableStatus(definition, table.getSize());
});
}
public Map getColumns(final String tableName) throws IOException {
return rwl.readEx(() -> getTable(tableName).getColumns());
}
public void setColumn(final String tableName, final String columnName, final ColumnDefinition columnDefinition)
throws IOException {
rwl.writeEx(() -> {
getTable(tableName).setColumn(columnName, columnDefinition);
});
}
public void removeColumn(final String tableName, final String columnName) throws IOException {
rwl.writeEx(() -> {
getTable(tableName).removeColumn(columnName);
});
}
public List