Overview

Namespaces

  • cassandra
  • None
  • PHP
  • phpcassa
    • Batch
    • Connection
    • Index
    • Iterator
    • Schema
      • DataType
    • Util
    • UUID

Classes

  • AbstractColumnFamily
  • ColumnFamily
  • ColumnSlice
  • SuperColumnFamily
  • SystemManager
  • UUID
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: namespace phpcassa;
  3: 
  4: use phpcassa\Connection\ConnectionWrapper;
  5: use phpcassa\Schema\DataType;
  6: 
  7: use cassandra\KsDef;
  8: use cassandra\CfDef;
  9: use cassandra\ColumnDef;
 10: use cassandra\IndexType;
 11: 
 12: /**
 13:  * Helps with getting information about the schema, making
 14:  * schema changes, and getting information about the state
 15:  * and configuration of the cluster.
 16:  *
 17:  * @package phpcassa
 18:  */
 19: class SystemManager {
 20: 
 21:     /** @internal */
 22:     const KEEP = "<__keep__>";
 23: 
 24:     /**
 25:      * @param string $server the host and port to connect to, in the
 26:      *        form 'host:port'. Defaults to 'localhost:9160'.
 27:      * @param array $credentials if using authentication or authorization with Cassandra,
 28:      *        a username and password need to be supplied. This should be in the form
 29:      *        array("username" => username, "password" => password)
 30:      * @param int $send_timeout the socket send timeout in milliseconds. Defaults to 15000.
 31:      * @param int $recv_timeout the socket receive timeout in milliseconds. Defaults to 15000.
 32:      */
 33:     public function __construct($server='localhost:9160',
 34:                                 $credentials=NULL,
 35:                                 $send_timeout=15000,
 36:                                 $recv_timeout=15000)
 37:     {
 38:         $this->conn = new ConnectionWrapper(
 39:             NULL, $server, $credentials, True,
 40:             $send_timeout, $recv_timeout);
 41:         $this->client = $this->conn->client;
 42:     }
 43: 
 44:     /**
 45:      * Closes the underlying Thrift connection.
 46:      */
 47:     public function close() {
 48:         $this->conn->close();
 49:     }
 50: 
 51:     protected function wait_for_agreement() {
 52:         while (true) {
 53:             $versions = $this->client->describe_schema_versions();
 54:             if (count($versions) == 1)
 55:                 break;
 56:             usleep(500);
 57:         }
 58:     }
 59: 
 60:     /**
 61:      * Creates a new keyspace.
 62:      *
 63:      * Example usage:
 64:      * <code>
 65:      * use phpcassa\SystemManager;
 66:      * use phpcassa\Schema\StrategyClass;
 67:      *
 68:      * $sys = SystemManager();
 69:      * $attrs = array("strategy_class" => StrategyClass\SIMPLE_STRATEGY,
 70:      *                "strategy_options" => array("replication_factor" => "1"));
 71:      * $sys->create_keyspace("Keyspace1", $attrs);
 72:      * </code>
 73:      *
 74:      * @param string $keyspace the keyspace name
 75:      * @param array $attrs an array that maps attribute
 76:      *        names to values. Valid attribute names include
 77:      *        "strategy_class", "strategy_options", and
 78:      *        "replication_factor".
 79:      *
 80:      *        By default, SimpleStrategy will be used with a replication
 81:      *        factor of 1 and no strategy options.
 82:      *
 83:      */
 84:     public function create_keyspace($keyspace, $attrs) {
 85:         $ksdef = $this->make_ksdef($keyspace, $attrs);
 86:         $this->client->system_add_keyspace($ksdef);
 87:         $this->wait_for_agreement();
 88:     }
 89: 
 90:     /**
 91:      * Modifies a keyspace's properties.
 92:      *
 93:      * Example usage:
 94:      * <code>
 95:      * $sys = SystemManager();
 96:      * $attrs = array("replication_factor" => 2);
 97:      * $sys->alter_keyspace("Keyspace1", $attrs);
 98:      * </code>
 99:      *
100:      * @param string $keyspace the keyspace to modify
101:      * @param array $attrs an array that maps attribute
102:      *        names to values. Valid attribute names include
103:      *        "strategy_class", "strategy_options", and
104:      *        "replication_factor".
105:      *
106:      */
107:     public function alter_keyspace($keyspace, $attrs) {
108:         $ksdef = $this->client->describe_keyspace($keyspace);
109:         $ksdef = $this->make_ksdef($keyspace, $attrs, $ksdef);
110:         $this->client->system_update_keyspace($ksdef);
111:         $this->wait_for_agreement();
112:     }
113: 
114:     /*
115:      * Drops a keyspace.
116:      *
117:      * @param string $keyspace the keyspace name
118:      */
119:     public function drop_keyspace($keyspace) {
120:         $this->client->system_drop_keyspace($keyspace);
121:         $this->wait_for_agreement();
122:     }
123: 
124:     protected static function endswith($haystack, $needle) {
125:         $start  = strlen($needle) * -1; //negative
126:         return (substr($haystack, $start) === $needle);
127:     }
128: 
129:     protected function make_ksdef($name, $attrs, $orig=NULL) {
130:         if ($orig !== NULL) {
131:             $ksdef = $orig;
132:         } else {
133:             $ksdef = new KsDef();
134:             $ksdef->strategy_class = 'SimpleStrategy';
135:             $ksdef->strategy_options = array("replication_factor" => "1");
136:         }
137: 
138:         $ksdef->name = $name;
139:         $ksdef->cf_defs = array();
140:         foreach ($attrs as $attr => $value) {
141:             if ($attr == "strategy_class") {
142:                 if (strpos($value, ".") === false)
143:                     $value = "org.apache.cassandra.locator.$value";
144:                 $ksdef->strategy_class = $value;
145:             } else {
146:                 $ksdef->$attr = $value;
147:             }
148:         }
149:         return $ksdef;
150:     }
151: 
152:     /**
153:      * Creates a column family.
154:      *
155:      * Example usage:
156:      * <code>
157:      * $sys = SystemManager();
158:      * $attrs = array("column_type" => "Standard",
159:      *                "comparator_type" => "org.apache.cassandra.db.marshal.AsciiType",
160:      *                "memtable_throughput_in_mb" => 32);
161:      * $sys->create_column_family("Keyspace1", "ColumnFamily1", $attrs);
162:      * </code>
163:      *
164:      * @param string $keyspace the keyspace containing the column family
165:      * @param string $column_family the name of the column family
166:      * @param array $attrs an array that maps attribute
167:      *        names to values.
168:      */
169:     public function create_column_family($keyspace, $column_family, $attrs=null) {
170:         if ($attrs === null)
171:             $attrs = array();
172: 
173:         $this->client->set_keyspace($keyspace);
174:         $cfdef = $this->make_cfdef($keyspace, $column_family, $attrs);
175:         $this->client->system_add_column_family($cfdef);
176:         $this->wait_for_agreement();
177:     }
178: 
179:     protected function get_cfdef($ksname, $cfname) {
180:         $ksdef = $this->client->describe_keyspace($ksname);
181:         $cfdefs = $ksdef->cf_defs;
182:         foreach($cfdefs as $cfdef) {
183:             if ($cfdef->name == $cfname)
184:                 return $cfdef;
185:         }
186:         return;
187:     }
188: 
189:     protected function make_cfdef($ksname, $cfname, $attrs, $orig=NULL) {
190:         if ($orig !== NULL) {
191:             $cfdef = $orig;
192:         } else {
193:             $cfdef = new CfDef();
194:             $cfdef->column_type = "Standard";
195:         }
196: 
197:         $cfdef->keyspace = $ksname;
198:         $cfdef->name = $cfname;
199: 
200:         foreach ($attrs as $attr => $value)
201:             $cfdef->$attr = $value;
202: 
203:         return $cfdef;
204:     }
205: 
206:     /**
207:      * Modifies a column family's attributes.
208:      *
209:      * Example usage:
210:      * <code>
211:      * $sys = SystemManager();
212:      * $attrs = array("max_compaction_threshold" => 10);
213:      * $sys->alter_column_family("Keyspace1", "ColumnFamily1", $attrs);
214:      * </code>
215:      *
216:      * @param string $keyspace the keyspace containing the column family
217:      * @param string $column_family the name of the column family
218:      * @param array $attrs an array that maps attribute
219:      *        names to values.
220:      */
221:     public function alter_column_family($keyspace, $column_family, $attrs) {
222:         $cfdef = $this->get_cfdef($keyspace, $column_family);
223:         $cfdef = $this->make_cfdef($keyspace, $column_family, $attrs, $cfdef);
224:         $this->client->set_keyspace($cfdef->keyspace);
225:         $this->client->system_update_column_family($cfdef);
226:         $this->wait_for_agreement();
227:     }
228: 
229:     /*
230:      * Drops a column family from a keyspace.
231:      *
232:      * @param string $keyspace the keyspace the CF is in
233:      * @param string $column_family the column family name
234:      */
235:     public function drop_column_family($keyspace, $column_family) {
236:         $this->client->set_keyspace($keyspace);
237:         $this->client->system_drop_column_family($column_family);
238:         $this->wait_for_agreement();
239:     }
240: 
241:     /**
242:      * Mark the entire column family as deleted.
243:      *
244:      * From the user's perspective a successful call to truncate will result
245:      * complete data deletion from cfname. Internally, however, disk space
246:      * will not be immediatily released, as with all deletes in cassandra,
247:      * this one only marks the data as deleted.
248:      *
249:      * The operation succeeds only if all hosts in the cluster at available
250:      * and will throw an UnavailableException if some hosts are down.
251:      *
252:      * Example usage:
253:      * <code>
254:      * $sys = SystemManager();
255:      * $sys->truncate_column_family("Keyspace1", "ColumnFamily1");
256:      * </code>
257:      *
258:      * @param string $keyspace the keyspace the CF is in
259:      * @param string $column_family the column family name
260:      */
261:     public function truncate_column_family($keyspace, $column_family) {
262:         $this->client->set_keyspace($keyspace);
263:         $this->client->truncate($column_family);
264:     }
265: 
266:     /**
267:      * Adds an index to a column family.
268:      *
269:      * Example usage:
270:      *
271:      * <code>
272:      * $sys = new SystemManager();
273:      * $sys->create_index("Keyspace1", "Users", "name", "UTF8Type");
274:      * </code>
275:      *
276:      * @param string $keyspace the name of the keyspace containing the column family
277:      * @param string $column_family the name of the column family
278:      * @param string $column the name of the column to put the index on
279:      * @param string $data_type the data type of the values being indexed
280:      * @param string $index_name an optional name for the index
281:      * @param IndexType $index_type the type of index. Defaults to
282:      *        \cassandra\IndexType::KEYS_INDEX, which is currently the only option.
283:      */
284:     public function create_index($keyspace, $column_family, $column,
285:         $data_type=self::KEEP, $index_name=NULL, $index_type=IndexType::KEYS)
286:     {
287:         $this->_alter_column($keyspace, $column_family, $column,
288:             $data_type=$data_type, $index_type=$index_type, $index_name=$index_name);
289:     }
290: 
291:     /**
292:      * Drop an index from a column family.
293:      *
294:      * Example usage:
295:      *
296:      * <code>
297:      * $sys = new SystemManager();
298:      * $sys->drop_index("Keyspace1", "Users", "name");
299:      * </code>
300:      *
301:      * @param string $keyspace the name of the keyspace containing the column family
302:      * @param string $column_family the name of the column family
303:      * @param string $column the name of the column to drop the index from
304:      */
305:     public function drop_index($keyspace, $column_family, $column) {
306:         $this->_alter_column($keyspace, $column_family, $column,
307:             $data_type=self::KEEP, $index_type=NULL, $index_name=NULL);
308:     }
309: 
310:     /**
311:      * Changes or sets the validation class of a single column.
312:      *
313:      * Example usage:
314:      *
315:      * <code>
316:      * $sys = new SystemManager();
317:      * $sys->alter_column("Keyspace1", "Users", "name", "UTF8Type");
318:      * </code>
319:      *
320:      * @param string $keyspace the name of the keyspace containing the column family
321:      * @param string $column_family the name of the column family
322:      * @param string $column the name of the column to put the index on
323:      * @param string $data_type the data type of the values being indexed
324:      */
325:     public function alter_column($keyspace, $column_family, $column, $data_type) {
326:         $this->_alter_column($keyspace, $column_family, $column, $data_type);
327:     }
328: 
329:     protected static function qualify_class_name($data_type) {
330:         if ($data_type === null)
331:             return null;
332: 
333:         if (strpos($data_type, ".") === false)
334:             return "org.apache.cassandra.db.marshal.$data_type";
335:         else
336:             return $data_type;
337:     }
338: 
339:     protected function _alter_column($keyspace, $column_family, $column,
340:         $data_type=self::KEEP, $index_type=self::KEEP, $index_name=self::KEEP) {
341: 
342:         $this->client->set_keyspace($keyspace);
343:         $cfdef = $this->get_cfdef($keyspace, $column_family);
344: 
345:         if ($cfdef->column_type == 'Super') {
346:             $col_name_type = DataType::get_type_for($cfdef->subcomparator_type);
347:         } else {
348:             $col_name_type = DataType::get_type_for($cfdef->comparator_type);
349:         }
350:         $packed_name = $col_name_type->pack($column);
351: 
352:         $col_def = null;
353:         $col_meta = $cfdef->column_metadata;
354:         for ($i = 0; $i < count($col_meta); $i++) {
355:             $temp_col_def = $col_meta[$i];
356:             if ($temp_col_def->name === $packed_name) {
357:                 $col_def = $temp_col_def;
358:                 unset($col_meta[$i]);
359:                 break;
360:             }
361:         }
362: 
363:         if ($col_def === null) {
364:             $col_def = new ColumnDef();
365:             $col_def->name = $packed_name;
366:         }
367:         if ($data_type !== self::KEEP)
368:             $col_def->validation_class = self::qualify_class_name($data_type);
369:         if ($index_type !== self::KEEP)
370:             $col_def->index_type = $index_type;
371:         if ($index_name !== self::KEEP)
372:             $col_def->index_name = $index_name;
373: 
374:         $col_meta[] = $col_def;
375:         $cfdef->column_metadata = $col_meta;
376:         $this->client->system_update_column_family($cfdef);
377:         $this->wait_for_agreement();
378:     }
379: 
380:     /**
381:      * Describes the Cassandra cluster.
382:      *
383:      * @return array the node to token mapping
384:      */
385:     public function describe_ring($keyspace) {
386:         return $this->client->describe_ring($keyspace);
387:     }
388: 
389:     /**
390:      * Gives the cluster name.
391:      *
392:      * @return string the cluster name
393:      */
394:     public function describe_cluster_name() {
395:         return $this->client->describe_cluster_name();
396:     }
397: 
398:     /**
399:      * Gives the Thrift API version for the Cassandra instance.
400:      *
401:      * Note that this is different than the Cassandra version.
402:      *
403:      * @return string the API version
404:      */
405:     public function describe_version() {
406:         return $this->client->describe_version();
407:     }
408: 
409:     /**
410:      * Describes what schema version each node currently has.
411:      * Differences in schema versions indicate a schema conflict.
412:      *
413:      * @return array a mapping of schema versions to nodes.
414:      */
415:     public function describe_schema_versions() {
416:         return $this->client->describe_schema_versions();
417:     }
418: 
419:     /**
420:      * Describes the cluster's partitioner.
421:      *
422:      * @return string the name of the partitioner in use
423:      */
424:     public function describe_partitioner() {
425:         return $this->client->describe_partitioner();
426:     }
427: 
428:     /**
429:      * Describes the cluster's snitch.
430:      *
431:      * @return string the name of the snitch in use
432:      */
433:     public function describe_snitch() {
434:         return $this->client->describe_snitch();
435:     }
436: 
437:     /**
438:      * Returns a description of the keyspace and its column families.
439:      * This includes all configuration settings for the keyspace and
440:      * column families.
441:      *
442:      * @param string $keyspace the keyspace name
443:      *
444:      * @return cassandra\KsDef
445:      */
446:     public function describe_keyspace($keyspace) {
447:         return $this->client->describe_keyspace($keyspace);
448:     }
449: 
450:     /**
451:      * Like describe_keyspace(), but for all keyspaces.
452:      *
453:      * @return array an array of cassandra\KsDef
454:      */
455:     public function describe_keyspaces() {
456:         return $this->client->describe_keyspaces();
457:     }
458: }
459: 
460: 
phpcassa API documentation generated by ApiGen 2.8.0