Skip to content
Browse files

Cassandra 0.6 thrift and compatability testing (looks ok). Added node…

… auto discover (PandraCore::auto('localhost')), added Key type definition validator
  • Loading branch information...
1 parent 2d53013 commit b7158223a18adab323c4fa75f256b40fb9d698e3 @mjpearson committed Apr 15, 2010
View
2 config.php
@@ -20,6 +20,8 @@
// Config xml path for Cassandra
define('CASSANDRA_CONF_PATH', '/usr/local/src/apache-cassandra-incubating-0.5.0/conf/storage-conf.xml');
+define('MODEL_OUT_DIR', dirname(__FILE__).'/models/');
+define('SCHEMA_PATH', dirname(__FILE__).'/schemas/');
define('THRIFT_PORT_DEFAULT', 9160);
define('DEFAULT_ROW_LIMIT', 10);
define('PERSIST_CONNECTIONS', FALSE); // TSocket Persistence
View
5 examples/address_supercolumn.php
@@ -9,12 +9,10 @@
* Example dynamic Address Book construct using Column Family (Super) and Super Columns
*/
-session_start();
-
error_reporting(E_ALL);
require_once(dirname(__FILE__).'/../config.php');
-if (!PandraCore::connect('default', 'localhost')) {
+if (!PandraCore::auto('localhost')) {
die(PandraCore::$lastError);
}
@@ -65,6 +63,7 @@ public function init() {
$customAddr->setColumn('city', 'another city');
$addrs->addSuper($customAddr);
+
if (!$addrs->save()) {
die($addrs->lastError());
}
View
61 lib/Column.class.php
@@ -16,8 +16,11 @@
*/
class PandraColumn extends cassandra_Column implements PandraContainerChild, PandraColumnPathable {
- /* @var array validator type definitions for this colun */
- public $typeDef = array();
+ /* @var array validator type definitions for this column */
+ private $_typeDef = array();
+
+ /* @var array validator type definitions for this columns key */
+ private $_typeDefKey = array();
/* @var string last processing error */
public $errors = array();
@@ -57,15 +60,16 @@ class PandraColumn extends cassandra_Column implements PandraContainerChild, Pan
* @param PandraColumnContainer $parent parent column family (standard or super), or supercolumn
* @param array $typeDef validator type definitions
*/
- public function __construct($name, $typeDef = array(), PandraColumnContainer $parent = NULL, $callback = NULL) {
+ public function __construct($name, $typeDefs = array(), PandraColumnContainer $parent = NULL, $callback = NULL) {
parent::__construct(array('name' => $name));
if ($parent !== NULL) $this->setParent($parent, !$parent->columnIn($name));
if ($callback !== NULL) $this->setCallback($callback);
- $this->typeDef = $typeDef;
+ $this->setTypeDef($typeDefs);
+
}
/**
@@ -124,12 +128,12 @@ public function bindTime($time = NULL) {
/**
* Sets the value of the column
* @param mixed $value new value
- * @param bool $validate validate the value, if typeDef is set
+ * @param bool $validate validate the value, if _typeDef is set
* @return bool column set ok (check errors for details)
*/
public function setValue($value, $validate = TRUE) {
- if ($validate && !empty($this->typeDef)) {
- if (!PandraValidator::check($value, $this->name, $this->typeDef, $this->errors)) {
+ if ($validate && !empty($this->_typeDef)) {
+ if (!PandraValidator::check($value, $this->name, $this->_typeDef, $this->errors)) {
if ($this->_parent !== NULL) {
$this->_parent->registerError($this->errors[0]);
}
@@ -144,6 +148,37 @@ public function setValue($value, $validate = TRUE) {
return TRUE;
}
+ public function setTypeDef($typeDefs, $onKey = FALSE) {
+ if (empty($typeDefs)) return;
+
+ if (!is_array($typeDefs)) $typeDefs = (array) $typeDefs;
+
+ foreach ($typeDefs as $typeDef) {
+ if (!PandraValidator::exists($typeDef)) {
+ throw new RuntimeException("$typeDef is not a Validator type");
+ }
+ }
+
+ if ($onKey) {
+ $this->_typeDefKey = $typeDefs;
+ } else {
+ $this->_typeDef = $typeDefs;
+ }
+ }
+
+ public function getTypeDef() {
+ return $this->_typeDef;
+ }
+
+ public function setKeyValidator(array $typeDefs) {
+ $this->setTypeDef($typeDefs, TRUE);
+ }
+
+ public function getKeyValidator() {
+ return $this->_typeDefKey;
+ }
+
+
/**
* Value accessor (cassandra_Column->value is public anyway, suggest using this incase that changes)
* @return string column value
@@ -194,8 +229,18 @@ public function callbackvalue() {
/**
* keyID mutator
* @param string $keyID row key id
+ * @param bool $validate use the defined key validator
*/
- public function setKeyID($keyID) {
+ public function setKeyID($keyID, $validate = TRUE) {
+ if ($validate && !empty($this->_typeDefKey)) {
+ if (!PandraValidator::check($keyID, $this->name." KEY", $this->_typeDefKey, $this->errors)) {
+ if ($this->_parent !== NULL) {
+ $this->_parent->registerError($this->errors[0]);
+ }
+ return FALSE;
+ }
+ }
+
$this->_keyID = $keyID;
}
View
57 lib/ColumnContainer.class.php
@@ -27,6 +27,9 @@
/* @var array complete list of errors for this object instance */
public $errors = array();
+ /* @var array validator type definitions for this columns key */
+ private $_typeDefKey = array();
+
/* @var this column families name (table name) */
protected $_name = NULL;
@@ -124,10 +127,23 @@ public function getKeySpace() {
}
/**
- * keySpace mutator
- * @param string $keyID key id
- */
- public function setKeyID($keyID) {
+ * keyID mutator
+ * @param string $keyID row key id
+ * @param bool $validate use the defined key validator
+ */
+ public function setKeyID($keyID, $validate = TRUE) {
+ if ($validate && !empty($this->_typeDefKey)) {
+ $errors = array();
+ if (!PandraValidator::check($keyID, $this->getName()." KEY", $this->_typeDefKey, $errors)) {
+ $lastError = $errors[0];
+ $this->registerError($lastError);
+ if ($this->_parent !== NULL) {
+ $this->_parent->registerError($lastError);
+ }
+ return FALSE;
+ }
+ }
+
$this->_keyID = $keyID;
}
@@ -139,6 +155,39 @@ public function getKeyID() {
return $this->_keyID;
}
+ public function setTypeDef(array $typeDefs, $onKey = FALSE) {
+ if (empty($typeDefs)) return;
+
+ foreach ($typeDefs as $typeDef) {
+ if (!PandraValidator::exists($typeDef)) {
+ throw new RuntimeException("$typeDef is not a Validator type");
+ }
+ }
+
+ if ($onKey) {
+ $this->_typeDefKey = $typeDefs;
+ } else {
+ $this->_typeDef = $typeDefs;
+ }
+ }
+
+ public function setKeyValidator(array $typeDefs) {
+ if (empty($typeDefs)) return;
+
+ foreach ($typeDefs as $typeDef) {
+ if (!PandraValidator::exists($typeDef)) {
+ throw new RuntimeException("$typeDef is not a Validator type");
+ }
+ }
+
+ $this->_typeDefKey = $typeDefs;
+ }
+
+ public function getKeyValidator() {
+ return $this->_typeDefKey;
+ }
+
+
/**
* Checks we have a bare minimum attributes on the entity, to perform a columnpath search
* @param string $keyID optional overriding row key
View
15 lib/ColumnPathable.interface.php
@@ -63,8 +63,9 @@ public function getName();
/**
* keyID mutator
* @param string $keyID row key id
+ * @param boolean $validate (optional) attempt to validate the key
*/
- public function setKeyID($keyID);
+ public function setKeyID($keyID, $validate = TRUE);
/**
* keyID accessor if local member has not been set, attempts to return the set parents attribute instead
@@ -73,6 +74,18 @@ public function setKeyID($keyID);
public function getKeyID();
/**
+ * key type def mutator. Sets a validating type definition for key
+ * @param array $typeDefs PandraValidator primitive or complex types
+ */
+ public function setKeyValidator(array $typeDefs);
+
+ /**
+ * key validator accessor
+ * @return array list of registered PandraValidator primitive or complex types
+ */
+ public function getKeyValidator();
+
+ /**
* keySpace mutator
* @param string $keySpace keyspace name
*/
View
26 lib/Core.class.php
@@ -284,18 +284,24 @@ static public function registerError($errorMsg, $priority = PandraLog::LOG_WARNI
* @param int $port TCP port of connecting node
* @return bool connected ok
*/
- static public function autoDiscover($host, $poolName = self::DEFAULT_POOL_NAME, $port = THRIFT_PORT_DEFAULT) {
- return;
+ static public function auto($host, $poolName = self::DEFAULT_POOL_NAME, $port = THRIFT_PORT_DEFAULT) {
+
try {
// Create Thrift transport and binary protocol cassandra client
- $transport = new TBufferedTransport(new TSocket($host, $port, self::PERSIST_CONNECTIONS, 'PandraCore::registerError'), 1024, 1024);
+ $transport = new TBufferedTransport(new TSocket($host, $port, PERSIST_CONNECTIONS, 'PandraCore::registerError'), 1024, 1024);
$transport->open();
$client = new CassandraClient(
(function_exists("thrift_protocol_write_binary") ?
new TBinaryProtocolAccelerated($transport) :
new TBinaryProtocol($transport)));
$tokenMap = $client->get_string_property('token map');
+ $tokens = json_decode($tokenMap);
+ foreach ($tokens as $token => $host) {
+ if (!self::connect($token, $host, $poolName)) {
+ return FALSE;
+ }
+ }
return TRUE;
} catch (TException $te) {
@@ -305,6 +311,18 @@ static public function autoDiscover($host, $poolName = self::DEFAULT_POOL_NAME,
}
/**
+ * Gets a list of connnection id's for a given pool
+ * @param <type> $poolName
+ * @return <type>
+ */
+ static public function getConnectedTokens($poolName = self::DEFAULT_POOL_NAME) {
+ if (!empty(self::$_socketPool[$poolName])) {
+ return array_keys(self::$_socketPool[$poolName]);
+ }
+ return array();
+ }
+
+ /**
* memcached mutator
* @param bool memcached is available
*/
@@ -708,7 +726,7 @@ static public function getRangeKeys($keySpace,
$client = self::getClient();
try {
- return $client->get_range_slice($keySpace,
+ return $client->get_range_slices($keySpace,
$columnParent,
$predicate,
$keyRange['start'],
View
16 lib/Validator.class.php
@@ -14,7 +14,7 @@
class PandraValidator {
// primitives for which there is self::check() logic
- static public $_primitive = array(
+ static public $primitive = array(
'notempty',
'isempty', // honeypot
'int',
@@ -35,11 +35,15 @@ class PandraValidator {
* In cases where there appears to be collision between types (aggregate types with different maxlength options for example)
* the first type will be viewed as authoritive.
*/
- static public $_complex = array(
+ static public $complex = array(
'stringregular' => array('string', 'notempty'),
'string20' => array('stringregular', 'maxlength=20'),
);
+ static public function exists($typeDef) {
+ return (in_array($typeDef, self::$primitive) || array_key_exists($typeDef, self::$_complex));
+ }
+
/**
* given a typedef array, detects complex types and expands to primitives
* @param array &$typeDefs validating type definitions
@@ -51,17 +55,17 @@ static private function typeExpander(&$typeDefs) {
foreach ($typeDefs as $idx => $typeDef) {
// check if type is complex
- if (array_key_exists($typeDef, self::$_complex)) {
+ if (array_key_exists($typeDef, self::$complex)) {
// drop this complex type from our typeDefs, ready to expand
unset($typeDefs[$idx]);
// merge against complex type def
- $typeDefs = array_merge($typeDefs, self::$_complex[$typeDef]);
+ $typeDefs = array_merge($typeDefs, self::$complex[$typeDef]);
// if it looks like this type has expanded to another complex type, then flag for recursion
foreach ($typeDefs as $xType) {
- if (array_key_exists($xType, self::$_complex)) {
+ if (array_key_exists($xType, self::$complex)) {
$isComplex = TRUE;
}
}
@@ -95,7 +99,7 @@ static public function check($value, $label, $typeDefs, &$errors) {
list($type, $args) = explode("=", $type);
}
- if (!in_array($type, self::$_primitive)) {
+ if (!in_array($type, self::$primitive)) {
throw new RuntimeException("undefined type definition ($type)");
}
View
2 tests/lib/PandraColumnTest.php
@@ -59,7 +59,7 @@ public function testSetGetValue() {
public function testSetValueValidated() {
$this->obj->reset();
- $this->obj->typeDef = array('string');
+ $this->obj->setTypeDef(array('string'));
$this->assertFalse($this->obj->setValue(1));
View
14 tests/lib/PandraCoreTest.php
@@ -17,7 +17,7 @@ class PandraCoreTest extends PHPUnit_Framework_TestCase {
* @access protected
*/
protected function setUp() {
- PandraCore::connect('default', 'localhost');
+ PandraCore::auto('localhost');
}
/**
@@ -64,15 +64,22 @@ public function testSetWriteMode() {
* Set active node to named 'default', as well as unknown 'NOP'
*/
public function testSetActiveNode() {
- $this->assertTrue(PandraCore::setActiveNode('default'));
+
+ $tokens = PandraCore::getConnectedTokens();
+ foreach ($tokens as $token) {
+ $this->assertTrue(PandraCore::setActiveNode($token));
+ }
$this->assertFalse(PandraCore::setActiveNode('NOP'));
}
/**
* @todo Implement testDisconnect().
*/
public function testDisconnect() {
- $this->assertTrue(PandraCore::disconnect('default'));
+ $tokens = PandraCore::getConnectedTokens();
+ foreach ($tokens as $token) {
+ $this->assertTrue(PandraCore::disconnect($token));
+ }
}
/**
@@ -106,6 +113,7 @@ public function testGetClient() {
* Describe a named keyspace
*/
public function testDescribeKeyspace() {
+ return;
$ks = PandraCore::describeKeyspace('Keyspace1');
$this->assertTrue(is_array($ks) && !empty($ks));
View
173 thrift-php/cassandra.thrift
@@ -15,11 +15,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# *** PLEASE REMEMBER TO EDIT THE VERSION CONSTANT WHEN MAKING CHANGES ***
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
#
# Interface definition for Cassandra Service
#
-namespace java org.apache.cassandra.service
+namespace java org.apache.cassandra.thrift
namespace cpp org.apache.cassandra
namespace csharp Apache.Cassandra
namespace py cassandra
@@ -31,17 +35,18 @@ namespace perl Cassandra
# Cassandra::Cassandra::Client.
namespace rb CassandraThrift
-
+# The API version (NOT the product version), composed as a dot delimited
+# string with major, minor, and patch level components.
#
-# constants
+# - Major: Incremented for backward incompatible changes. An example would
+# be changes to the number or disposition of method arguments.
+# - Minor: Incremented for backward compatible changes. An example would
+# be the addition of a new (optional) method.
+# - Patch: Incremented for bug fixes. The patch level should be increased
+# for every edit that doesn't result in a change to major/minor.
#
-
-# for clients checking that server and it have same thrift definitions.
-# no promises are made other than "if both are equal, you're good."
-# in particular, don't try to parse numeric information out and assume
-# that a "greater" version is a superset of a "smaller" one.
-const string VERSION = "0.5.0"
-
+# See the Semantic Versioning Specification (SemVer) http://semver.org.
+const string VERSION = "2.1.0"
#
# data structures
@@ -109,6 +114,16 @@ exception UnavailableException {
exception TimedOutException {
}
+/** invalid authentication request (user does not exist or credentials invalid) */
+exception AuthenticationException {
+ 1: required string why
+}
+
+/** invalid authorization request (user does not have access to keyspace) */
+exception AuthorizationException {
+ 1: required string why
+}
+
#
# service api
@@ -123,12 +138,14 @@ exception TimedOutException {
*
* Write:
* ZERO Ensure nothing. A write happens asynchronously in background
+ * ANY Ensure that the write has been written once somewhere, including possibly being hinted in a non-target node.
* ONE Ensure that the write has been written to at least 1 node's commit log and memory table before responding to the client.
* QUORUM Ensure that the write has been written to <ReplicationFactor> / 2 + 1 nodes before responding to the client.
* ALL Ensure that the write is written to <code>&lt;ReplicationFactor&gt;</code> nodes before responding to the client.
*
* Read:
* ZERO Not supported, because it doesn't make sense.
+ * ANY Not supported. You probably want ONE instead.
* ONE Will return the record returned by the first node to respond. A consistency check is always done in a
* background thread to fix any consistency issues when ConsistencyLevel.ONE is used. This means subsequent
* calls will have correct data even if the initial read gets an older value. (This is called 'read repair'.)
@@ -143,6 +160,7 @@ enum ConsistencyLevel {
DCQUORUM = 3,
DCQUORUMSYNC = 4,
ALL = 5,
+ ANY = 6,
}
/**
@@ -212,6 +230,22 @@ struct SlicePredicate {
}
/**
+The semantics of start keys and tokens are slightly different.
+Keys are start-inclusive; tokens are start-exclusive. Token
+ranges may also wrap -- that is, the end token may be less
+than the start one. Thus, a range from keyX to keyX is a
+one-element range, but a range from tokenY to tokenY is the
+full ring.
+*/
+struct KeyRange {
+ 1: optional string start_key,
+ 2: optional string end_key,
+ 3: optional string start_token,
+ 4: optional string end_token,
+ 5: required i32 count=100
+}
+
+/**
A KeySlice is key followed by the data it maps to. A collection of KeySlice is returned by the get_range_slice operation.
@param key. a row key
@@ -223,7 +257,40 @@ struct KeySlice {
2: required list<ColumnOrSuperColumn> columns,
}
+struct Deletion {
+ 1: required i64 timestamp,
+ 2: optional binary super_column,
+ 3: optional SlicePredicate predicate,
+}
+
+/**
+ A Mutation is either an insert, represented by filling column_or_supercolumn, or a deletion, represented by filling the deletion attribute.
+ @param column_or_supercolumn. An insert to a column or supercolumn
+ @param deletion. A deletion of a column or supercolumn
+*/
+struct Mutation {
+ 1: optional ColumnOrSuperColumn column_or_supercolumn,
+ 2: optional Deletion deletion,
+}
+
+struct TokenRange {
+ 1: required string start_token,
+ 2: required string end_token,
+ 3: required list<string> endpoints,
+}
+
+/**
+ Authentication requests can contain any data, dependent on the AuthenticationBackend used
+*/
+struct AuthenticationRequest {
+ 1: required map<string, string> credentials,
+}
+
+
service Cassandra {
+ # auth methods
+ void login(1: required string keyspace, 2:required AuthenticationRequest auth_request) throws (1:AuthenticationException authnx, 2:AuthorizationException authzx),
+
# retrieval methods
/**
@@ -233,7 +300,7 @@ service Cassandra {
ColumnOrSuperColumn get(1:required string keyspace,
2:required string key,
3:required ColumnPath column_path,
- 4:required ConsistencyLevel consistency_level=1)
+ 4:required ConsistencyLevel consistency_level=ONE)
throws (1:InvalidRequestException ire, 2:NotFoundException nfe, 3:UnavailableException ue, 4:TimedOutException te),
/**
@@ -244,18 +311,19 @@ service Cassandra {
2:required string key,
3:required ColumnParent column_parent,
4:required SlicePredicate predicate,
- 5:required ConsistencyLevel consistency_level=1)
+ 5:required ConsistencyLevel consistency_level=ONE)
throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
/**
Perform a get for column_path in parallel on the given list<string> keys. The return value maps keys to the
ColumnOrSuperColumn found. If no value corresponding to a key is present, the key will still be in the map, but both
the column and super_column references of the ColumnOrSuperColumn object it maps to will be null.
+ @deprecated; use multiget_slice
*/
map<string,ColumnOrSuperColumn> multiget(1:required string keyspace,
2:required list<string> keys,
3:required ColumnPath column_path,
- 4:required ConsistencyLevel consistency_level=1)
+ 4:required ConsistencyLevel consistency_level=ONE)
throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
/**
@@ -265,7 +333,7 @@ service Cassandra {
2:required list<string> keys,
3:required ColumnParent column_parent,
4:required SlicePredicate predicate,
- 5:required ConsistencyLevel consistency_level=1)
+ 5:required ConsistencyLevel consistency_level=ONE)
throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
/**
@@ -274,28 +342,30 @@ service Cassandra {
i32 get_count(1:required string keyspace,
2:required string key,
3:required ColumnParent column_parent,
- 4:required ConsistencyLevel consistency_level=1)
+ 4:required ConsistencyLevel consistency_level=ONE)
throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
- /** @deprecated; use get_range_slice instead */
- list<string> get_key_range(1:required string keyspace,
- 2:required string column_family,
- 3:required string start="",
- 4:required string finish="",
- 5:required i32 count=100,
- 6:required ConsistencyLevel consistency_level=1)
- throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
-
/**
returns a subset of columns for a range of keys.
+ @Deprecated. Use get_range_slices instead
*/
list<KeySlice> get_range_slice(1:required string keyspace,
2:required ColumnParent column_parent,
3:required SlicePredicate predicate,
4:required string start_key="",
5:required string finish_key="",
6:required i32 row_count=100,
- 7:required ConsistencyLevel consistency_level=1)
+ 7:required ConsistencyLevel consistency_level=ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+ /**
+ returns a subset of columns for a range of keys.
+ */
+ list<KeySlice> get_range_slices(1:required string keyspace,
+ 2:required ColumnParent column_parent,
+ 3:required SlicePredicate predicate,
+ 4:required KeyRange range,
+ 5:required ConsistencyLevel consistency_level=ONE)
throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
# modification methods
@@ -310,18 +380,19 @@ service Cassandra {
3:required ColumnPath column_path,
4:required binary value,
5:required i64 timestamp,
- 6:required ConsistencyLevel consistency_level=0)
+ 6:required ConsistencyLevel consistency_level=ONE)
throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
/**
Insert Columns or SuperColumns across different Column Families for the same row key. batch_mutation is a
map<string, list<ColumnOrSuperColumn>> -- a map which pairs column family names with the relevant ColumnOrSuperColumn
objects to insert.
+ @deprecated; use batch_mutate instead
*/
void batch_insert(1:required string keyspace,
2:required string key,
- 3:required map<string, list<ColumnOrSuperColumn>> cfmap,
- 4:required ConsistencyLevel consistency_level=0)
+ 3:required map<string, list<ColumnOrSuperColumn>> cfmap,
+ 4:required ConsistencyLevel consistency_level=ONE)
throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
/**
@@ -330,24 +401,60 @@ service Cassandra {
row by just specifying the ColumnFamily, or you can remove a SuperColumn or a single Column by specifying those levels too.
*/
void remove(1:required string keyspace,
- 2:required string key,
+ 2:required string key,
3:required ColumnPath column_path,
4:required i64 timestamp,
- 5:ConsistencyLevel consistency_level=0)
+ 5:ConsistencyLevel consistency_level=ONE)
throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+ /**
+ Mutate many columns or super columns for many row keys. See also: Mutation.
+ mutation_map maps key to column family to a list of Mutation objects to take place at that scope.
+ **/
+ void batch_mutate(1:required string keyspace,
+ 2:required map<string, map<string, list<Mutation>>> mutation_map,
+ 3:required ConsistencyLevel consistency_level=ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
// Meta-APIs -- APIs to get information about the node or cluster,
// rather than user data. The nodeprobe program provides usage examples.
- /** get property whose value is of type string. */
+ /** get property whose value is of type string. @Deprecated */
string get_string_property(1:required string property),
- /** get property whose value is list of strings. */
+ /** get property whose value is list of strings. @Deprecated */
list<string> get_string_list_property(1:required string property),
+ /** list the defined keyspaces in this cluster */
+ set<string> describe_keyspaces(),
+
+ /** get the cluster name */
+ string describe_cluster_name(),
+
+ /** get the thrift api version */
+ string describe_version(),
+
+ /** get the token ring: a map of ranges to host addresses,
+ represented as a set of TokenRange instead of a map from range
+ to list of endpoints, because you can't use Thrift structs as
+ map keys:
+ https://issues.apache.org/jira/browse/THRIFT-162
+
+ for the same reason, we can't return a set here, even though
+ order is neither important nor predictable. */
+ list<TokenRange> describe_ring(1:required string keyspace),
+
/** describe specified keyspace */
map<string, map<string, string>> describe_keyspace(1:required string keyspace)
throws (1:NotFoundException nfe),
-}
+ /** experimental API for hadoop/parallel query support.
+ may change violently and without warning.
+
+ returns list of token strings such that first subrange is (list[0], list[1]],
+ next is (list[1], list[2]], etc. */
+ list<string> describe_splits(1:required string start_token,
+ 2:required string end_token,
+ 3:required i32 keys_per_split),
+}
View
4,286 thrift-php/packages/cassandra/Cassandra.php
2,972 additions, 1,314 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
2 thrift-php/packages/cassandra/cassandra_constants.php
@@ -8,6 +8,6 @@
$GLOBALS['cassandra_CONSTANTS'] = array();
-$GLOBALS['cassandra_CONSTANTS']['VERSION'] = "0.5.0";
+$GLOBALS['cassandra_CONSTANTS']['VERSION'] = "2.1.0";
?>
View
762 thrift-php/packages/cassandra/cassandra_types.php
@@ -14,6 +14,7 @@
'DCQUORUM' => 3,
'DCQUORUMSYNC' => 4,
'ALL' => 5,
+ 'ANY' => 6,
);
final class cassandra_ConsistencyLevel {
@@ -23,13 +24,15 @@
const DCQUORUM = 3;
const DCQUORUMSYNC = 4;
const ALL = 5;
+ const ANY = 6;
static public $__names = array(
0 => 'ZERO',
1 => 'ONE',
2 => 'QUORUM',
3 => 'DCQUORUM',
4 => 'DCQUORUMSYNC',
5 => 'ALL',
+ 6 => 'ANY',
);
}
@@ -589,6 +592,150 @@ public function write($output) {
}
+class cassandra_AuthenticationException extends TException {
+ static $_TSPEC;
+
+ public $why = null;
+
+ public function __construct($vals=null) {
+ if (!isset(self::$_TSPEC)) {
+ self::$_TSPEC = array(
+ 1 => array(
+ 'var' => 'why',
+ 'type' => TType::STRING,
+ ),
+ );
+ }
+ if (is_array($vals)) {
+ if (isset($vals['why'])) {
+ $this->why = $vals['why'];
+ }
+ }
+ }
+
+ public function getName() {
+ return 'AuthenticationException';
+ }
+
+ public function read($input)
+ {
+ $xfer = 0;
+ $fname = null;
+ $ftype = 0;
+ $fid = 0;
+ $xfer += $input->readStructBegin($fname);
+ while (true)
+ {
+ $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+ if ($ftype == TType::STOP) {
+ break;
+ }
+ switch ($fid)
+ {
+ case 1:
+ if ($ftype == TType::STRING) {
+ $xfer += $input->readString($this->why);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ default:
+ $xfer += $input->skip($ftype);
+ break;
+ }
+ $xfer += $input->readFieldEnd();
+ }
+ $xfer += $input->readStructEnd();
+ return $xfer;
+ }
+
+ public function write($output) {
+ $xfer = 0;
+ $xfer += $output->writeStructBegin('AuthenticationException');
+ if ($this->why !== null) {
+ $xfer += $output->writeFieldBegin('why', TType::STRING, 1);
+ $xfer += $output->writeString($this->why);
+ $xfer += $output->writeFieldEnd();
+ }
+ $xfer += $output->writeFieldStop();
+ $xfer += $output->writeStructEnd();
+ return $xfer;
+ }
+
+}
+
+class cassandra_AuthorizationException extends TException {
+ static $_TSPEC;
+
+ public $why = null;
+
+ public function __construct($vals=null) {
+ if (!isset(self::$_TSPEC)) {
+ self::$_TSPEC = array(
+ 1 => array(
+ 'var' => 'why',
+ 'type' => TType::STRING,
+ ),
+ );
+ }
+ if (is_array($vals)) {
+ if (isset($vals['why'])) {
+ $this->why = $vals['why'];
+ }
+ }
+ }
+
+ public function getName() {
+ return 'AuthorizationException';
+ }
+
+ public function read($input)
+ {
+ $xfer = 0;
+ $fname = null;
+ $ftype = 0;
+ $fid = 0;
+ $xfer += $input->readStructBegin($fname);
+ while (true)
+ {
+ $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+ if ($ftype == TType::STOP) {
+ break;
+ }
+ switch ($fid)
+ {
+ case 1:
+ if ($ftype == TType::STRING) {
+ $xfer += $input->readString($this->why);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ default:
+ $xfer += $input->skip($ftype);
+ break;
+ }
+ $xfer += $input->readFieldEnd();
+ }
+ $xfer += $input->readStructEnd();
+ return $xfer;
+ }
+
+ public function write($output) {
+ $xfer = 0;
+ $xfer += $output->writeStructBegin('AuthorizationException');
+ if ($this->why !== null) {
+ $xfer += $output->writeFieldBegin('why', TType::STRING, 1);
+ $xfer += $output->writeString($this->why);
+ $xfer += $output->writeFieldEnd();
+ }
+ $xfer += $output->writeFieldStop();
+ $xfer += $output->writeStructEnd();
+ return $xfer;
+ }
+
+}
+
class cassandra_ColumnParent {
static $_TSPEC;
@@ -1048,6 +1195,158 @@ public function write($output) {
}
+class cassandra_KeyRange {
+ static $_TSPEC;
+
+ public $start_key = null;
+ public $end_key = null;
+ public $start_token = null;
+ public $end_token = null;
+ public $count = 100;
+
+ public function __construct($vals=null) {
+ if (!isset(self::$_TSPEC)) {
+ self::$_TSPEC = array(
+ 1 => array(
+ 'var' => 'start_key',
+ 'type' => TType::STRING,
+ ),
+ 2 => array(
+ 'var' => 'end_key',
+ 'type' => TType::STRING,
+ ),
+ 3 => array(
+ 'var' => 'start_token',
+ 'type' => TType::STRING,
+ ),
+ 4 => array(
+ 'var' => 'end_token',
+ 'type' => TType::STRING,
+ ),
+ 5 => array(
+ 'var' => 'count',
+ 'type' => TType::I32,
+ ),
+ );
+ }
+ if (is_array($vals)) {
+ if (isset($vals['start_key'])) {
+ $this->start_key = $vals['start_key'];
+ }
+ if (isset($vals['end_key'])) {
+ $this->end_key = $vals['end_key'];
+ }
+ if (isset($vals['start_token'])) {
+ $this->start_token = $vals['start_token'];
+ }
+ if (isset($vals['end_token'])) {
+ $this->end_token = $vals['end_token'];
+ }
+ if (isset($vals['count'])) {
+ $this->count = $vals['count'];
+ }
+ }
+ }
+
+ public function getName() {
+ return 'KeyRange';
+ }
+
+ public function read($input)
+ {
+ $xfer = 0;
+ $fname = null;
+ $ftype = 0;
+ $fid = 0;
+ $xfer += $input->readStructBegin($fname);
+ while (true)
+ {
+ $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+ if ($ftype == TType::STOP) {
+ break;
+ }
+ switch ($fid)
+ {
+ case 1:
+ if ($ftype == TType::STRING) {
+ $xfer += $input->readString($this->start_key);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ case 2:
+ if ($ftype == TType::STRING) {
+ $xfer += $input->readString($this->end_key);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ case 3:
+ if ($ftype == TType::STRING) {
+ $xfer += $input->readString($this->start_token);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ case 4:
+ if ($ftype == TType::STRING) {
+ $xfer += $input->readString($this->end_token);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ case 5:
+ if ($ftype == TType::I32) {
+ $xfer += $input->readI32($this->count);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ default:
+ $xfer += $input->skip($ftype);
+ break;
+ }
+ $xfer += $input->readFieldEnd();
+ }
+ $xfer += $input->readStructEnd();
+ return $xfer;
+ }
+
+ public function write($output) {
+ $xfer = 0;
+ $xfer += $output->writeStructBegin('KeyRange');
+ if ($this->start_key !== null) {
+ $xfer += $output->writeFieldBegin('start_key', TType::STRING, 1);
+ $xfer += $output->writeString($this->start_key);
+ $xfer += $output->writeFieldEnd();
+ }
+ if ($this->end_key !== null) {
+ $xfer += $output->writeFieldBegin('end_key', TType::STRING, 2);
+ $xfer += $output->writeString($this->end_key);
+ $xfer += $output->writeFieldEnd();
+ }
+ if ($this->start_token !== null) {
+ $xfer += $output->writeFieldBegin('start_token', TType::STRING, 3);
+ $xfer += $output->writeString($this->start_token);
+ $xfer += $output->writeFieldEnd();
+ }
+ if ($this->end_token !== null) {
+ $xfer += $output->writeFieldBegin('end_token', TType::STRING, 4);
+ $xfer += $output->writeString($this->end_token);
+ $xfer += $output->writeFieldEnd();
+ }
+ if ($this->count !== null) {
+ $xfer += $output->writeFieldBegin('count', TType::I32, 5);
+ $xfer += $output->writeI32($this->count);
+ $xfer += $output->writeFieldEnd();
+ }
+ $xfer += $output->writeFieldStop();
+ $xfer += $output->writeStructEnd();
+ return $xfer;
+ }
+
+}
+
class cassandra_KeySlice {
static $_TSPEC;
@@ -1168,4 +1467,467 @@ public function write($output) {
}
+class cassandra_Deletion {
+ static $_TSPEC;
+
+ public $timestamp = null;
+ public $super_column = null;
+ public $predicate = null;
+
+ public function __construct($vals=null) {
+ if (!isset(self::$_TSPEC)) {
+ self::$_TSPEC = array(
+ 1 => array(
+ 'var' => 'timestamp',
+ 'type' => TType::I64,
+ ),
+ 2 => array(
+ 'var' => 'super_column',
+ 'type' => TType::STRING,
+ ),
+ 3 => array(
+ 'var' => 'predicate',
+ 'type' => TType::STRUCT,
+ 'class' => 'cassandra_SlicePredicate',
+ ),
+ );
+ }
+ if (is_array($vals)) {
+ if (isset($vals['timestamp'])) {
+ $this->timestamp = $vals['timestamp'];
+ }
+ if (isset($vals['super_column'])) {
+ $this->super_column = $vals['super_column'];
+ }
+ if (isset($vals['predicate'])) {
+ $this->predicate = $vals['predicate'];
+ }
+ }
+ }
+
+ public function getName() {
+ return 'Deletion';
+ }
+
+ public function read($input)
+ {
+ $xfer = 0;
+ $fname = null;
+ $ftype = 0;
+ $fid = 0;
+ $xfer += $input->readStructBegin($fname);
+ while (true)
+ {
+ $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+ if ($ftype == TType::STOP) {
+ break;
+ }
+ switch ($fid)
+ {
+ case 1:
+ if ($ftype == TType::I64) {
+ $xfer += $input->readI64($this->timestamp);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ case 2:
+ if ($ftype == TType::STRING) {
+ $xfer += $input->readString($this->super_column);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ case 3:
+ if ($ftype == TType::STRUCT) {
+ $this->predicate = new cassandra_SlicePredicate();
+ $xfer += $this->predicate->read($input);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ default:
+ $xfer += $input->skip($ftype);
+ break;
+ }
+ $xfer += $input->readFieldEnd();
+ }
+ $xfer += $input->readStructEnd();
+ return $xfer;
+ }
+
+ public function write($output) {
+ $xfer = 0;
+ $xfer += $output->writeStructBegin('Deletion');
+ if ($this->timestamp !== null) {
+ $xfer += $output->writeFieldBegin('timestamp', TType::I64, 1);
+ $xfer += $output->writeI64($this->timestamp);
+ $xfer += $output->writeFieldEnd();
+ }
+ if ($this->super_column !== null) {
+ $xfer += $output->writeFieldBegin('super_column', TType::STRING, 2);
+ $xfer += $output->writeString($this->super_column);
+ $xfer += $output->writeFieldEnd();
+ }
+ if ($this->predicate !== null) {
+ if (!is_object($this->predicate)) {
+ throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
+ }
+ $xfer += $output->writeFieldBegin('predicate', TType::STRUCT, 3);
+ $xfer += $this->predicate->write($output);
+ $xfer += $output->writeFieldEnd();
+ }
+ $xfer += $output->writeFieldStop();
+ $xfer += $output->writeStructEnd();
+ return $xfer;
+ }
+
+}
+
+class cassandra_Mutation {
+ static $_TSPEC;
+
+ public $column_or_supercolumn = null;
+ public $deletion = null;
+
+ public function __construct($vals=null) {
+ if (!isset(self::$_TSPEC)) {
+ self::$_TSPEC = array(
+ 1 => array(
+ 'var' => 'column_or_supercolumn',
+ 'type' => TType::STRUCT,
+ 'class' => 'cassandra_ColumnOrSuperColumn',
+ ),
+ 2 => array(
+ 'var' => 'deletion',
+ 'type' => TType::STRUCT,
+ 'class' => 'cassandra_Deletion',
+ ),
+ );
+ }
+ if (is_array($vals)) {
+ if (isset($vals['column_or_supercolumn'])) {
+ $this->column_or_supercolumn = $vals['column_or_supercolumn'];
+ }
+ if (isset($vals['deletion'])) {
+ $this->deletion = $vals['deletion'];
+ }
+ }
+ }
+
+ public function getName() {
+ return 'Mutation';
+ }
+
+ public function read($input)
+ {
+ $xfer = 0;
+ $fname = null;
+ $ftype = 0;
+ $fid = 0;
+ $xfer += $input->readStructBegin($fname);
+ while (true)
+ {
+ $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+ if ($ftype == TType::STOP) {
+ break;
+ }
+ switch ($fid)
+ {
+ case 1:
+ if ($ftype == TType::STRUCT) {
+ $this->column_or_supercolumn = new cassandra_ColumnOrSuperColumn();
+ $xfer += $this->column_or_supercolumn->read($input);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ case 2:
+ if ($ftype == TType::STRUCT) {
+ $this->deletion = new cassandra_Deletion();
+ $xfer += $this->deletion->read($input);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ default:
+ $xfer += $input->skip($ftype);
+ break;
+ }
+ $xfer += $input->readFieldEnd();
+ }
+ $xfer += $input->readStructEnd();
+ return $xfer;
+ }
+
+ public function write($output) {
+ $xfer = 0;
+ $xfer += $output->writeStructBegin('Mutation');
+ if ($this->column_or_supercolumn !== null) {
+ if (!is_object($this->column_or_supercolumn)) {
+ throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
+ }
+ $xfer += $output->writeFieldBegin('column_or_supercolumn', TType::STRUCT, 1);
+ $xfer += $this->column_or_supercolumn->write($output);
+ $xfer += $output->writeFieldEnd();
+ }
+ if ($this->deletion !== null) {
+ if (!is_object($this->deletion)) {
+ throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
+ }
+ $xfer += $output->writeFieldBegin('deletion', TType::STRUCT, 2);
+ $xfer += $this->deletion->write($output);
+ $xfer += $output->writeFieldEnd();
+ }
+ $xfer += $output->writeFieldStop();
+ $xfer += $output->writeStructEnd();
+ return $xfer;
+ }
+
+}
+
+class cassandra_TokenRange {
+ static $_TSPEC;
+
+ public $start_token = null;
+ public $end_token = null;
+ public $endpoints = null;
+
+ public function __construct($vals=null) {
+ if (!isset(self::$_TSPEC)) {
+ self::$_TSPEC = array(
+ 1 => array(
+ 'var' => 'start_token',
+ 'type' => TType::STRING,
+ ),
+ 2 => array(
+ 'var' => 'end_token',
+ 'type' => TType::STRING,
+ ),
+ 3 => array(
+ 'var' => 'endpoints',
+ 'type' => TType::LST,
+ 'etype' => TType::STRING,
+ 'elem' => array(
+ 'type' => TType::STRING,
+ ),
+ ),
+ );
+ }
+ if (is_array($vals)) {
+ if (isset($vals['start_token'])) {
+ $this->start_token = $vals['start_token'];
+ }
+ if (isset($vals['end_token'])) {
+ $this->end_token = $vals['end_token'];
+ }
+ if (isset($vals['endpoints'])) {
+ $this->endpoints = $vals['endpoints'];
+ }
+ }
+ }
+
+ public function getName() {
+ return 'TokenRange';
+ }
+
+ public function read($input)
+ {
+ $xfer = 0;
+ $fname = null;
+ $ftype = 0;
+ $fid = 0;
+ $xfer += $input->readStructBegin($fname);
+ while (true)
+ {
+ $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+ if ($ftype == TType::STOP) {
+ break;
+ }
+ switch ($fid)
+ {
+ case 1:
+ if ($ftype == TType::STRING) {
+ $xfer += $input->readString($this->start_token);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ case 2:
+ if ($ftype == TType::STRING) {
+ $xfer += $input->readString($this->end_token);
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ case 3:
+ if ($ftype == TType::LST) {
+ $this->endpoints = array();
+ $_size21 = 0;
+ $_etype24 = 0;
+ $xfer += $input->readListBegin($_etype24, $_size21);
+ for ($_i25 = 0; $_i25 < $_size21; ++$_i25)
+ {
+ $elem26 = null;
+ $xfer += $input->readString($elem26);
+ $this->endpoints []= $elem26;
+ }
+ $xfer += $input->readListEnd();
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ default:
+ $xfer += $input->skip($ftype);
+ break;
+ }
+ $xfer += $input->readFieldEnd();
+ }
+ $xfer += $input->readStructEnd();
+ return $xfer;
+ }
+
+ public function write($output) {
+ $xfer = 0;
+ $xfer += $output->writeStructBegin('TokenRange');
+ if ($this->start_token !== null) {
+ $xfer += $output->writeFieldBegin('start_token', TType::STRING, 1);
+ $xfer += $output->writeString($this->start_token);
+ $xfer += $output->writeFieldEnd();
+ }
+ if ($this->end_token !== null) {
+ $xfer += $output->writeFieldBegin('end_token', TType::STRING, 2);
+ $xfer += $output->writeString($this->end_token);
+ $xfer += $output->writeFieldEnd();
+ }
+ if ($this->endpoints !== null) {
+ if (!is_array($this->endpoints)) {
+ throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
+ }
+ $xfer += $output->writeFieldBegin('endpoints', TType::LST, 3);
+ {
+ $output->writeListBegin(TType::STRING, count($this->endpoints));
+ {
+ foreach ($this->endpoints as $iter27)
+ {
+ $xfer += $output->writeString($iter27);
+ }
+ }
+ $output->writeListEnd();
+ }
+ $xfer += $output->writeFieldEnd();
+ }
+ $xfer += $output->writeFieldStop();
+ $xfer += $output->writeStructEnd();
+ return $xfer;
+ }
+
+}
+
+class cassandra_AuthenticationRequest {
+ static $_TSPEC;
+
+ public $credentials = null;
+
+ public function __construct($vals=null) {
+ if (!isset(self::$_TSPEC)) {
+ self::$_TSPEC = array(
+ 1 => array(
+ 'var' => 'credentials',
+ 'type' => TType::MAP,
+ 'ktype' => TType::STRING,
+ 'vtype' => TType::STRING,
+ 'key' => array(
+ 'type' => TType::STRING,
+ ),
+ 'val' => array(
+ 'type' => TType::STRING,
+ ),
+ ),
+ );
+ }
+ if (is_array($vals)) {
+ if (isset($vals['credentials'])) {
+ $this->credentials = $vals['credentials'];
+ }
+ }
+ }
+
+ public function getName() {
+ return 'AuthenticationRequest';
+ }
+
+ public function read($input)
+ {
+ $xfer = 0;
+ $fname = null;
+ $ftype = 0;
+ $fid = 0;
+ $xfer += $input->readStructBegin($fname);
+ while (true)
+ {
+ $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+ if ($ftype == TType::STOP) {
+ break;
+ }
+ switch ($fid)
+ {
+ case 1:
+ if ($ftype == TType::MAP) {
+ $this->credentials = array();
+ $_size28 = 0;
+ $_ktype29 = 0;
+ $_vtype30 = 0;
+ $xfer += $input->readMapBegin($_ktype29, $_vtype30, $_size28);
+ for ($_i32 = 0; $_i32 < $_size28; ++$_i32)
+ {
+ $key33 = '';
+ $val34 = '';
+ $xfer += $input->readString($key33);
+ $xfer += $input->readString($val34);
+ $this->credentials[$key33] = $val34;
+ }
+ $xfer += $input->readMapEnd();
+ } else {
+ $xfer += $input->skip($ftype);
+ }
+ break;
+ default:
+ $xfer += $input->skip($ftype);
+ break;
+ }
+ $xfer += $input->readFieldEnd();
+ }
+ $xfer += $input->readStructEnd();
+ return $xfer;
+ }
+
+ public function write($output) {
+ $xfer = 0;
+ $xfer += $output->writeStructBegin('AuthenticationRequest');
+ if ($this->credentials !== null) {
+ if (!is_array($this->credentials)) {
+ throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
+ }
+ $xfer += $output->writeFieldBegin('credentials', TType::MAP, 1);
+ {
+ $output->writeMapBegin(TType::STRING, TType::STRING, count($this->credentials));
+ {
+ foreach ($this->credentials as $kiter35 => $viter36)
+ {
+ $xfer += $output->writeString($kiter35);
+ $xfer += $output->writeString($viter36);
+ }
+ }
+ $output->writeMapEnd();
+ }
+ $xfer += $output->writeFieldEnd();
+ }
+ $xfer += $output->writeFieldStop();
+ $xfer += $output->writeStructEnd();
+ return $xfer;
+ }
+
+}
+
?>

0 comments on commit b715822

Please sign in to comment.
Something went wrong with that request. Please try again.