Adding the Cassandra DB support to AppWrite

If you're building a PHP application that requires a NoSQL database, Cassandra is a popular choice due to its scalability and high availability. In this blog post, we'll take a look at the Cassandra class, which is a database adapter that provides a simple API for interacting with Cassandra databases from PHP.

Step 1: Installing the Cassandra extension

Before we can use the Cassandra class, we need to make sure that the Cassandra extension is installed in our PHP environment. If you're using a package manager like Composer, you can install the extension by adding it to your composer.json file:

{
    "require": {
        "datastax/php-driver": "^1.7"
    }
}

Alternatively, you can install the extension manually by following the instructions in the official DataStax PHP Driver for Apache Cassandra documentation.

Step 2: Creating a database connection

To interact with a Cassandra database, we first need to create a connection. We can do this by creating a new instance of the Cassandra class and passing in the connection options:

use Utopia\Database\Adapter\Cassandra;

$options = [
    'hosts' => ['localhost'],
    'username' => 'cassandra',
    'password' => 'cassandra',
];

try {
    $db = new Cassandra($options);
} catch (Exception $e) {
    // Handle connection error
}

In this example, we're passing in an array of options that includes the hostname of the Cassandra cluster, as well as the username and password for authentication. If the connection fails, an exception is thrown, which we can catch and handle accordingly.

Step 3: Retrieving data from a collection

Once we have a database connection, we can retrieve data from a collection using the getDocument() and getDocuments() methods. The getDocument() method retrieves a single document by ID, while the getDocuments() method retrieves a collection of documents based on a query:

$document = $db->getDocument('my_collection', '123');

$documents = $db->getDocuments('my_collection', new Query([
    ['field', '=', 'value'],
]));

In both cases, we're passing in the name of the collection as the first argument. For getDocument(), we're also passing in the ID of the document we want to retrieve. For getDocuments(), we're passing in a Query object that specifies the conditions for the query.

Step 4: Saving data to a collection

To save data to a collection, we can use the saveDocument() method:

$document = new Document('123', ['field' => 'value']);

$db->saveDocument('my_collection', $document);

In this example, we're creating a new Document object with an ID of 123 and some data. We're then passing this object to the saveDocument() method, along with the name of the collection. The document will be inserted into the collection, and if a document with the same ID already exists, a Duplicate exception will be thrown.

Step 5: Updating data in a collection

To update data in a collection, we can use the saveDocument() method with the $replace parameter set to true:

$document = $db->getDocument('my_collection', '123');

$document->setData(['field' => 'new_value']);

$db->saveDocument('my_collection', $document, true);

In this example, we're retrieving a document from the collection, updating its data, and then saving the document back to the collection with the $replace parameter set to true. This will replace the existing document with the updated data.

Step 6: Deleting data from a collection

To delete data from a collection, we can use the deleteDocument() method:

$db->deleteDocument('my_collection', '123');

In this example, we're passing in the name of the collection and the ID of the document we want to delete. The document will be removed from the collection.

Step 7: Handling exceptions

Finally, it's important to handle exceptions that may be thrown by the Cassandra class. In addition to the Duplicate exception that can be thrown when trying to insert a document with a duplicate ID, the class may also throw a Timeout exception if a query times out, or a generic Exception if any other error occurs:

try {
    // Use Cassandra class methods
} catch (Duplicate $e) {
    // Handle duplicate exception
} catch (Timeout $e) {
    // Handle timeout exception
} catch (Exception $e) {
    // Handle generic exception
}

By catching and handling these exceptions, we can make our application more robust and handle errors gracefully.