Skip to content

Commit 1ca29c5

Browse files
committed
PHP-139 - Support simple string queries
CQL strings should be able to be executed directly without the need to be wrapped in a `Cassandra\SimpleStatement`. Also added support to `Cassandra\BatchStatement::add()`.
1 parent f1300a2 commit 1ca29c5

File tree

7 files changed

+205
-26
lines changed

7 files changed

+205
-26
lines changed

ext/doc/Cassandra/BatchStatement.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ public function __construct($type = \Cassandra::BATCH_LOGGED) {}
4949
/**
5050
* Adds a statement to this batch.
5151
*
52-
* @param Statement $statement the statement to add
52+
* @param string|Statement $statement string or statement to add
5353
* @param array|null $arguments positional or named arguments
5454
*
5555
* @throws Exception\InvalidArgumentException
5656
*
5757
* @return BatchStatement self
5858
*/
59-
public function add(Statement $statement, array $arguments = null) {}
59+
public function add($statement, array $arguments = null) {}
6060
}

ext/doc/Cassandra/DefaultSession.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,22 @@ public function schema() {}
4444
*
4545
* @throws Exception
4646
*
47-
* @param Statement $statement statement to be executed
47+
* @param string|Statement $statement string or statement to be executed
4848
* @param ExecutionOptions $options execution options (optional)
4949
*
5050
* @return Rows execution result
5151
*/
52-
public function execute(Statement $statement, ExecutionOptions $options = null) {}
52+
public function execute($statement, ExecutionOptions $options = null) {}
5353

5454
/**
5555
* {@inheritDoc}
5656
*
57-
* @param Statement $statement statement to be executed
57+
* @param string|Statement $statement string or statement to be executed
5858
* @param ExecutionOptions|null $options execution options (optional)
5959
*
6060
* @return Future future result
6161
*/
62-
public function executeAsync(Statement $statement, ExecutionOptions $options = null) {}
62+
public function executeAsync($statement, ExecutionOptions $options = null) {}
6363

6464
/**
6565
* {@inheritDoc}

ext/doc/Cassandra/Session.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,25 +48,25 @@ public function schema();
4848
*
4949
* @throws Exception
5050
*
51-
* @param Statement $statement statement to be executed
51+
* @param string|Statement $statement string or statement to be executed
5252
* @param ExecutionOptions $options execution options (optional)
5353
*
5454
* @return Rows execution result
5555
*/
56-
public function execute(Statement $statement, ExecutionOptions $options = null);
56+
public function execute($statement, ExecutionOptions $options = null);
5757

5858
/**
5959
* Executes a given statement and returns a future result.
6060
*
6161
* Note that this method ignores timeout specified in the ExecutionOptions,
6262
* you can provide one to Future::get() instead.
6363
*
64-
* @param Statement $statement statement to be executed
64+
* @param string|Statement $statement string or statement to be executed
6565
* @param ExecutionOptions|null $options execution options (optional)
6666
*
6767
* @return Future future result
6868
*/
69-
public function executeAsync(Statement $statement, ExecutionOptions $options = null);
69+
public function executeAsync($statement, ExecutionOptions $options = null);
7070

