intermaterium / cassandra-native
A native Apache Cassandra and ScyllaDB connector for PHP based on the CQL binary protocol with support for persistent connections
Package info
github.com/chrisBirmingham/Cassandra-Native
pkg:composer/intermaterium/cassandra-native
Requires
- php: >=8.2
Requires (Dev)
None
Suggests
- ext-lz4: Required for enabling compression between Cassandra
Provides
None
Conflicts
None
Replaces
None
README
A native Apache Cassandra and ScyllaDB connector for PHP applications using the CQL binary protocol (v4), without the need for an external extension.
Requires PHP version >=8.2, Cassandra >1.2, and any ScyllaDB version.
Much of the API is built to emulate the Datastax PHP Driver.
Original work by Uri Hartmann
Installation
$ composer require intermaterium/cassandra-native
Features
- Simple and Prepared Statements
- SSL Encryption
- Persistent Connections
- Compression via LZ4.
- Authentication
- Tuples and User Defined Types
Missing Features
- Batch Statements
- Async queries
- Result Paging
Usage
Cluster
A Cassandra cluster can be built via the ClusterBuilder class.
By default, the Cluster will try to connect to localhost.
$clusterBuilder = new \CassandraNative\Cluster\ClusterBuilder(); $cassandra = $clusterBuilder->build();
You can specify a set of IP/hostnames to connect to using the
withContactPoints method.
The client will attempt to connect to one of the contact points
at random. If the connection fails, it will try another host until
all contact points have been attempted or max connection attempts,
configured with the withMaxConnectionAttempts method,
has been reached, the default is 3 attempts. If the client cannot connect to
any of the provided hosts an NoHostsAvailableException is thrown.
$clusterBuilder = new \CassandraNative\Cluster\ClusterBuilder(); $clusterBuilder->withContactPoints(['1.0.0.0', '2.0.0.0']); $cassandra = $clusterBuilder->build();
When connecting, the created Cassandra instance doesn't connect to
a specific keyspace. Calling connect on the created Cassandra
instance is the same as performing a USE $keyspace query against
the connection.
$cassandra->connect('system');
SSL
You can enable SSL Encryption via the SSLBuilder class and
pass the result of a call to the build method to the withSSL
method of a cluster builder instance.
$sslBuilder = new \CassandraNative\SSL\SSLBuilder(); $sslBuilder ->withClientCert(__DIR__ . '/certs/localhost.cer') ->withPrivateKey(__DIR__ . '/certs/localhost.key.pem'); ->withTrustedCerts(__DIR__ . '/certs/localhost.cer.pem'); $clusterBuilder->withSSL($sslBuilder->build());
Compression
Compression can be enabled by calling the withCompression method
on the cluster builder.
$clusterBuilder->withCompression(true);
When enabled, the client checks to see if the LZ4 PHP extension is loaded. If the extension is not loaded, an exception is thrown.
Authentication
Authentication can be enabled by providing an Authentication Provider
to the cluster build via the withCredentials method. Included in this library
is the PasswordAuthenticator provider which accepts a plaintext username
and password combo.
$authProvider = new \CassandraNative\Auth\PasswordAuthenticator('cassandra', 'cassandra'); $clusterBuilder->withCredentials($authProvider);
For other SASL based authentication methods you'll need to provide/use your
own implementation. This can be done by creating a class which implements the
AuthProviderInterface.
<?php class KeberosProvider implements \CassandraNative\Auth\AuthProviderInterface { public function mechanism(): string { return 'java class name'; } public function response(): string { return 'i am an initial response'; } }
The mechanism method returns the fully qualified name of the java class
cassandra is configured to use. This name can be found in the authenticator.class_name
directive of the cassandra.yaml config.
The response method is called when the first auth challenge is issued. Some
auth providers will only require sending this response.
For auth providers that require responding to subsequent authentication challenges
the AuthChallengeProvderInterface is provided. This interface provides the challengeResponse
method. This method accepts an token parameter which contains the binary representation
of a token sent back from the Cassandra node describing how to respond to the auth
challenge.
If a provider does not implement the AuthChallengeProviderInterface and an auth
challenge is issued after the first response, an AuthenticationException is thrown.
Statements
The client currently only supports two types of statements, Simple
and Prepared. Both types of statement are executed via the execute method
on the Cassandra instance. The execute method accepts the statement, an optional
array of values to bind to parameters and an optional consistency level which
overrides the default consistency.
The execute method returns a Rows class which implements the ArrayAccess and
Iterator interfaces.
Simple Statements
Simple statements use the SimpleStatement class.
$stmt = new \CassandraNative\Statement\SimpleStatement('DESCRIBE TABLES'); $rows = $cassandra->execute($stmt);
Simple statements support parameterised values.
$stmt = new \CassandraNative\Statement\SimpleStatement('SELECT col1, col2, col3 FROM my_table WHERE id=?') $rows = $cassandra->execute( $stmt, [ [1001, Cassandra::ColumnType::Bigint] ] ); // Or $stmt = new \CassandraNative\Statement\SimpleStatement('SELECT col1, col2, col3 FROM my_table WHERE id=:id') $rows = $cassandra->execute( $stmt, [ 'id' => [1001, Cassandra::ColumnType::Bigint] ] );
You must specify the bound parameters type when using a simple statement. These
types are available in Cassandra::ColumnType enum.
- Note, container types i.e. Map, Lists etc are not supported for simple statements.
Prepared Statements
Prepared Statements are created via the prepare method on the Cassandra instance.
$stmt = $cassandra->prepare('UPDATE my_table SET col2=?,col3=? WHERE col1=?'); $values = ['col2' => 5, 'col3' => '0x55', 'col1' => 'five']; $rows = $cassandra->execute($stmt, $values);
Unlike Simple Statements, you don't need to specify the bound values type.
External links
-
Datastax's blog introducing the binary protocol: http://www.datastax.com/dev/blog/binary-protocol
-
CQL definitions https://cassandra.apache.org/doc/latest/cassandra/reference/native-protocol.html#native-protocol-version-4