Skip to main content

Database Administration Transaction

The database administration transaction can be used for

  1. Creation of new databases without index
  2. Creation of a new database with index definition
  3. Deletion of existing databases

Note that all database administration transactions must be submitted by the admin.

Once a database session is created, we can call session.DBsTx() to start the database administration transaction context. On this transaction context, we have the support for following method calls:

// DBsTxContext abstraction for database management transaction context
type DBsTxContext interface {
// CreateDB creates new database along with index definition for the query.
// The index is a map of attributes/fields in json document, i.e., value associated
// with the key, to its value type. For example, map["name"]types.IndexAttributeType_STRING
// denotes that "name" attribute in all json documents to be stored in the given
// database to be indexed for queries. Note that only indexed attributes can be
// used as predicates in the query string. Currently, we support the following three
// value types: STRING, BOOLEAN, and INT64
CreateDB(dbName string, index map[string]types.IndexAttributeType) error
// DeleteDB deletes database
DeleteDB(dbName string) error
// Exists checks whenever database is already created
Exists(dbName string) (bool, error)
// Commit submits transaction to the server, can be sync or async.
// Sync option returns tx id and tx receipt and
// in case of error, commitTimeout error is one of possible errors to return.
// Async returns tx id, always nil as tx receipt or error
Commit(sync bool) (string, *types.TxReceipt, error)
// Abort cancel submission and abandon all changes
// within given transaction context
Abort() error
// CommittedTxEnvelope returns transaction envelope, can be called only after Commit(), otherwise will return nil
CommittedTxEnvelope() (proto.Message, error)
}

1) Creation of Databases

1.1) Source Code

The following is the source code to create two new databases named db1 and db2.

package main

import (
"fmt"
"strconv"
)

func main() {
db, err := createConnection()
// if err is not nil, print and return

session, err := openSession(db, "admin")
// if err is not nil, print and return

dbtx, err := session.DBsTx()
// if err is not nil, print and return

err = dbtx.CreateDB("db1", nil)
// if err is not nil, print and return

err = dbtx.CreateDB("db2", nil)
// if err is not nil, print and return

txID, receipt, err := dbtx.Commit(true)
// if err is not nil, print and return

fmt.Println("transaction with txID " + txID + " got committed in the block " + strconv.Itoa(int(receipt.GetHeader().GetBaseHeader().GetNumber())))
}

1.2) Source Code Commentary

For the sake of simplicity, not all errors are handled in this code. Further, the implementation of createConnection() and openSession() can be found here.

The session.DBsTx() starts a new database administration transaction and returns the database administration transaction context. We can then perform all administrative activities using the transaction context. The dbtx.CreateDB("db1", nil) creates the database named db1, while dbtx.CreateDB("db2", "nil") creates the database named db2. Then, the transaction is committed by calling dbtx.Commit(true). The argument true denotes that this is a synchronous submission. As a result, the Commit() returns the transaction receipt if this transaction gets committed before the TxTimeout configured in the openSession().

The structure of txReceipt can be seen [here]. The user can store this txReceipt as it is a commitment used to verify the proof generated by the server.

Refer to Check Existence of a Database in queries.

2) Creation of Database with Index Definition

2.1) Source Code

The following is the source code to create a new database named db8 with index definition.

package main

import (
"fmt"
"strconv"

"github.com/hyperledger-labs/orion-server/pkg/types"
)

func main() {
db, err := createConnection()
// if err is not nil, print and return

session, err := openSession(db, "admin")
// if err is not nil, print and return

dbtx, err := session.DBsTx()
// if err is not nil, print and return

index := map[string]types.IndexAttributeType{
"attr1": types.IndexAttributeType_BOOLEAN,
"attr2": types.IndexAttributeType_NUMBER,
"attr3": types.IndexAttributeType_STRING,
}
err = dbtx.CreateDB("db8", index)
// if err is not nil, print and return

txID, receipt, err := dbtx.Commit(true)
// if err is not nil, print and return

fmt.Println("transaction with txID " + txID + " got committed in the block " + strconv.Itoa(int(receipt.GetHeader().GetBaseHeader().GetNumber())))
}

2.2) Source Code Commentary

For the sake of simplicity, not all errors are handled in this code. Further, the implementation of createConnection() and openSession() can be found here.

The session.DBsTx() starts a new database administration transaction and returns the database administration transaction context. We can then perform all administrative activities using the transaction context. To define an index for a database to be created, first we need to create the index definition. The above code creates the following index:

    index := map[string]types.IndexAttributeType{
"attr1": types.IndexAttributeType_BOOLEAN,
"attr2": types.IndexAttributeType_NUMBER,
"attr3": types.IndexAttributeType_STRING,
}

This index dictates to the Orion server to create an index for three attributes in the JSON document stored in the database to be created. These attributes are attr1, attr2, and attr3. The type of each of these attributes are also provided in the index defintion.

Once the index is defined, the database with this index is created by calling dbtx.CreateDB("db8", index).

Finally, the transaction is committed by calling dbtx.Commit(true). The argument true denotes that this is a synchronous submission. As a result, the Commit() returns the transaction receipt if this transaction gets committed before the TxTimeout configured in the openSession().

The structure of txReceipt can be seen [here]. The user can store this txReceipt as it is a commitment used to verify the proof generated by the server.

3) Deletion of Existing Databases

3.1) Source Code

package main

import (
"fmt"
"strconv"
)

func main() {
db, err := createConnection()
// if err is not nil, print and return

session, err := openSession(db, "admin")
// if err is not nil, print and return

dbtx, err := session.DBsTx()
// if err is not nil, print and return

err = dbtx.DeleteDB("db1")
// if err is not nil, print and return

err = dbtx.DeleteDB("db2")
// if err is not nil, print and return

txID, receipt, err := dbtx.Commit(true)
// if err is not nil, print and return

fmt.Println("transaction with txID " + txID + " got committed in the block " + strconv.Itoa(int(receipt.GetHeader().GetBaseHeader().GetNumber())))
}

3.2) Source Code Commentary

For the sake of simplicity, not all errors are handled in this code. Further, the implementation of createConnection() and openSession() can be found here.

The session.DBsTx() starts a new database administration transaction and returns the database administration transaction context. We can then perform all administrative activities using the transaction context.

The dbtx.DeleteDB("db1") and dbtx.DeleteDB("db2") delete the databases db1 and db2, respectively.

Then, the transaction is committed by calling dbtx.Commit(true). The argument true denotes that this is a synchronous submission. As a result, the Commit() returns the transaction receipt if this transaction gets committed before the TxTimeout configured in the openSession().

The structure of txReceipt can be seen [here]. The user can store this txReceipt as it is a commitment used to verify the proof generated by the server.

Refer to Check Existence of a Database in queries.

Additional Examples

In addition to these examples, you can use the database administration transaction examples from the go-sdk examples folder: orion-sdk-go/examples/api/db_tx/db_tx.go