Skip to content

Commit

Permalink
- bug fix #17,
Browse files Browse the repository at this point in the history
- columncontainer children now using slice gets (individually loadable and savable),
- +query stub
- +numeric range query clause
- dropped support for auto loading by key in constructor (must call load() explicitly). Was dieing on large data sets where colautocreate not used
- consolidated container children common methods into abstract, general cleanup
- fixed bugs encountered during tests
  • Loading branch information
mjpearson committed Mar 1, 2010
1 parent c497212 commit 8f47e87
Show file tree
Hide file tree
Showing 14 changed files with 526 additions and 292 deletions.
59 changes: 39 additions & 20 deletions lib/Column.class.php
Expand Up @@ -26,37 +26,37 @@ class PandraColumn extends cassandra_Column {
private $_delete = FALSE;

/* @var PandraColumnFamily column family parent reference */
private $_parentCF = NULL;
private $_parent = NULL;

/**
* Column constructor (extends cassandra_Column)
* @param string $name Column name
* @param PandraColumnContainer $parentCF parent column family (standard or super), or supercolumn
* @param PandraColumnContainer $parent parent column family (standard or super), or supercolumn
* @param array $typeDef validator type definitions
*/
public function __construct($name, $parentCF = NULL, $typeDef = array()) {
public function __construct($name, PandraColumnContainer $parent = NULL, $typeDef = array()) {
parent::__construct(array('name' => $name));
if ($parentCF instanceof PandraColumnContainer) {
$this->setParentCF($parentCF);
if ($parent instanceof PandraColumnContainer) {
$this->setParent($parent);
}

$this->typeDef = $typeDef;
}

/**
* Sets parent ColumnFamily or
* @param PandraColumnContainer $parentCF
* @param PandraColumnContainer $parent
*/
public function setParentCF(PandraColumnContainer $parentCF) {
$this->_parentCF = $parentCF;
public function setParent(PandraColumnContainer $parent) {
$this->_parent = $parent;
}

/**
* Gets the current working parent column family
* @return <type>
*/
public function getParentCF() {
return $this->_parentCF;
public function getParent() {
return $this->_parent;
}

/**
Expand All @@ -79,8 +79,8 @@ public function bindTime($time = NULL) {
public function setValue($value, $validate = TRUE) {
if ($validate && !empty($this->typeDef)) {
if (!PandraValidator::check($value, $this->name, $this->typeDef, $this->errors)) {
if ($this->_parentCF instanceof PandraColumnContainer) {
$this->_parentCF->errors[] = $this->errors[0];
if ($this->_parent instanceof PandraColumnContainer) {
$this->_parent->errors[] = $this->errors[0];
}
return FALSE;
}
Expand All @@ -100,13 +100,19 @@ public function callbackvalue() {
}

/**
* Casts from a cassandra_Column type, to PandraColumn
* Casts from a cassandra_ColumnOrSuperColumn->column or cassandra_Column types, to PandraColumn
* @param cassandra_Column $object source objct
* @param PandraColumnFamily $parentCF parent container
* @param PandraColumnContainer $parent parent container
* @return PandraColumn new column object
*/
static public function cast(cassandra_Column $object, $parentCF = NULL) {
$newObj = new PandraColumn($object->name, ($parentCF === NULL) ? $this->_parentCF : $parentCF);
static public function cast($object, PandraColumnContainer $parent = NULL) {
if ($object instanceof cassandra_ColumnOrSuperColumn) {
$object = $object->column;
} elseif (!($object instanceof cassandra_Column)) {
throw new RuntimeException('Cast expected cassandra_Column[OrSuperColumn], recieved '.get_class($object));
}

$newObj = new PandraColumn($object->name, ($parent === NULL) ? $this->_parent : $parent);
$newObj->value = $object->value;
$newObj->timestamp = $object->timestamp;
return $newObj;
Expand All @@ -122,7 +128,7 @@ static public function cast(cassandra_Column $object, $parentCF = NULL) {
*/
public function save($keyID, $keySpace, $columnFamily, $consistencyLevel = NULL) {

if (!$this->isModified()) return TRUE;
if (!$this->getModified()) return TRUE;

// Build the column path for modifying this individual column
$columnPath = new cassandra_ColumnPath();
Expand Down Expand Up @@ -160,7 +166,7 @@ public function save($keyID, $keySpace, $columnFamily, $consistencyLevel = NULL)
public function registerError($errorStr) {
if (!empty($errorStr)) {
array_push($this->errors, $errorStr);
if ($this->_parentCF instanceof PandraColumnContainer) $this->_parentCF->registerError($errorStr);
if ($this->_parent !== NULL) $this->_parent->registerError($errorStr);
}
}

Expand Down Expand Up @@ -191,14 +197,23 @@ public function getLastError() {
public function reset() {
$this->_modified = FALSE;
$this->_delete = FALSE;
return TRUE;
}

/**
* mutator, marks this column for deletion and sets modified
*/
public function delete() {
$this->_delete = TRUE;
$this->setModified();
$this->_modified = TRUE;
}

public function setDelete($delete) {
$this->_delete = $delete;
}

public function getDelete() {
return $this->_delete;
}

/**
Expand All @@ -209,6 +224,10 @@ public function isDeleted() {
return ($this->_delete && $this->_modified);
}

public function isModified() {
return $this->_modified;
}

/**
* Modified mutator
* @param bool $modified column is modified
Expand All @@ -221,7 +240,7 @@ public function setModified($modified = TRUE) {
* Modified accessor
* @return bool column has been modified since instance construct/load
*/
public function isModified() {
public function getModified() {
return $this->_modified;
}
}
Expand Down
103 changes: 81 additions & 22 deletions lib/ColumnContainer.class.php
Expand Up @@ -4,6 +4,9 @@
*
* For licensing terms, plese see license.txt which should distribute with this source
*
* Column Container abstract for (Super) Column Families and Super Columns, which contain our
* working columns
*
* @package Pandra
* @author Michael Pearson <pandra-support@phpgrease.net>
*/
Expand All @@ -16,6 +19,10 @@ abstract class PandraColumnContainer implements ArrayAccess {
/* @var this column families name (table name) */
protected $_name = NULL;

protected $_keyID = NULL;

protected $_keySpace = NULL;

/* @var string magic set/get prefixes for Columns */
const _columnNamePrefix = 'column_'; // magic __get/__set column prefix in column famliy

Expand Down Expand Up @@ -44,6 +51,14 @@ public function __construct() {
$this->init();
}

/**
* init is is always called by the constructor. Child classes can implement
* constructor logic, schemas, defaults validators etc. here
* @return void
*/
public function init() {
}

/**
* accessor, container name
* @return string container name
Expand All @@ -58,15 +73,28 @@ public function getName() {
*/
public function setName($name) {
$this->_name = $name;
}

public function setKeySpace($keySpace) {
$this->_keySpace = $keySpace;
}

/**
* init is is always called by the constructor. Child classes can implement
* constructor logic, schemas, defaults validators etc. here
* @return void
*/
public function init() {
public function getKeySpace() {
return $this->_keySpace;
}

public function setKeyID($keyID) {
$this->_keyID = $keyID;
}

public function getKeyID() {
return $this->_keyID;
}

public function pathOK($keyID = NULL) {
$ok = ( ($keyID !== NULL || $this->getKeyID() !== NULL) && $this->getKeySpace() !== NULL && $this->getName() !== NULL);
if (!$ok) $this->registerError('Required field (Keyspace, ColumnFamily or KeyID) not present');
return $ok;
}

/**
Expand All @@ -77,18 +105,26 @@ protected function setModified($modified = TRUE) {
$this->_modified = $modified;
}

/**
* marks the container and subcolumns (or subcontainers) for deletion
* operation cascades to columns
* @return void
*/
public function delete() {
$this->setDelete(TRUE);
foreach ($this->_columns as &$column) {
$column->delete();
}
}

/**
* mutator, marks this column for deletion and sets modified
* @param bool $delete
*/
protected function setDelete($delete) {
$this->setModified($delete);
$this->_delete = $delete;
}

public function delete() {
$this->setDelete(TRUE);
}

/**
* accessor, delete
Expand Down Expand Up @@ -192,7 +228,7 @@ public function getColumn($columnMatch) {

foreach ($this->_columns as $columnName => &$column) {
if ($columnMatch->match($columnName)) {
$container->columns[$columnName] = $column;
$container->setColumn($columnName, $column);
}
}
return $container;
Expand Down Expand Up @@ -233,14 +269,19 @@ public function listColumns() {
}

/**
* Resets deletion states for the column family
* unmarks container and subcolumns (or subcontainers) for deletion
* cascades to columns, unsets modified flag
*/
public function reset() {
// undo any deletion marks
$this->_delete = FALSE;
foreach ($this->_columns as &$cObj) {
$cObj->reset();
$this->setDelete(FALSE);
$this->setModified(FALSE);
$cReset = FALSE;
foreach ($this->_columns as &$column) {
$cReset = $column->reset();
if ($cReset == FALSE) break;
}

return (!$this->_delete && !$this->_modified && $cReset);
}

/**
Expand Down Expand Up @@ -272,8 +313,8 @@ public function getAutoCreate($override = NULL) {
* autoCreate mutator
* @param bool $autoCreate new mode
*/
public function setAutoCreate(bool $autoCreate) {
$this->$_autoCreate = $autoCreate;
public function setAutoCreate($autoCreate) {
$this->_autoCreate = $autoCreate;
}

/**
Expand All @@ -282,22 +323,25 @@ public function setAutoCreate(bool $autoCreate) {
* @return bool column values set without error
*/
public function populate($data, $colAutoCreate = NULL) {

if (is_string($data)) {
$data = json_decode($data, TRUE);
}

if (is_array($data) && count($data)) {

// Check depth, take first few keys as keyspace/columnfamily/key

foreach ($data as $idx => $colValue) {

if ($colValue instanceof cassandra_Column) {
if ($this->getAutoCreate($colAutoCreate) || array_key_exists($colValue->name, $this->_columns)) {
$this->_columns[$colValue->name] = PandraColumn::cast($colValue, $this);
}

// circular dependency?
} elseif ($colValue instanceof cassandra_ColumnOrSuperColumn && !empty($colValue->column)) {
if ($this->getAutoCreate($colAutoCreate) || array_key_exists($colValue->column->name, $this->_columns)) {
$this->_columns[$colValue->column->name] = PandraColumn::cast($colValue->column, $this);
}
} else {
$colExists = array_key_exists($idx, $this->_columns);
// Create a new named column object
Expand Down Expand Up @@ -365,6 +409,14 @@ public function __set($columnName, $value) {
}
}

protected function setLoaded($loaded) {
$this->_loaded = $loaded;
}

public function isLoaded() {
return $this->_loaded;
}

/**
* accessor, checks if container has been explicitly modified, or it sub columns
* @return <type>
Expand All @@ -376,6 +428,13 @@ public function isModified() {
return $this->_modified;
}

/**
* @return bool Column Family is marked for deletion
*/
public function isDeleted() {
return ($this->_modified && $this->_delete);
}

/**
* Binds current time to all modified columns
* @param int $timeOverride optional timestamp, will default to time() if NULL
Expand Down

1 comment on commit 8f47e87

@mjpearson
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is looking unstable and needs additional unit tests - lots of changes!

Please sign in to comment.