7171
/**
7272
* Creates a prepared statement from a given CQL string.

ext/src/BatchStatement.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,13 @@ PHP_METHOD(BatchStatement, add)
7676
return;
7777
}
7878

79-
if (!instanceof_function(Z_OBJCE_P(statement), php_driver_simple_statement_ce TSRMLS_CC) &&
80-
!instanceof_function(Z_OBJCE_P(statement), php_driver_prepared_statement_ce TSRMLS_CC)) {
81-
INVALID_ARGUMENT(statement, "an instance of " PHP_DRIVER_NAMESPACE "\\SimpleStatement or " PHP_DRIVER_NAMESPACE "\\PreparedStatement");
79+
if (Z_TYPE_P(statement) != IS_STRING &&
80+
(Z_TYPE_P(statement) != IS_OBJECT ||
81+
(!instanceof_function(Z_OBJCE_P(statement), php_driver_simple_statement_ce TSRMLS_CC) &&
82+
!instanceof_function(Z_OBJCE_P(statement), php_driver_prepared_statement_ce TSRMLS_CC)))) {
83+
INVALID_ARGUMENT(statement, "a string, an instance of "
84+
PHP_DRIVER_NAMESPACE "\\SimpleStatement or an instance of "
85+
PHP_DRIVER_NAMESPACE "\\PreparedStatement");
8286
}
8387

8488
self = PHP_DRIVER_GET_STATEMENT(getThis());
@@ -91,7 +95,6 @@ PHP_METHOD(BatchStatement, add)
9195
PHP5TO7_ZVAL_COPY(PHP5TO7_ZVAL_MAYBE_P(batch_statement_entry->arguments), arguments);
9296
}
9397

94-
9598
#if PHP_MAJOR_VERSION >= 7
9699
ZVAL_PTR(&entry, batch_statement_entry);
97100
zend_hash_next_index_insert(&self->data.batch.statements, &entry);
@@ -107,7 +110,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo__construct, 0, ZEND_RETURN_VALUE, 0)
107110
ZEND_END_ARG_INFO()
108111

109112
ZEND_BEGIN_ARG_INFO_EX(arginfo_add, 0, ZEND_RETURN_VALUE, 1)
110-
PHP_DRIVER_NAMESPACE_ZEND_ARG_OBJ_INFO(0, statement, Statement, 0)
113+
ZEND_ARG_INFO(0, statement)
111114
ZEND_ARG_ARRAY_INFO(0, arguments, 1)
112115
ZEND_END_ARG_INFO()
113116

ext/src/DefaultSession.c

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -447,18 +447,30 @@ create_batch(php_driver_statement *batch,
447447

448448
php5to7_zval *current;
449449
PHP5TO7_ZEND_HASH_FOREACH_VAL(&batch->data.batch.statements, current) {
450+
php_driver_statement *statement;
451+
php_driver_statement simple_statement;
452+
HashTable *arguments;
453+
CassStatement *stmt;
454+
450455
#if PHP_MAJOR_VERSION >= 7
451456
php_driver_batch_statement_entry *batch_statement_entry = (php_driver_batch_statement_entry *)Z_PTR_P(current);
452457
#else
453458
php_driver_batch_statement_entry *batch_statement_entry = *((php_driver_batch_statement_entry **)current);
454459
#endif
455-
php_driver_statement *statement =
456-
PHP_DRIVER_GET_STATEMENT(PHP5TO7_ZVAL_MAYBE_P(batch_statement_entry->statement));
457-
HashTable *arguments
458-
= !PHP5TO7_ZVAL_IS_UNDEF(batch_statement_entry->arguments)
459-
? Z_ARRVAL_P(PHP5TO7_ZVAL_MAYBE_P(batch_statement_entry->arguments))
460-
: NULL;
461-
CassStatement *stmt = create_statement(statement, arguments TSRMLS_CC);
460+
461+
if (PHP5TO7_Z_TYPE_MAYBE_P(batch_statement_entry->statement) == IS_STRING) {
462+
simple_statement.type = PHP_DRIVER_SIMPLE_STATEMENT;
463+
simple_statement.data.simple.cql = PHP5TO7_Z_STRVAL_MAYBE_P(batch_statement_entry->statement);
464+
statement = &simple_statement;
465+
} else {
466+
statement = PHP_DRIVER_GET_STATEMENT(PHP5TO7_ZVAL_MAYBE_P(batch_statement_entry->statement));
467+
}
468+
469+
arguments = !PHP5TO7_ZVAL_IS_UNDEF(batch_statement_entry->arguments)
470+
? Z_ARRVAL_P(PHP5TO7_ZVAL_MAYBE_P(batch_statement_entry->arguments))
471+
: NULL;
472+
473+
stmt = create_statement(statement, arguments TSRMLS_CC);
462474
if (!stmt) {
463475
cass_batch_free(cass_batch);
464476
return NULL;
@@ -536,6 +548,7 @@ PHP_METHOD(DefaultSession, execute)
536548
zval *options = NULL;
537549
php_driver_session *self = NULL;
538550
php_driver_statement *stmt = NULL;
551+
php_driver_statement simple_statement;
539552
HashTable *arguments = NULL;
540553
CassConsistency consistency = PHP_DRIVER_DEFAULT_CONSISTENCY;
541554
int page_size = -1;
@@ -555,7 +568,17 @@ PHP_METHOD(DefaultSession, execute)
555568
}
556569

557570
self = PHP_DRIVER_GET_SESSION(getThis());
558-
stmt = PHP_DRIVER_GET_STATEMENT(statement);
571+
572+
if (Z_TYPE_P(statement) == IS_STRING) {
573+
simple_statement.type = PHP_DRIVER_SIMPLE_STATEMENT;
574+
simple_statement.data.simple.cql = Z_STRVAL_P(statement);
575+
stmt = &simple_statement;
576+
} else if (Z_TYPE_P(statement) == IS_OBJECT &&
577+
instanceof_function(Z_OBJCE_P(statement), php_driver_statement_ce TSRMLS_CC)) {
578+
stmt = PHP_DRIVER_GET_STATEMENT(statement);
579+
} else {
580+
INVALID_ARGUMENT(statement, "a string or an instance of " PHP_DRIVER_NAMESPACE "\\Statement");
581+
}
559582

560583
consistency = self->default_consistency;
561584
page_size = self->default_page_size;
@@ -671,6 +694,7 @@ PHP_METHOD(DefaultSession, executeAsync)
671694
zval *options = NULL;
672695
php_driver_session *self = NULL;
673696
php_driver_statement *stmt = NULL;
697+
php_driver_statement simple_statement;
674698
HashTable *arguments = NULL;
675699
CassConsistency consistency = PHP_DRIVER_DEFAULT_CONSISTENCY;
676700
int page_size = -1;
@@ -689,7 +713,17 @@ PHP_METHOD(DefaultSession, executeAsync)
689713
}
690714

691715
self = PHP_DRIVER_GET_SESSION(getThis());
692-
stmt = PHP_DRIVER_GET_STATEMENT(statement);
716+
717+
if (Z_TYPE_P(statement) == IS_STRING) {
718+
simple_statement.type = PHP_DRIVER_SIMPLE_STATEMENT;
719+
simple_statement.data.simple.cql = Z_STRVAL_P(statement);
720+
stmt = &simple_statement;
721+
} else if (Z_TYPE_P(statement) == IS_OBJECT &&
722+
instanceof_function(Z_OBJCE_P(statement), php_driver_statement_ce TSRMLS_CC)) {
723+
stmt = PHP_DRIVER_GET_STATEMENT(statement);
724+
} else {
725+
INVALID_ARGUMENT(statement, "a string or an instance of " PHP_DRIVER_NAMESPACE "\\Statement");
726+
}
693727

694728
consistency = self->default_consistency;
695729
page_size = self->default_page_size;
@@ -978,7 +1012,7 @@ PHP_METHOD(DefaultSession, schema)
9781012
}
9791013

9801014
ZEND_BEGIN_ARG_INFO_EX(arginfo_execute, 0, ZEND_RETURN_VALUE, 1)
981-
PHP_DRIVER_NAMESPACE_ZEND_ARG_OBJ_INFO(0, statement, Statement, 0)
1015+
ZEND_ARG_INFO(0, statement)
9821016
PHP_DRIVER_NAMESPACE_ZEND_ARG_OBJ_INFO(0, options, ExecutionOptions, 0)
9831017
ZEND_END_ARG_INFO()
9841018

ext/src/Session.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
zend_class_entry *php_driver_session_ce = NULL;
2020

2121
ZEND_BEGIN_ARG_INFO_EX(arginfo_execute, 0, ZEND_RETURN_VALUE, 1)
22-
PHP_DRIVER_NAMESPACE_ZEND_ARG_OBJ_INFO(0, statement, Statement, 0)
22+
ZEND_ARG_INFO(0, statement)
2323
PHP_DRIVER_NAMESPACE_ZEND_ARG_OBJ_INFO(0, options, ExecutionOptions, 0)
2424
ZEND_END_ARG_INFO()
2525

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
Feature: Simple string queries
2+
3+
PHP Driver supports running string queries.
4+
5+
Background:
6+
Given a running Cassandra cluster
7+
And the following schema:
8+
"""cql
9+
CREATE KEYSPACE simplex WITH replication = {
10+
'class': 'SimpleStrategy',
11+
'replication_factor': 1
12+
};
13+
USE simplex;
14+
CREATE TABLE playlists (
15+
id uuid,
16+
title text,
17+
album text,
18+
artist text,
19+
song_id uuid,
20+
PRIMARY KEY (id, title, album, artist)
21+
);
22+
23+
INSERT INTO playlists
24+
(id, song_id, artist, title, album) VALUES
25+
(62c36092-82a1-3a00-93d1-46196ee77204, 756716f7-2e54-4715-9f00-91dcbea6cf50, 'Joséphine Baker', 'La Petite Tonkinoise', 'Bye Bye Blackbird');
26+
27+
INSERT INTO playlists
28+
(id, song_id, artist, title, album) VALUES
29+
(62c36092-82a1-3a00-93d1-46196ee77204, f6071e72-48ec-4fcb-bf3e-379c8a696488, 'Willi Ostermann', 'Die Mösch', 'In Gold');
30+
31+
INSERT INTO playlists
32+
(id, song_id, artist, title, album) VALUES
33+
(62c36092-82a1-3a00-93d1-46196ee77204, fbdf82ed-0063-4796-9c7c-a3d4f47b4b25, 'Mick Jager', 'Memo From Turner', 'Performance');
34+
"""
35+
36+
Scenario: A simple CQL string can be used to execute queries
37+
Given the following example:
38+
"""php
39+
<?php
40+
$cluster = Cassandra::cluster()
41+
->withContactPoints('127.0.0.1')
42+
->build();
43+
$session = $cluster->connect("simplex");
44+
$result = $session->execute("SELECT * FROM playlists");
45+
46+
foreach ($result as $row) {
47+
echo $row['artist'] . ": " . $row['title'] . " / " . $row['album'] . PHP_EOL;
48+
}
49+
"""
50+
When it is executed
51+
Then its output should contain:
52+
"""
53+
Joséphine Baker: La Petite Tonkinoise / Bye Bye Blackbird
54+
"""
55+
And its output should contain:
56+
"""
57+
Willi Ostermann: Die Mösch / In Gold
58+
"""
59+
And its output should contain:
60+
"""
61+
Mick Jager: Memo From Turner / Performance
62+
"""
63+
64+
Scenario: A simple CQL string can also be used to execute asynchronous queries
65+
Given the following example:
66+
"""php
67+
<?php
68+
$cluster = Cassandra::cluster()
69+
->withContactPoints('127.0.0.1')
70+
->build();
71+
$session = $cluster->connect("simplex");
72+
$future = $session->executeAsync("SELECT * FROM playlists");
73+
74+
echo "Doing something else..." . PHP_EOL;
75+
76+
$result = $future->get();
77+
78+
foreach ($result as $row) {
79+
echo $row['artist'] . ": " . $row['title'] . " / " . $row['album'] . PHP_EOL;
80+
}
81+
"""
82+
When it is executed
83+
Then its output should contain:
84+
"""
85+
Doing something else...
86+
"""
87+
And its output should contain:
88+
"""
89+
Joséphine Baker: La Petite Tonkinoise / Bye Bye Blackbird
90+
"""
91+
And its output should contain:
92+
"""
93+
Willi Ostermann: Die Mösch / In Gold
94+
"""
95+
And its output should contain:
96+
"""
97+
Mick Jager: Memo From Turner / Performance
98+
"""
99+
100+
Scenario: Simple CQL strings can also be used in batch statements
101+
Given the following example:
102+
"""php
103+
<?php
104+
$cluster = Cassandra::cluster()
105+
->withContactPoints('127.0.0.1')
106+
->build();
107+
$session = $cluster->connect("simplex");
108+
$future = $session->executeAsync("SELECT * FROM playlists");
109+
110+
$batch = new Cassandra\BatchStatement(Cassandra::BATCH_UNLOGGED);
111+
112+
$batch->add("INSERT INTO playlists
113+
(id, song_id, artist, title, album) VALUES
114+
(3a55adfc-bbf6-43bd-9428-e714f109b977, 82a954c4-750a-4ada-8e02-6b15c9bf3140 , 'The Beatles', 'Come Together', 'Abbey Road')");
115+
$batch->add("INSERT INTO playlists
116+
(id, song_id, artist, title, album) VALUES
117+
(3a55adfc-bbf6-43bd-9428-e714f109b977, 564e3c0d-bc3b-4d2d-8a34-679bb5247b71, 'Michael Jackson', 'Thriller', 'Thriller')");
118+
$batch->add("INSERT INTO playlists
119+
(id, song_id, artist, title, album) VALUES
120+
(3a55adfc-bbf6-43bd-9428-e714f109b977, 326ead7f-4c54-43f4-9b1b-40f7ca84cd5e, 'Pink Floyd', 'Another Brick in the Wall (Part I)', 'The Wall')");
121+
122+
$session->execute($batch);
123+
124+
$result = $session->execute("SELECT * FROM playlists");
125+
126+
foreach ($result as $row) {
127+
echo $row['artist'] . ": " . $row['title'] . " / " . $row['album'] . PHP_EOL;
128+
}
129+
"""
130+
When it is executed
131+
Then its output should contain:
132+
"""
133+
The Beatles: Come Together / Abbey Road
134+
"""
135+
And its output should contain:
136+
"""
137+
Michael Jackson: Thriller / Thriller
138+
"""
139+
And its output should contain:
140+
"""
141+
Pink Floyd: Another Brick in the Wall (Part I) / The Wall
142+
"""

0 commit comments

Comments
 (0)