Skip to content

Instantly share code, notes, and snippets.

@mnunberg
Created September 25, 2012 15:23
Show Gist options
  • Select an option

  • Save mnunberg/3782572 to your computer and use it in GitHub Desktop.

Select an option

Save mnunberg/3782572 to your computer and use it in GitHub Desktop.
CouchbaseView.php
<?php
class CouchbaseView {
/**
* These constants are view options. They are symbolic names for string
* parameters passed as partm of the query string
*/
const VOPT_STALE = "stale";
const VOPT_START_DOCID = "startkey_docid";
const VOPT_END_DOCID = "endkey_docid";
const VOPT_START_KEY = "startkey";
const VOPT_END_KEY = "endkey";
const VOPT_INCLUSIVE_END = "inclusive_end";
const VOPT_GROUP = "group";
const VOPT_GROUP_LEVEL = "group_level";
const VOPT_ORDER_DESC = "descending";
const VOPT_LIMIT = "limit";
const VOPT_SKIP = "skip";
const VOPT_ON_ERROR = "on_error";
const VOPT_REDUCE = "reduce";
const VOPT_FULLDATASET = "full_set";
const OPT_DIE_ON_ERROR = 1;
const STALE_OK = "ok";
const STALE_UPDATE_AFTER = "update_after";
const STALE_UPDATE_FORCE = "false";
const ORDER_ASC = 1;
const ORDER_DESC = 2;
/**
* Create a new view object
* @param doc_name the name of the design document which contains the view
* @param view_name the name of the view to execute
* @param options an array of key-value options
*/
function __construct($doc_name, $view_name, $options = NULL) {
$this->doc = $doc_name;
$this->view = $view_name;
if ($options) {
$this->options = $options;
} else {
$this->options = array();
}
$this->_result_errors = NULL;
$this->_view_errors = NULL;
$this->_internal_options = array();
$this->_rows = NULL;
}
/**
* Whether to allow results from stale indices
* @param value one of the constants:
* STALE_UPDATE_AFTER, STALE_UPDATE_FORCE, STALE_OK.
* A boolean false may be used to indicate UPDATE_FORCE, and true
* to indicate OK
*/
function allowStale($value) {
$vt = gettype($value);
if ($vt == 'boolean' || $vt == 'integer') {
$this->options["stale"] = $value ? "true" : "false";
} else {
switch ($value) {
case $this::STALE_UPDATE_AFTER:
case $this::STALE_UPDATE_FORCE:
case $this::STALE_OK:
$this->options['stale'] = $value;
break;
default:
die("Bad option $value");
break;
}
}
}
static protected function _convert_keyrange($kary) {
if (gettype($kary) != 'array') {
return $kary;
}
$ret = json_encode($kary);
return $ret;
}
/**
* Set the key range
* @param start a key or an array of keys to use for the start
* @param end a key or an array of keys to use for the end
* @param inclusive whether the $end parameter is inclusive
*/
function setKeyRange($start, $end, $inclusive = false) {
if ($start != NULL) {
$this->options['startkey'] = $this->_convert_keyrange($start);
}
if ($end != NULL) {
$this->options['endkey'] = $this->_convert_keyrange($end);
}
if ($inclusive) {
$this->options['inclusive_end'] = true;
}
}
/**
* Set the Document ID range.
* @param start the docid specifying the start of the range
* @param end the docid specifying the end of the range
*/
function setIdRange($start, $end) {
if ($start != NULL) {
$this->options['startkey_docid'] = $start;
}
if ($end != NULL) {
$this->options['endkey_docid'] = $end;
}
}
/**
* Set the grouping level
* @param level the numeric level
*/
function setGroupLevel($level) {
if ($level) {
$this->options['group_level'] = $level;
$this->options['group'] = 'true';
} else {
unset($this->options['group_level']);
unset($this->options['group']);
}
}
/**
* Set the order in which the results will be returned
* @param direction either ORDER_ASC or ORDER_DESC
*/
function setOrder($direction) {
if ($direction == $this::ORDER_ASC) {
return; // default
} else if ($direction == $this::ORDER_DESC) {
$this->options['descending'] = 'true';
} else {
die("Unrecognized order preference $direction");
}
}
/**
* Set the behavior for result errors, in which there are problems processing
* some results.
* @param boolean. If set, the view aborts on the first error, otherwise
* it continues. Result errors may be obtained via calling getResultErrors()
*/
function setAbortOnError($value) {
if ($value) {
$this->options['on_error'] = 'stop';
} else {
$this->options['on_error'] = 'continue';
}
}
/**
* Set the limit on the amount of rows that may be returned
* @param num the numeric limit
*/
function setLimit($num) {
if (intval($num) <= 0) {
die ("Invalid limit (must be greater than zero");
}
$this->options['limit'] = "$num";
}
/**
* Set the amount of records by which the view should skip ahead before
* returning rows.
* @param num the amount to skip
* @param $startkey_docid The docid to skip ahead to before initiating the
* numeric skip. This is faster, but requires that the view have a
* start key set via setKeyRange
*/
function setSkip($num, $startkey_docid = NULL) {
if ($startkey_docid) {
if (!$this->options['start_key']) {
die ("startkey_docid parameter requires that " .
"setKeyRange was called");
}
$this->options['startkey_docid'] = $startkey_docid;
}
if (intval($num) <= 0) {
die ("Skip number must be greater than 0");
}
$this->options['skip'] = "$num";
}
/**
* Limit the results to the specified keys
* @param keys a single key or array of keys
*/
function setMatchKey($keys) {
if (gettype($keys) == 'array') {
$this->options['keys'] = $this->_convert_keyrange($keys);
} else {
$this->options['key'] = $keys;
}
}
function setOption($opt, $value) {
$this->_internal_options[$opt] = $value;
}
function getOption($opt) {
return $this->_internal_options[$opt];
}
/**
* Executes the query using the given handle
*
* @handle a Couchbase resource or object
* @return true if the view succeeded, false if it didn't.
* Error status may be fetched by using errorInfo
*/
function execute($handle) {
$res = NULL;
if (gettype($handle) == 'Couchbase') {
$res = $handle->view(
$this->doc,
$this->view,
$this->options,
$return_error = true);
} else {
$res = couchbase_view($handle,
$this->doc,
$this->view,
$this->options,
$return_error = true);
}
if (array_key_exists('rows', $res)) {
$this->_rows = $res['rows'];
if (array_key_exists('errors', $res)) {
$this->_result_errors = $res['errors'];
}
return true;
} else {
$this->_view_errors = $res;
return false;
}
}
/**
* Returns the last view execution error
* @return an array consisting of (http_code, error, reason).
* (http code is not yet implemented)
*/
function errorInfo() {
if ($this->_view_errors) {
return array(
0,
$this->_view_errors["error"],
$this->_view_errors["reason"]
);
} else {
return false;
}
}
function getResultErrors() {
if ($this->_result_errors) {
return $this->_result_errors;
}
return false;
}
/**
* Fetch all rows from the view
* @return an array of rows. The contents of the rows depend on the view
* parameters
*/
function fetchAll() {
if ($this->_rows) {
return $this->_rows;
} else {
return array();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment