Database Administration Transaction
The database administration transaction can be used for
- Creation of new databases without index
- Creation of a new database with index definition
- Deletion of existing databases
Note that all database administration transactions must be submitted by the admin.
Prerequisite
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