Manual - CQLSÍ

CQLSÍ - Cassandra Query Language Simple Interface (SÍ és per l'afirmació Sí, en Català).

Introduït a Catalonia Framework v.1.1.014 pot ser usat amb el Framework o amb el paquet mínim CQLSÍ

Què és CQLSÍ

CQLSÍ és una interfície simple, un wrapper, per a treballar amb CQL des de PHP sense Thrift.
Després de molts problemes amb Thrift, fails intentant diferent solucions de codi de tercers i compilant existents incompilables drivers PDO, i Thrift essent declarat obsolet per DataStax en favor de CQL per a Cassandra 1.2 i 2.0, etc... vaig decidir crear una manera simple, sense dolor, per a comunicar-me amb CQL mentre un mecanisme millor no aparegui en escena.
Bàsicament CQLSÍ executa cqlsh des de bash, captura la sortida i proporciona les dades a la capa d'abstracció de la classe Db del Catalonia Framework, així que passar de MySqli a Cassandra implica només canviar l'arxiu de configuració per a que usi Db::TYPE_CONNECTION_CASSANDRA_CQLSI en comptes de Db::TYPE_CONNECTION_MYSQLI o Db::TYPE_CONNECTION_POSTGRE

Pros i Contres

Els pros

Els contres:

Llançant moltes consultes de cop

Si heu d'executar diverses consultes INSERT o UPDATE de cop, les podeu agrupar en una única cadena $s_cql i salvareu el temps de connectar cada vegada.
Per exemple, aquest codi:
$s_cql_long_query = '';
for ($i_userid=3000;$i_userid<4000;$i_userid++) {
    $s_cql_long_query .= "INSERT INTO users (user_id, fname, lname, longtext) VALUES ( ".$i_userid.", 'Carles', 'X', 'whatever');";
}
$o_db_cassandra->queryWrite($s_cql_long_query);
Aquest codi crea 1.000 inserts, en el meu modest i ocupat portàtil comporta 2,9599 segons de processar aquests inserts. Això inclou tot el temps, o sigui el cost d'execució de cqlsh, el temps d'establir la connexió, el temps de processar el cql per part de Cassandra i fer les 1.000 inserts i el temps de tancar la connexió, parsejar el resultat i ensamblar la capa d'abstracció a l'array de dades.
Un insert simple triga 0,6536 segons i 10 inserts enviats com un simple $s_sql triguen 0,6992 seconds, així que el més car és llançar la comanda cqlsh, i establir la connexió.

Les consultes simultànies han de ser totes del mateix tipus: escriptura (Write). No es recomana però es pot arribar a enviar diversos INSERT seguits d'una SELECT (executar-ho com queryRead).

Instal·lació

CQLSÍ no requereix d'instal·lar res, simplement necessiteu tenir el client cqlsh instal·lat al sistema.

Això és fet típicament per a Ubuntu/Debian així:

Editar /etc/apt/sources.list i afegir:
deb http://debian.datastax.com/community stable main

Com es descriu a http://www.datastax.com/docs/1.0/install/install_deb

Afegir la key:

curl -L http://debian.datastax.com/debian/repo_key | sudo apt-key add -

Llavors instal·lar la clau cqlsh i si voleu Cassandra (però no necessiteu que corri al webserver)

sudo apt-get update
sudo apt-get install python-cql=1.0.10-1
sudo apt-get install dsc=1.0.10 cassandra=1.0.10

Mireu si hi ha actualitzacions, per si una nova versió ha estat alliberada:

sudo apt-get upgrade

Look for upgrades, just in case a new version has been releases:

sudo apt-get upgrade
Ubuntu a Amazon EC2 retornarà: The following packages have been kept back, indicant que cassandra no s'ha actualitzat.
Per a forçar la instal·lació de la versió més moderna feu:
sudo apt-get install cassandra
Si Cassandra fallà en arrencar després d'actualitzar, probablement té un probleme amb els logs de la versió antiga.
Si la vostra instal·lació és nova podeu simplement ignorar els logs i la vostra instal·lació funcionarà:
root@ip-10-10-10-10:/var/lib/cassandra/commitlog# mkdir old_logs
root@ip-10-10-10-10:/var/lib/cassandra/commitlog# mv *.log old_logs/
root@ip-10-10-10-10:/var/lib/cassandra/commitlog# service cassandra start
Prengueu en consideració que la versió de cqlsh ha de la 4.1.0 com a mínim per a funcionar amb CQLSÍ.

Probablement el vostre sistema no permet a l'usuari del webserver (www-data) crear l'arxiu d'history. Això ho necessita bash, segurament haureu de fer:

sudo mkdir /var/www/.cassandra
sudo chmod 777 /var/www/.cassandra
O similar, de manaera que bash pugui crear l'arxiu history.

Treballant amb diferents clusters / keyspaces

Podeu definir tants objectes Db com volgueu, cadascun configurat per a usar un cluster diferent o un keyspace diferent.
Preneu aquest exemple a l'arxiu init/boostrap.php :
$st_other_config1['database'] = Array(  'read'  => Array(   'servers'   => Array(0 => Array('connection_type'   => Db::TYPE_CONNECTION_CASSANDRA_CQLSI,
                                                                                            'connection_method' => Db::CONNECTION_METHOD_TCPIP,
                                                                                            'server_hostname'   => '127.0.0.1',
                                                                                            'server_port'       => Db::PORT_DEFAULT_CASSANDRA,
                                                                                            'username'          => 'www_cassandra',
                                                                                            'password'          => 'yourpassword',
                                                                                            'database'          => 'mykeyspace',
                                                                                            'client_encoding'   => 'utf8'
                                                                                            )
                                                                                )
                                                        ),
                                        'write' => Array(   'servers'   => Array(0 => Array('connection_type'   => Db::TYPE_CONNECTION_CASSANDRA_CQLSI,
                                                                                            'connection_method' => Db::CONNECTION_METHOD_TCPIP,
                                                                                            'server_hostname'   => '127.0.0.1',
                                                                                            'server_port'       => Db::PORT_DEFAULT_CASSANDRA,
                                                                                            'username'          => 'www_cassandra',
                                                                                            'password'          => 'yourpassword',
                                                                                            'database'          => 'mykeyspace',
                                                                                            'client_encoding'   => 'utf8'
                                                                                            )
                                                                                )

                                                        )
                                    );

$o_db_cassandra = new Db($st_other_config1['database']);
$s_cql = "INSERT INTO users (user_id, fname, lname, longtext) VALUES ( 1714, 'Carles', 'Mateo', 'whatever...');";
$st_result = $o_db_cassandra->queryWrite( $s_cql);
Podeu canviar de keyspace per a les següents consultes:
$o_db->setDatabaseOrKeyspace('cataloniasample', Db::CONNECTION_READ);
$o_db->setDatabaseOrKeyspace('cataloniasample', Db::CONNECTION_WRITE);
No es recomana, però es permet treballar amb un namespace diferent per a lectures i escriptures.

Per a inserir apòstrofs, que són salvats usant '' i per a evitar injeccions useu Db::prepareInsert(), per exemple:
$i_user_id = prepareInsert($i_user_id, self::DATA_TYPE_INT, self::TYPE_CONNECTION_CASSANDRA_CQLSI);
$s_fname = prepareInsert($s_fname, self::DATA_TYPE_STRING, self::TYPE_CONNECTION_CASSANDRA_CQLSI);
$s_lname = prepareInsert($s_lname, self::DATA_TYPE_STRING, self::TYPE_CONNECTION_CASSANDRA_CQLSI);
$s_longtext = prepareInsert($s_longtext, self::DATA_TYPE_STRING, self::TYPE_CONNECTION_CASSANDRA_CQLSI);
$s_cql = "INSERT INTO users (user_id, fname, lname, longtext) VALUES ( $i_user_id, '$s_fname', '$s_lname', '$s_longtext');";
$st_result = $o_db_cassandra->queryWrite($s_cql);

Treballant amb dades

Per a consultes que retornen dades, com SELECT, s'ha d'emprar $o_db->queryRead($s_cql).
Per a consultes que fan INSERT, UPDATE, ALTER..., s'ha d'emprar $o_db->queryWrite($s_cql).
Per a MySql i Postgre això té un altre significat (usar primaris o secundaris), però per a CQLSÍ és necessari pel wrapper, ja que la gestió d'errors és realitzada de manera diferent entre les modificacions de dades i per a la recuperació de dades.

El caracter Enter serà retornat com \n, de manera que tindreu una cadena com:
"Diverses\nnoves\nlínies"
El tipus de dades Null seran proporcionats com la cadena "null".
Els caracter UTF-8 tenen suport total, així accents, i d'altres caracters especials codificats per defecte amb LANG=ca_ES.UTF-8.

Examinem un exemple per a agafar dades:
$st_results = $o_db_cassandra->queryRead('SELECT * FROM users LIMIT 10;');
$i_row_num = 0;
$s_first_data = '';
if ($st_results['result']['status'] == Db::QUERY_RESULT_STATUS_EXECUTED && $st_results['result']['error'] == 0) {
    echo '<table border="1">';
    foreach($st_results['data'] as $i_row=>$st_data) {
        $i_row_num++;
        echo '<tr>';
        foreach($st_data as $s_key => $s_value) {
            if ($i_row_num == 1) {
                // Write headers
                echo '<th>'.$s_key.'</th>';
                $s_first_data .= '<td>'.$s_value.'</td>';
            } else {
                echo '<td>'.$s_value.'</td>';
            }
        }
        echo '</tr>';
        if ($i_row_num == 1) {
            echo '<tr>'.$s_first_data.'</tr>';
        }
    }
    echo '</table>';
} else {
    echo 'Error: '.$st_results['result']['error_description'];
}
Aquest codi a init/bootstrap.php produeix aquesta sortida:


En cas d'error echo 'Error: '.$st_results['result']['error_description']; serà mostrat:


Activar debug

CQLSÍ genera arxius temportals a /tmp.
Aquests arxius són .sh que s'executen i .cqlsi amb les comandes a enviar a cqlsh.
Si necessiteu debugar i veure l'error exacte que obteniu, podeu indicar a CQLSÍ no esborrar aquests arxius després de l'ús.

Per exemple:
$s_cql = "CREATE TABLE IF NOT EXISTS test (userid int,
                                           firstname text,
                                           lastname text,
                                           tele set<text>,
                                           emails set<text>,
                                           skills list<text>,
                                           todos map<timestamp,text>,
                     PRIMARY KEY (userid) );";

$o_db_cassandra->setKeepCqlFiles(true);

$st_result = $o_db_cassandra->queryWrite($s_cql);

Errors comuns

Tornar a la plana principal del Manual