[ASTERIXDB-3259][MTD] Add 'database' entity & tuple translator
- user model changes: no
- storage format changes: no
- interface changes: yes
Details:
- add 'database' entity
- add 'database' tuple translator
- add 'database' drop/add methods to:
metadata node APIs, metadata manager APIs
metadata cache, MetadataTransactionContext
- insert the initial databases on bootstrap:
"System" and "Default"
Change-Id: Idfdfded43ad8695676c10eda6af73cfc8bed8f7e
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17788
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Murtadha Hubail <mhubail@apache.org>
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataCache.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataCache.java
index 6602666..a8d57ce 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataCache.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataCache.java
@@ -30,6 +30,7 @@
import org.apache.asterix.common.metadata.DataverseName;
import org.apache.asterix.metadata.api.IMetadataEntity;
import org.apache.asterix.metadata.entities.CompactionPolicy;
+import org.apache.asterix.metadata.entities.Database;
import org.apache.asterix.metadata.entities.Dataset;
import org.apache.asterix.metadata.entities.DatasourceAdapter;
import org.apache.asterix.metadata.entities.Datatype;
@@ -51,10 +52,11 @@
* Caches metadata entities such that the MetadataManager does not have to
* contact the MetadataNode. The cache is updated transactionally via logical
* logging in the MetadataTransactionContext. Note that transaction abort is
- * simply ignored, i.e., updates are not not applied to the cache.
+ * simply ignored, i.e., updates are not applied to the cache.
*/
public class MetadataCache {
+ protected final Map<String, Database> databases = new HashMap<>();
// Key is dataverse name.
protected final Map<DataverseName, Dataverse> dataverses = new HashMap<>();
// Key is dataverse name. Key of value map is dataset name.
@@ -152,6 +154,16 @@
}
}
+ public Database addDatabaseIfNotExists(Database database) {
+ synchronized (databases) {
+ String databaseName = database.getDatabaseName();
+ if (!databases.containsKey(databaseName)) {
+ return databases.put(databaseName, database);
+ }
+ return null;
+ }
+ }
+
public Dataverse addDataverseIfNotExists(Dataverse dataverse) {
synchronized (dataverses) {
synchronized (datasets) {
@@ -244,6 +256,36 @@
}
}
+ public Database dropDatabase(Database database) {
+ synchronized (databases) {
+ synchronized (dataverses) {
+ synchronized (datasets) {
+ synchronized (indexes) {
+ synchronized (datatypes) {
+ synchronized (functions) {
+ synchronized (fullTextConfigs) {
+ synchronized (fullTextFilters) {
+ synchronized (adapters) {
+ synchronized (libraries) {
+ synchronized (feeds) {
+ synchronized (compactionPolicies) {
+ synchronized (synonyms) {
+ return databases.remove(database.getDatabaseName());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
public Dataverse dropDataverse(Dataverse dataverse) {
synchronized (dataverses) {
synchronized (datasets) {
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java
index 547be91..b75fc3a 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java
@@ -42,6 +42,7 @@
import org.apache.asterix.metadata.api.IMetadataManager;
import org.apache.asterix.metadata.api.IMetadataNode;
import org.apache.asterix.metadata.entities.CompactionPolicy;
+import org.apache.asterix.metadata.entities.Database;
import org.apache.asterix.metadata.entities.Dataset;
import org.apache.asterix.metadata.entities.DatasourceAdapter;
import org.apache.asterix.metadata.entities.Datatype;
@@ -169,6 +170,26 @@
}
@Override
+ public void addDatabase(MetadataTransactionContext ctx, Database database) throws AlgebricksException {
+ try {
+ metadataNode.addDatabase(ctx.getTxnId(), database);
+ } catch (RemoteException e) {
+ throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
+ }
+ ctx.addDatabase(database);
+ }
+
+ @Override
+ public void dropDatabase(MetadataTransactionContext ctx, String databaseName) throws AlgebricksException {
+ try {
+ metadataNode.dropDatabase(ctx.getTxnId(), databaseName);
+ } catch (RemoteException e) {
+ throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
+ }
+ ctx.dropDatabase(databaseName);
+ }
+
+ @Override
public void addDataverse(MetadataTransactionContext ctx, Dataverse dataverse) throws AlgebricksException {
try {
metadataNode.addDataverse(ctx.getTxnId(), dataverse);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
index b8d1203..a8bbd45 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
@@ -63,6 +63,7 @@
import org.apache.asterix.metadata.api.IValueExtractor;
import org.apache.asterix.metadata.bootstrap.MetadataIndexesProvider;
import org.apache.asterix.metadata.entities.CompactionPolicy;
+import org.apache.asterix.metadata.entities.Database;
import org.apache.asterix.metadata.entities.Dataset;
import org.apache.asterix.metadata.entities.DatasourceAdapter;
import org.apache.asterix.metadata.entities.Datatype;
@@ -82,6 +83,7 @@
import org.apache.asterix.metadata.entities.Synonym;
import org.apache.asterix.metadata.entities.ViewDetails;
import org.apache.asterix.metadata.entitytupletranslators.CompactionPolicyTupleTranslator;
+import org.apache.asterix.metadata.entitytupletranslators.DatabaseTupleTranslator;
import org.apache.asterix.metadata.entitytupletranslators.DatasetTupleTranslator;
import org.apache.asterix.metadata.entitytupletranslators.DatasourceAdapterTupleTranslator;
import org.apache.asterix.metadata.entitytupletranslators.DatatypeTupleTranslator;
@@ -350,6 +352,28 @@
}
@Override
+ public void addDatabase(TxnId txnId, Database database) throws AlgebricksException, RemoteException {
+ try {
+ DatabaseTupleTranslator tupleReaderWriter = tupleTranslatorProvider.getDatabaseTupleTranslator(true);
+ ITupleReference tuple = tupleReaderWriter.getTupleFromMetadataEntity(database);
+ insertTupleIntoIndex(txnId, mdIndexesProvider.getDatabaseEntity().getIndex(), tuple);
+ } catch (HyracksDataException e) {
+ if (e.matches(ErrorCode.DUPLICATE_KEY)) {
+ //TODO(DB): change to database
+ throw new AsterixException(org.apache.asterix.common.exceptions.ErrorCode.DATAVERSE_EXISTS, e,
+ database.getDatabaseName());
+ } else {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+
+ @Override
+ public void dropDatabase(TxnId txnId, String databaseName) throws AlgebricksException, RemoteException {
+ //TODO(DB): implement
+ }
+
+ @Override
public void addDataverse(TxnId txnId, Dataverse dataverse) throws AlgebricksException {
try {
DataverseTupleTranslator tupleReaderWriter = tupleTranslatorProvider.getDataverseTupleTranslator(true);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataTransactionContext.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataTransactionContext.java
index 48fb450..54bc0bc 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataTransactionContext.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataTransactionContext.java
@@ -27,6 +27,7 @@
import org.apache.asterix.common.transactions.TxnId;
import org.apache.asterix.external.dataset.adapter.AdapterIdentifier;
import org.apache.asterix.metadata.entities.CompactionPolicy;
+import org.apache.asterix.metadata.entities.Database;
import org.apache.asterix.metadata.entities.Dataset;
import org.apache.asterix.metadata.entities.DatasourceAdapter;
import org.apache.asterix.metadata.entities.Datatype;
@@ -86,6 +87,11 @@
return txnId;
}
+ public void addDatabase(Database database) {
+ droppedCache.dropDatabase(database);
+ logAndApply(new MetadataLogicalOperation(database, true));
+ }
+
public void addDataverse(Dataverse dataverse) {
droppedCache.dropDataverse(dataverse);
logAndApply(new MetadataLogicalOperation(dataverse, true));
@@ -150,6 +156,12 @@
logAndApply(new MetadataLogicalOperation(index, false));
}
+ public void dropDatabase(String databaseName) {
+ Database database = new Database(databaseName, false, MetadataUtil.PENDING_NO_OP);
+ droppedCache.addDatabaseIfNotExists(database);
+ logAndApply(new MetadataLogicalOperation(database, false));
+ }
+
public void dropDataverse(DataverseName dataverseName) {
Dataverse dataverse = new Dataverse(dataverseName, null, MetadataUtil.PENDING_NO_OP);
droppedCache.addDataverseIfNotExists(dataverse);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java
index a109785..074a5cd 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java
@@ -29,6 +29,7 @@
import org.apache.asterix.external.indexing.ExternalFile;
import org.apache.asterix.metadata.MetadataTransactionContext;
import org.apache.asterix.metadata.entities.CompactionPolicy;
+import org.apache.asterix.metadata.entities.Database;
import org.apache.asterix.metadata.entities.Dataset;
import org.apache.asterix.metadata.entities.DatasourceAdapter;
import org.apache.asterix.metadata.entities.Datatype;
@@ -89,6 +90,10 @@
*/
void abortTransaction(MetadataTransactionContext ctx) throws ACIDException, RemoteException;
+ void addDatabase(MetadataTransactionContext ctx, Database database) throws AlgebricksException;
+
+ void dropDatabase(MetadataTransactionContext ctx, String databaseName) throws AlgebricksException;
+
/**
* Inserts a new dataverse into the metadata.
*
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java
index 60f457f..c167dd6 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java
@@ -29,6 +29,7 @@
import org.apache.asterix.common.transactions.TxnId;
import org.apache.asterix.external.indexing.ExternalFile;
import org.apache.asterix.metadata.entities.CompactionPolicy;
+import org.apache.asterix.metadata.entities.Database;
import org.apache.asterix.metadata.entities.Dataset;
import org.apache.asterix.metadata.entities.DatasourceAdapter;
import org.apache.asterix.metadata.entities.Datatype;
@@ -78,6 +79,10 @@
*/
void abortTransaction(TxnId txnId) throws RemoteException;
+ void addDatabase(TxnId txnId, Database database) throws AlgebricksException, RemoteException;
+
+ void dropDatabase(TxnId txnId, String databaseName) throws AlgebricksException, RemoteException;
+
/**
* Inserts a new dataverse into the metadata, acquiring local locks on behalf of
* the given transaction id.
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/DatabaseEntity.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/DatabaseEntity.java
index 4982dc2..0a14c24 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/DatabaseEntity.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/DatabaseEntity.java
@@ -20,7 +20,6 @@
package org.apache.asterix.metadata.bootstrap;
import static org.apache.asterix.metadata.bootstrap.MetadataPrimaryIndexes.PROPERTIES_DATABASE;
-import static org.apache.asterix.metadata.bootstrap.MetadataRecordTypes.FIELD_NAME_DATABASE_ID;
import static org.apache.asterix.metadata.bootstrap.MetadataRecordTypes.FIELD_NAME_DATABASE_NAME;
import static org.apache.asterix.metadata.bootstrap.MetadataRecordTypes.FIELD_NAME_PENDING_OP;
import static org.apache.asterix.metadata.bootstrap.MetadataRecordTypes.FIELD_NAME_SYSTEM_DATABASE;
@@ -44,7 +43,6 @@
private final int payloadPosition;
private final MetadataIndex index;
private final int databaseNameIndex;
- private final int databaseIdIndex;
private final int systemDatabaseIndex;
private final int timestampIndex;
private final int pendingOpIndex;
@@ -53,7 +51,6 @@
this.index = index;
this.payloadPosition = payloadPosition;
this.databaseNameIndex = startIndex++;
- this.databaseIdIndex = startIndex++;
this.systemDatabaseIndex = startIndex++;
this.timestampIndex = startIndex++;
this.pendingOpIndex = startIndex++;
@@ -79,10 +76,6 @@
return databaseNameIndex;
}
- public int databaseIdIndex() {
- return databaseIdIndex;
- }
-
public int systemDatabaseIndex() {
return systemDatabaseIndex;
}
@@ -100,11 +93,10 @@
// RecordTypeName
RECORD_NAME_DATABASE,
// FieldNames
- new String[] { FIELD_NAME_DATABASE_NAME, FIELD_NAME_DATABASE_ID, FIELD_NAME_SYSTEM_DATABASE,
- FIELD_NAME_TIMESTAMP, FIELD_NAME_PENDING_OP },
+ new String[] { FIELD_NAME_DATABASE_NAME, FIELD_NAME_SYSTEM_DATABASE, FIELD_NAME_TIMESTAMP,
+ FIELD_NAME_PENDING_OP },
// FieldTypes
- new IAType[] { BuiltinType.ASTRING, BuiltinType.AINT32, BuiltinType.ABOOLEAN, BuiltinType.ASTRING,
- BuiltinType.AINT32 },
+ new IAType[] { BuiltinType.ASTRING, BuiltinType.ABOOLEAN, BuiltinType.ASTRING, BuiltinType.AINT32 },
//IsOpen?
true);
}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBootstrap.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBootstrap.java
index 1e84287..d3a7535 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBootstrap.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBootstrap.java
@@ -156,6 +156,7 @@
"Finished enlistment of metadata B-trees in " + (isNewUniverse ? "new" : "old") + " universe");
}
if (isNewUniverse) {
+ insertInitialDatabases(mdTxnCtx, mdIndexesProvider);
insertInitialDataverses(mdTxnCtx);
insertMetadataDatasets(mdTxnCtx, PRIMARY_INDEXES);
insertMetadataDatatypes(mdTxnCtx);
@@ -190,6 +191,14 @@
}
}
+ private static void insertInitialDatabases(MetadataTransactionContext mdTxnCtx,
+ MetadataIndexesProvider mdIndexesProvider) throws AlgebricksException {
+ if (mdIndexesProvider.isUsingDatabase()) {
+ MetadataManager.INSTANCE.addDatabase(mdTxnCtx, MetadataBuiltinEntities.SYSTEM_DATABASE);
+ MetadataManager.INSTANCE.addDatabase(mdTxnCtx, MetadataBuiltinEntities.DEFAULT_DATABASE);
+ }
+ }
+
private static void insertInitialDataverses(MetadataTransactionContext mdTxnCtx) throws AlgebricksException {
MetadataManager.INSTANCE.addDataverse(mdTxnCtx, MetadataBuiltinEntities.METADATA_DATAVERSE);
MetadataManager.INSTANCE.addDataverse(mdTxnCtx, MetadataBuiltinEntities.DEFAULT_DATAVERSE);
@@ -213,7 +222,7 @@
new Dataset(indexes[i].getDataverseName(), indexes[i].getIndexedDatasetName(),
indexes[i].getDataverseName(), indexes[i].getPayloadRecordType().getTypeName(),
indexes[i].getNodeGroupName(), StorageConstants.DEFAULT_COMPACTION_POLICY_NAME,
- StorageConstants.DEFAULT_COMPACTION_POLICY_PROPERTIES, id, new HashMap<String, String>(),
+ StorageConstants.DEFAULT_COMPACTION_POLICY_PROPERTIES, id, new HashMap<>(),
DatasetType.INTERNAL, indexes[i].getDatasetId().getId(), MetadataUtil.PENDING_NO_OP));
}
if (LOGGER.isInfoEnabled()) {
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBuiltinEntities.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBuiltinEntities.java
index 05b7c96..4077573 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBuiltinEntities.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBuiltinEntities.java
@@ -19,6 +19,7 @@
package org.apache.asterix.metadata.bootstrap;
import org.apache.asterix.common.metadata.DataverseName;
+import org.apache.asterix.metadata.entities.Database;
import org.apache.asterix.metadata.entities.Datatype;
import org.apache.asterix.metadata.entities.Dataverse;
import org.apache.asterix.metadata.utils.MetadataConstants;
@@ -27,6 +28,13 @@
import org.apache.asterix.runtime.formats.NonTaggedDataFormat;
public class MetadataBuiltinEntities {
+
+ //--------------------------------------- Databases ----------------------------------------//
+ public static final Database SYSTEM_DATABASE =
+ new Database(MetadataConstants.SYSTEM_DATABASE, true, MetadataUtil.PENDING_NO_OP);
+ public static final Database DEFAULT_DATABASE =
+ new Database(MetadataConstants.DEFAULT_DATABASE, false, MetadataUtil.PENDING_NO_OP);
+
//--------------------------------------- Dataverses ----------------------------------------//
public static final Dataverse METADATA_DATAVERSE = new Dataverse(MetadataConstants.METADATA_DATAVERSE_NAME,
NonTaggedDataFormat.NON_TAGGED_DATA_FORMAT, MetadataUtil.PENDING_NO_OP);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataIndexesProvider.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataIndexesProvider.java
index f7bf610..8c19505 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataIndexesProvider.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataIndexesProvider.java
@@ -31,6 +31,10 @@
cloudDeployment = ncServiceCtx.getAppConfig().getBoolean(CLOUD_DEPLOYMENT);
}
+ public DatabaseEntity getDatabaseEntity() {
+ return DatabaseEntity.of(cloudDeployment);
+ }
+
public DataverseEntity getDataverseEntity() {
return DataverseEntity.of(cloudDeployment);
}
@@ -100,13 +104,25 @@
}
public IMetadataIndex[] getMetadataIndexes() {
- return new IMetadataIndex[] { getDataverseEntity().getIndex(), getDatasetEntity().getIndex(),
- getDatatypeEntity().getIndex(), getIndexEntity().getIndex(), getSynonymEntity().getIndex(),
- getNodeEntity().getIndex(), getNodeGroupEntity().getIndex(), getFunctionEntity().getIndex(),
- getDatasourceAdapterEntity().getIndex(), getFeedEntity().getIndex(), getFeedPolicyEntity().getIndex(),
- getLibraryEntity().getIndex(), getCompactionPolicyEntity().getIndex(),
- getExternalFileEntity().getIndex(), getFeedConnectionEntity().getIndex(),
- getFullTextConfigEntity().getIndex(), getFullTextFilterEntity().getIndex() };
+ if (isUsingDatabase()) {
+ return new IMetadataIndex[] { getDatabaseEntity().getIndex(), getDataverseEntity().getIndex(),
+ getDatasetEntity().getIndex(), getDatatypeEntity().getIndex(), getIndexEntity().getIndex(),
+ getSynonymEntity().getIndex(), getNodeEntity().getIndex(), getNodeGroupEntity().getIndex(),
+ getFunctionEntity().getIndex(), getDatasourceAdapterEntity().getIndex(), getFeedEntity().getIndex(),
+ getFeedPolicyEntity().getIndex(), getLibraryEntity().getIndex(),
+ getCompactionPolicyEntity().getIndex(), getExternalFileEntity().getIndex(),
+ getFeedConnectionEntity().getIndex(), getFullTextConfigEntity().getIndex(),
+ getFullTextFilterEntity().getIndex() };
+ } else {
+ return new IMetadataIndex[] { getDataverseEntity().getIndex(), getDatasetEntity().getIndex(),
+ getDatatypeEntity().getIndex(), getIndexEntity().getIndex(), getSynonymEntity().getIndex(),
+ getNodeEntity().getIndex(), getNodeGroupEntity().getIndex(), getFunctionEntity().getIndex(),
+ getDatasourceAdapterEntity().getIndex(), getFeedEntity().getIndex(),
+ getFeedPolicyEntity().getIndex(), getLibraryEntity().getIndex(),
+ getCompactionPolicyEntity().getIndex(), getExternalFileEntity().getIndex(),
+ getFeedConnectionEntity().getIndex(), getFullTextConfigEntity().getIndex(),
+ getFullTextFilterEntity().getIndex() };
+ }
}
public boolean isUsingDatabase() {
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Database.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Database.java
new file mode 100644
index 0000000..8be93e3
--- /dev/null
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Database.java
@@ -0,0 +1,84 @@
+/*
+ * 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.asterix.metadata.entities;
+
+import java.util.Objects;
+
+import org.apache.asterix.metadata.MetadataCache;
+import org.apache.asterix.metadata.api.IMetadataEntity;
+
+/**
+ * Metadata describing a database.
+ */
+public class Database implements IMetadataEntity<Database> {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String databaseName;
+ private final boolean isSystemDatabase;
+ private final int pendingOp;
+
+ public Database(String databaseName, boolean isSystemDatabase, int pendingOp) {
+ this.databaseName = databaseName;
+ this.isSystemDatabase = isSystemDatabase;
+ this.pendingOp = pendingOp;
+ }
+
+ public String getDatabaseName() {
+ return databaseName;
+ }
+
+ public boolean isSystemDatabase() {
+ return isSystemDatabase;
+ }
+
+ public int getPendingOp() {
+ return pendingOp;
+ }
+
+ @Override
+ public Database addToCache(MetadataCache cache) {
+ return cache.addDatabaseIfNotExists(this);
+ }
+
+ @Override
+ public Database dropFromCache(MetadataCache cache) {
+ return cache.dropDatabase(this);
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + ":" + databaseName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof Database)) {
+ return false;
+ }
+ Database other = (Database) o;
+ return Objects.equals(databaseName, other.databaseName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(databaseName);
+ }
+}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatabaseTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatabaseTupleTranslator.java
new file mode 100644
index 0000000..9752dc8
--- /dev/null
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatabaseTupleTranslator.java
@@ -0,0 +1,104 @@
+/*
+ * 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.asterix.metadata.entitytupletranslators;
+
+import java.util.Calendar;
+
+import org.apache.asterix.metadata.bootstrap.DatabaseEntity;
+import org.apache.asterix.metadata.entities.Database;
+import org.apache.asterix.om.base.ABoolean;
+import org.apache.asterix.om.base.AInt32;
+import org.apache.asterix.om.base.AMutableInt32;
+import org.apache.asterix.om.base.ARecord;
+import org.apache.asterix.om.base.AString;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
+
+/**
+ * Translates a Database metadata entity to an ITupleReference and vice versa.
+ */
+public class DatabaseTupleTranslator extends AbstractTupleTranslator<Database> {
+
+ private final DatabaseEntity databaseEntity;
+ private AMutableInt32 aInt32;
+
+ protected DatabaseTupleTranslator(boolean getTuple, DatabaseEntity databaseEntity) {
+ super(getTuple, databaseEntity.getIndex(), databaseEntity.payloadPosition());
+ this.databaseEntity = databaseEntity;
+ if (getTuple) {
+ aInt32 = new AMutableInt32(-1);
+ }
+ }
+
+ @Override
+ protected Database createMetadataEntityFromARecord(ARecord databaseRecord) throws AlgebricksException {
+ String databaseName =
+ ((AString) databaseRecord.getValueByPos(databaseEntity.databaseNameIndex())).getStringValue();
+ boolean isSystemDatabase =
+ ((ABoolean) databaseRecord.getValueByPos(databaseEntity.systemDatabaseIndex())).getBoolean();
+ int pendingOp = ((AInt32) databaseRecord.getValueByPos(databaseEntity.pendingOpIndex())).getIntegerValue();
+ return new Database(databaseName, isSystemDatabase, pendingOp);
+ }
+
+ @Override
+ public ITupleReference getTupleFromMetadataEntity(Database database) throws HyracksDataException {
+ tupleBuilder.reset();
+
+ // write the database name key in the first field of the tuple
+ aString.setValue(database.getDatabaseName());
+ stringSerde.serialize(aString, tupleBuilder.getDataOutput());
+ tupleBuilder.addFieldEndOffset();
+
+ // write the payload in the second field of the tuple
+ recordBuilder.reset(databaseEntity.getRecordType());
+
+ // write "DatabaseName" at index 0
+ fieldValue.reset();
+ aString.setValue(database.getDatabaseName());
+ stringSerde.serialize(aString, fieldValue.getDataOutput());
+ recordBuilder.addField(databaseEntity.databaseNameIndex(), fieldValue);
+
+ // write "SystemDatabase" at index 1
+ fieldValue.reset();
+ booleanSerde.serialize(database.isSystemDatabase() ? ABoolean.TRUE : ABoolean.FALSE,
+ fieldValue.getDataOutput());
+ recordBuilder.addField(databaseEntity.systemDatabaseIndex(), fieldValue);
+
+ // write "Timestamp" at index 2
+ fieldValue.reset();
+ aString.setValue(Calendar.getInstance().getTime().toString());
+ stringSerde.serialize(aString, fieldValue.getDataOutput());
+ recordBuilder.addField(databaseEntity.timestampIndex(), fieldValue);
+
+ // write "PendingOp" at index 3
+ fieldValue.reset();
+ aInt32.setValue(database.getPendingOp());
+ int32Serde.serialize(aInt32, fieldValue.getDataOutput());
+ recordBuilder.addField(databaseEntity.pendingOpIndex(), fieldValue);
+
+ // write the payload record
+ recordBuilder.write(tupleBuilder.getDataOutput(), true);
+ tupleBuilder.addFieldEndOffset();
+
+ tuple.reset(tupleBuilder.getFieldEndOffsets(), tupleBuilder.getByteArray());
+ return tuple;
+ }
+}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/MetadataTupleTranslatorProvider.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/MetadataTupleTranslatorProvider.java
index 3560e9f..42e4d9d 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/MetadataTupleTranslatorProvider.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/MetadataTupleTranslatorProvider.java
@@ -47,6 +47,10 @@
return new DatatypeTupleTranslator(txnId, metadataNode, getTuple, mdIndexesProvider.getDatatypeEntity());
}
+ public DatabaseTupleTranslator getDatabaseTupleTranslator(boolean getTuple) {
+ return new DatabaseTupleTranslator(getTuple, mdIndexesProvider.getDatabaseEntity());
+ }
+
public DataverseTupleTranslator getDataverseTupleTranslator(boolean getTuple) {
return new DataverseTupleTranslator(getTuple, mdIndexesProvider.getDataverseEntity());
}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/MetadataConstants.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/MetadataConstants.java
index 60d97d6..1c5774b 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/MetadataConstants.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/MetadataConstants.java
@@ -34,6 +34,10 @@
public static final Pattern METADATA_OBJECT_NAME_INVALID_CHARS =
Pattern.compile(SystemUtils.IS_OS_WINDOWS ? "[\u0000-\u001F\u007F\"*/:<>\\\\|+,;=\\[\\]\n]" : "[\u0000/]");
+ // Pre-defined databases
+ public static final String SYSTEM_DATABASE = "System";
+ public static final String DEFAULT_DATABASE = "Default";
+
// Name of the dataverse the metadata lives in.
public static final DataverseName METADATA_DATAVERSE_NAME = DataverseName.createBuiltinDataverseName("Metadata");
// Name of the node group where metadata is stored on.