libQtCassandra 0.3.2
|
00001 /* 00002 * Text: 00003 * QCassandraTable.cpp 00004 * 00005 * Description: 00006 * Handling of the cassandra::CfDef (Column Family Definition). 00007 * 00008 * Documentation: 00009 * See each function below. 00010 * 00011 * License: 00012 * Copyright (c) 2011 Made to Order Software Corp. 00013 * 00014 * http://snapwebsites.org/ 00015 * contact@m2osw.com 00016 * 00017 * Permission is hereby granted, free of charge, to any person obtaining a 00018 * copy of this software and associated documentation files (the 00019 * "Software"), to deal in the Software without restriction, including 00020 * without limitation the rights to use, copy, modify, merge, publish, 00021 * distribute, sublicense, and/or sell copies of the Software, and to 00022 * permit persons to whom the Software is furnished to do so, subject to 00023 * the following conditions: 00024 * 00025 * The above copyright notice and this permission notice shall be included 00026 * in all copies or substantial portions of the Software. 00027 * 00028 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00029 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00030 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00031 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 00032 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 00033 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 00034 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00035 */ 00036 00037 #include "QtCassandra/QCassandraTable.h" 00038 #include "QtCassandra/QCassandraContext.h" 00039 #include "QCassandraPrivate.h" 00040 #include "thrift-gencpp-cassandra/cassandra_types.h" 00041 #include <stdexcept> 00042 00043 #include <QtCore/QDebug> 00044 #include <QtCore/QRegExp> 00045 00046 00047 namespace QtCassandra 00048 { 00049 00050 00084 class QCassandraTablePrivate : public org::apache::cassandra::CfDef {}; 00085 00086 00087 00088 00089 00166 QCassandraTable::QCassandraTable(QCassandraContext *context, const QString& table_name) 00167 : //f_from_cassandra(false) -- auto-init 00168 f_private(new QCassandraTablePrivate), 00169 f_context(context) 00170 //f_column_definitions() -- auto-init 00171 //f_rows() -- auto-init 00172 { 00173 // verify the name here (faster than waiting for the server and good documentation) 00174 QRegExp re("[A-Za-z][A-Za-z0-9_]*"); 00175 if(!re.exactMatch(table_name)) { 00176 throw std::runtime_error("invalid column name (does not match [A-Za-z][A-Za-z0-9_]*)"); 00177 } 00178 00179 // we save the context name (keyspace) and since it's forbidden to change it 00180 // in the context, we know it won't change here either 00181 QString keyspace = context->contextName(); 00182 f_private->__set_keyspace(keyspace.toUtf8().data()); 00183 00184 // we save the name and at this point we prevent it from being changed. 00185 f_private->__set_name(table_name.toUtf8().data()); 00186 } 00187 00193 QCassandraTable::~QCassandraTable() 00194 { 00195 } 00196 00211 QString QCassandraTable::contextName() const 00212 { 00213 return f_private->keyspace.c_str(); 00214 } 00215 00223 QString QCassandraTable::tableName() const 00224 { 00225 return f_private->name.c_str(); 00226 } 00227 00236 void QCassandraTable::setIdentifier(int32_t identifier) 00237 { 00238 f_private->__set_id(identifier); 00239 } 00240 00247 void QCassandraTable::unsetIdentifier() 00248 { 00249 f_private->__isset.id = false; 00250 } 00251 00259 int32_t QCassandraTable::identifier() const 00260 { 00261 return f_private->id; 00262 } 00263 00273 void QCassandraTable::setComment(QString comment) 00274 { 00275 f_private->__set_comment(comment.toUtf8().data()); 00276 } 00277 00282 void QCassandraTable::unsetComment() 00283 { 00284 f_private->__isset.comment = false; 00285 } 00286 00296 QString QCassandraTable::comment() const 00297 { 00298 return f_private->comment.c_str(); 00299 } 00300 00311 void QCassandraTable::setColumnType(const QString& column_type) 00312 { 00313 if(column_type != "Standard" && column_type != "Super") { 00314 throw std::runtime_error("the type of a column can be either \"Standard\" or \"Super\"."); 00315 } 00316 00317 f_private->__set_column_type(column_type.toUtf8().data()); 00318 } 00319 00324 void QCassandraTable::unsetColumnType() 00325 { 00326 f_private->__isset.column_type = false; 00327 } 00328 00335 QString QCassandraTable::columnType() const 00336 { 00337 return f_private->column_type.c_str(); 00338 } 00339 00354 void QCassandraTable::setDefaultValidationClass(const QString& validation_class) 00355 { 00356 f_private->__set_default_validation_class(validation_class.toUtf8().data()); 00357 } 00358 00363 void QCassandraTable::unsetDefaultValidationClass() 00364 { 00365 f_private->__isset.default_validation_class = false; 00366 } 00367 00375 QString QCassandraTable::defaultValidationClass() const 00376 { 00377 return f_private->default_validation_class.c_str(); 00378 } 00379 00394 void QCassandraTable::setKeyValidationClass(const QString& validation_class) 00395 { 00396 f_private->__set_key_validation_class(validation_class.toUtf8().data()); 00397 } 00398 00404 void QCassandraTable::unsetKeyValidationClass() 00405 { 00406 f_private->__isset.key_validation_class = false; 00407 } 00408 00415 QString QCassandraTable::keyValidationClass() const 00416 { 00417 return f_private->key_validation_class.c_str(); 00418 } 00419 00430 void QCassandraTable::setKeyAlias(const QString& key_alias) 00431 { 00432 f_private->__set_key_alias(key_alias.toUtf8().data()); 00433 } 00434 00439 void QCassandraTable::unsetKeyAlias() 00440 { 00441 f_private->__isset.key_alias = false; 00442 } 00443 00455 QString QCassandraTable::keyAlias() const 00456 { 00457 return f_private->key_alias.c_str(); 00458 } 00459 00506 void QCassandraTable::setComparatorType(const QString& comparator_type) 00507 { 00508 f_private->__set_comparator_type(comparator_type.toUtf8().data()); 00509 } 00510 00516 void QCassandraTable::unsetComparatorType() 00517 { 00518 f_private->__isset.comparator_type = false; 00519 } 00520 00527 QString QCassandraTable::comparatorType() const 00528 { 00529 return f_private->comparator_type.c_str(); 00530 } 00531 00544 void QCassandraTable::setSubcomparatorType(const QString& subcomparator_type) 00545 { 00546 f_private->__set_subcomparator_type(subcomparator_type.toUtf8().data()); 00547 } 00548 00553 void QCassandraTable::unsetSubcomparatorType() 00554 { 00555 f_private->__isset.subcomparator_type = false; 00556 } 00557 00566 QString QCassandraTable::subcomparatorType() const 00567 { 00568 return f_private->subcomparator_type.c_str(); 00569 } 00570 00583 QSharedPointer<QCassandraColumnDefinition> QCassandraTable::columnDefinition(const QString& column_name) 00584 { 00585 // column already exists? 00586 QCassandraColumnDefinitions::iterator ci(f_column_definitions.find(column_name)); 00587 if(ci != f_column_definitions.end()) { 00588 return ci.value(); 00589 } 00590 00591 // this is a new column, allocate it 00592 QSharedPointer<QCassandraColumnDefinition> c(new QCassandraColumnDefinition(this, column_name)); 00593 f_column_definitions.insert(column_name, c); 00594 return c; 00595 } 00596 00608 const QCassandraColumnDefinitions& QCassandraTable::columnDefinitions() const 00609 { 00610 return f_column_definitions; 00611 } 00612 00628 void QCassandraTable::setRowCacheSize(double size) 00629 { 00630 f_private->__set_row_cache_size(size); 00631 } 00632 00637 void QCassandraTable::unsetRowCacheSize() 00638 { 00639 f_private->__isset.row_cache_size = false; 00640 } 00641 00648 double QCassandraTable::rowCacheSize() const 00649 { 00650 return f_private->row_cache_size; 00651 } 00652 00663 void QCassandraTable::setRowCacheSavePeriodInSeconds(int32_t seconds) 00664 { 00665 f_private->__set_row_cache_save_period_in_seconds(seconds); 00666 } 00667 00673 void QCassandraTable::unsetRowCacheSavePeriodInSeconds() 00674 { 00675 f_private->__isset.row_cache_save_period_in_seconds = false; 00676 } 00677 00686 int32_t QCassandraTable::rowCacheSavePeriodInSeconds() const 00687 { 00688 return f_private->row_cache_save_period_in_seconds; 00689 } 00690 00701 void QCassandraTable::setKeyCacheSize(double size) 00702 { 00703 f_private->__set_key_cache_size(size); 00704 } 00705 00711 void QCassandraTable::unsetKeyCacheSize() 00712 { 00713 f_private->__isset.key_cache_size = false; 00714 } 00715 00722 double QCassandraTable::keyCacheSize() const 00723 { 00724 return f_private->key_cache_size; 00725 } 00726 00739 void QCassandraTable::setKeyCacheSavePeriodInSeconds(int32_t seconds) 00740 { 00741 f_private->__set_key_cache_save_period_in_seconds(seconds); 00742 } 00743 00749 void QCassandraTable::unsetKeyCacheSavePeriodInSeconds() 00750 { 00751 f_private->__isset.key_cache_save_period_in_seconds = false; 00752 } 00753 00761 int32_t QCassandraTable::keyCacheSavePeriodInSeconds() const 00762 { 00763 return f_private->key_cache_save_period_in_seconds; 00764 } 00765 00772 void QCassandraTable::setReadRepairChance(double repair_chance) 00773 { 00774 f_private->__set_read_repair_chance(repair_chance); 00775 } 00776 00781 void QCassandraTable::unsetReadRepairChance() 00782 { 00783 f_private->__isset.read_repair_chance = false; 00784 } 00785 00792 double QCassandraTable::readRepairChance() const 00793 { 00794 return f_private->read_repair_chance; 00795 } 00796 00813 void QCassandraTable::setMinCompactionThreshold(int32_t threshold) 00814 { 00815 f_private->__set_min_compaction_threshold(threshold); 00816 } 00817 00822 void QCassandraTable::unsetMinCompactionThreshold() 00823 { 00824 f_private->__isset.min_compaction_threshold = false; 00825 } 00826 00833 double QCassandraTable::minCompactionThreshold() const 00834 { 00835 return f_private->min_compaction_threshold; 00836 } 00837 00848 void QCassandraTable::setMaxCompactionThreshold(int32_t threshold) 00849 { 00850 f_private->__set_max_compaction_threshold(threshold); 00851 } 00852 00858 void QCassandraTable::unsetMaxCompactionThreshold() 00859 { 00860 f_private->__isset.max_compaction_threshold = false; 00861 } 00862 00872 double QCassandraTable::maxCompactionThreshold() const 00873 { 00874 return f_private->max_compaction_threshold; 00875 } 00876 00885 void QCassandraTable::setReplicateOnWrite(bool replicate_on_write) 00886 { 00887 f_private->__set_replicate_on_write(replicate_on_write); 00888 } 00889 00895 void QCassandraTable::unsetReplicateOnWrite() 00896 { 00897 f_private->__isset.replicate_on_write = false; 00898 } 00899 00909 bool QCassandraTable::replicateOnWrite() const 00910 { 00911 f_private->replicate_on_write; 00912 } 00913 00924 void QCassandraTable::setMergeShardsChance(double merge_shards_chance) 00925 { 00926 f_private->__set_merge_shards_chance(merge_shards_chance); 00927 } 00928 00933 void QCassandraTable::unsetMergeShardsChance() 00934 { 00935 f_private->__isset.merge_shards_chance = false; 00936 } 00937 00945 double QCassandraTable::mergeShardsChance() const 00946 { 00947 return f_private->merge_shards_chance; 00948 } 00949 00958 void QCassandraTable::setRowCacheProvider(const QString& provider) 00959 { 00960 f_private->__set_row_cache_provider(provider.toUtf8().data()); 00961 } 00962 00967 void QCassandraTable::unsetRowCacheProvider() 00968 { 00969 f_private->__isset.row_cache_provider = false; 00970 } 00971 00978 QString QCassandraTable::rowCacheProvider() const 00979 { 00980 return f_private->row_cache_provider.c_str(); 00981 } 00982 00995 void QCassandraTable::setGcGraceSeconds(int32_t seconds) 00996 { 00997 f_private->__set_gc_grace_seconds(seconds); 00998 } 00999 01005 void QCassandraTable::unsetGcGraceSeconds() 01006 { 01007 f_private->__isset.gc_grace_seconds = false; 01008 } 01009 01017 int32_t QCassandraTable::gcGraceSeconds() const 01018 { 01019 return f_private->gc_grace_seconds; 01020 } 01021 01035 void QCassandraTable::setMemtableFlushAfterMins(int32_t minutes) 01036 { 01037 f_private->__set_memtable_flush_after_mins(minutes); 01038 } 01039 01046 void QCassandraTable::unsetMemtableFlushAfterMins() 01047 { 01048 f_private->__isset.memtable_flush_after_mins = false; 01049 } 01050 01059 int32_t QCassandraTable::memtableFlushAfterMins() const 01060 { 01061 return f_private->memtable_flush_after_mins; 01062 } 01063 01075 void QCassandraTable::setMemtableThroughputInMb(int32_t megabytes) 01076 { 01077 f_private->__set_memtable_throughput_in_mb(megabytes); 01078 } 01079 01085 void QCassandraTable::unsetMemtableThroughputInMb() 01086 { 01087 f_private->__isset.memtable_throughput_in_mb = false; 01088 } 01089 01096 int32_t QCassandraTable::memtableThroughputInMb() const 01097 { 01098 return f_private->memtable_throughput_in_mb; 01099 } 01100 01108 void QCassandraTable::setMemtableOperationsInMillions(int32_t operations) 01109 { 01110 f_private->__set_memtable_operations_in_millions(operations); 01111 } 01112 01117 void QCassandraTable::unsetMemtableOperationsInMillions() 01118 { 01119 f_private->__isset.memtable_operations_in_millions = false; 01120 } 01121 01129 int32_t QCassandraTable::memtableOperationsInMillions() const 01130 { 01131 return f_private->memtable_operations_in_millions; 01132 } 01133 01143 void QCassandraTable::setFromCassandra() 01144 { 01145 f_from_cassandra = true; 01146 } 01147 01155 void QCassandraTable::parseTableDefinition(const void *data) 01156 { 01157 const org::apache::cassandra::CfDef *cf = reinterpret_cast<const org::apache::cassandra::CfDef *>(data); 01158 01159 if(cf->keyspace != f_private->keyspace) { 01160 // what do we do here? 01161 throw std::logic_error("CfDef and QCassandraTablePrivate context names don't match"); 01162 } 01163 01164 // table name 01165 if(cf->name != f_private->name) { 01166 // what do we do here? 01167 throw std::logic_error("CfDef and QCassandraTablePrivate table names don't match"); 01168 } 01169 01170 // column type 01171 if(cf->__isset.column_type) { 01172 f_private->__set_column_type(cf->column_type); 01173 } 01174 else { 01175 f_private->__isset.column_type = false; 01176 } 01177 01178 // comparator type 01179 if(cf->__isset.comparator_type) { 01180 f_private->__set_comparator_type(cf->comparator_type); 01181 } 01182 else { 01183 f_private->__isset.comparator_type = false; 01184 } 01185 01186 // sub-comparator type 01187 if(cf->__isset.subcomparator_type) { 01188 f_private->__set_subcomparator_type(cf->subcomparator_type); 01189 } 01190 else { 01191 f_private->__isset.subcomparator_type = false; 01192 } 01193 01194 // comment 01195 if(cf->__isset.comment) { 01196 f_private->__set_comment(cf->comment); 01197 } 01198 else { 01199 f_private->__isset.comment = false; 01200 } 01201 01202 // row cache size 01203 if(cf->__isset.row_cache_size) { 01204 f_private->__set_row_cache_size(cf->row_cache_size); 01205 } 01206 else { 01207 f_private->__isset.row_cache_size = false; 01208 } 01209 01210 // key cache size 01211 if(cf->__isset.key_cache_size) { 01212 f_private->__set_key_cache_size(cf->key_cache_size); 01213 } 01214 else { 01215 f_private->__isset.key_cache_size = false; 01216 } 01217 01218 // read repair chance 01219 if(cf->__isset.read_repair_chance) { 01220 f_private->__set_read_repair_chance(cf->read_repair_chance); 01221 } 01222 else { 01223 f_private->__isset.read_repair_chance = false; 01224 } 01225 01226 // gc grace seconds 01227 if(cf->__isset.gc_grace_seconds) { 01228 f_private->__set_gc_grace_seconds(cf->gc_grace_seconds); 01229 } 01230 else { 01231 f_private->__isset.gc_grace_seconds = false; 01232 } 01233 01234 // default validation class 01235 if(cf->__isset.default_validation_class) { 01236 f_private->__set_default_validation_class(cf->default_validation_class); 01237 } 01238 else { 01239 f_private->__isset.default_validation_class = false; 01240 } 01241 01242 // identifier 01243 if(cf->__isset.id) { 01244 f_private->__set_id(cf->id); 01245 } 01246 else { 01247 f_private->__isset.id = false; 01248 } 01249 01250 // min compaction threshold 01251 if(cf->__isset.min_compaction_threshold) { 01252 f_private->__set_min_compaction_threshold(cf->min_compaction_threshold); 01253 } 01254 else { 01255 f_private->__isset.min_compaction_threshold = false; 01256 } 01257 01258 // max compaction threshold 01259 if(cf->__isset.max_compaction_threshold) { 01260 f_private->__set_max_compaction_threshold(cf->max_compaction_threshold); 01261 } 01262 else { 01263 f_private->__isset.max_compaction_threshold = false; 01264 } 01265 01266 // row cache save period in seconds 01267 if(cf->__isset.row_cache_save_period_in_seconds) { 01268 f_private->__set_row_cache_save_period_in_seconds(cf->row_cache_save_period_in_seconds); 01269 } 01270 else { 01271 f_private->__isset.row_cache_save_period_in_seconds = false; 01272 } 01273 01274 // key cache save period in seconds 01275 if(cf->__isset.key_cache_save_period_in_seconds) { 01276 f_private->__set_key_cache_save_period_in_seconds(cf->key_cache_save_period_in_seconds); 01277 } 01278 else { 01279 f_private->__isset.key_cache_save_period_in_seconds = false; 01280 } 01281 01282 // memtable flush after mins 01283 if(cf->__isset.memtable_flush_after_mins) { 01284 f_private->__set_memtable_flush_after_mins(cf->memtable_flush_after_mins); 01285 } 01286 else { 01287 f_private->__isset.memtable_flush_after_mins = false; 01288 } 01289 01290 // memtable_throughput_in_mb 01291 if(cf->__isset.memtable_throughput_in_mb) { 01292 f_private->__set_memtable_throughput_in_mb(cf->memtable_throughput_in_mb); 01293 } 01294 else { 01295 f_private->__isset.memtable_throughput_in_mb = false; 01296 } 01297 01298 // memtable_operations_in_millions 01299 if(cf->__isset.memtable_operations_in_millions) { 01300 f_private->__set_memtable_operations_in_millions(cf->memtable_operations_in_millions); 01301 } 01302 else { 01303 f_private->__isset.memtable_operations_in_millions = false; 01304 } 01305 01306 // replicate on write 01307 if(cf->__isset.replicate_on_write) { 01308 f_private->__set_replicate_on_write(cf->replicate_on_write); 01309 } 01310 else { 01311 f_private->__isset.replicate_on_write = false; 01312 } 01313 01314 // merge shards chance 01315 if(cf->__isset.merge_shards_chance) { 01316 f_private->__set_merge_shards_chance(cf->merge_shards_chance); 01317 } 01318 else { 01319 f_private->__isset.merge_shards_chance = false; 01320 } 01321 01322 // key validation class 01323 if(cf->__isset.key_validation_class) { 01324 f_private->__set_key_validation_class(cf->key_validation_class); 01325 } 01326 else { 01327 f_private->__isset.key_validation_class = false; 01328 } 01329 01330 // row_cache_provider 01331 if(cf->__isset.row_cache_provider) { 01332 f_private->__set_row_cache_provider(cf->row_cache_provider); 01333 } 01334 else { 01335 f_private->__isset.row_cache_provider = false; 01336 } 01337 01338 // key alias 01339 if(cf->__isset.key_alias) { 01340 f_private->__set_key_alias(cf->key_alias); 01341 } 01342 else { 01343 f_private->__isset.key_alias = false; 01344 } 01345 01346 // table definitions (CfDef, column family definitions) 01347 f_column_definitions.clear(); 01348 for(std::vector<org::apache::cassandra::ColumnDef>::const_iterator 01349 col = cf->column_metadata.begin(); col != cf->column_metadata.end(); ++col) { 01350 QSharedPointer<QCassandraColumnDefinition> column_definition(columnDefinition(col->name.c_str())); 01351 const org::apache::cassandra::ColumnDef& column_def(*col); 01352 column_definition->parseColumnDefinition(&column_def); 01353 } 01354 01355 f_from_cassandra = true; 01356 } 01357 01368 void QCassandraTable::prepareTableDefinition(void *data) const 01369 { 01370 org::apache::cassandra::CfDef *cf = reinterpret_cast<org::apache::cassandra::CfDef *>(data); 01371 *cf = *f_private; 01372 01373 // copy the columns 01374 cf->column_metadata.clear(); 01375 for(QtCassandra::QCassandraColumnDefinitions::const_iterator 01376 c = f_column_definitions.begin(); 01377 c != f_column_definitions.end(); 01378 ++c) 01379 { 01380 org::apache::cassandra::ColumnDef col; 01381 (*c)->prepareColumnDefinition(&col); 01382 cf->column_metadata.push_back(col); 01383 } 01384 cf->__isset.column_metadata = !cf->column_metadata.empty(); 01385 } 01386 01432 void QCassandraTable::create() 01433 { 01434 if(f_context == NULL) { 01435 throw std::runtime_error("this table was dropped and is not attached to a context anymore"); 01436 } 01437 f_context->createTable(this); 01438 f_from_cassandra = true; 01439 01440 // TBD: Should we then call describe_keyspace() on our Context 01441 // to make sure we've got the right data (defaults) in this 01442 // object and column definitions? 01443 } 01444 01457 void QCassandraTable::update() 01458 { 01459 if(f_context == NULL) { 01460 throw std::runtime_error("table was dropped and is not attached to a context anymore"); 01461 } 01462 if(!f_from_cassandra) { 01463 // you cannot update a table that's not from Cassandra 01464 throw std::runtime_error("table is not defined in Cassandra, it cannot be updated there"); 01465 } 01466 01467 f_context->updateTable(this); 01468 01469 // TBD: Should we then call describe_keyspace() on our Context 01470 // to make sure we've got the right data (defaults) in this 01471 // object and column definitions? 01472 } 01473 01486 void QCassandraTable::clearCache() 01487 { 01488 for(QCassandraRows::iterator ri(f_rows.begin()); ri != f_rows.end(); ++ri) { 01489 (*ri)->unparent(); 01490 } 01491 f_rows.clear(); 01492 } 01493 01508 void QCassandraTable::truncate() 01509 { 01510 if(f_context == NULL) { 01511 throw std::runtime_error("table was dropped and is not attached to a context anymore"); 01512 } 01513 if(f_from_cassandra) { 01514 f_context->truncateTable(this); 01515 } 01516 01517 // delete the memory cache too 01518 clearCache(); 01519 } 01520 01542 uint32_t QCassandraTable::readRows(const QCassandraRowPredicate& row_predicate) 01543 { 01544 if(f_context == NULL) { 01545 throw std::runtime_error("table was dropped and is not attached to a context anymore"); 01546 } 01547 if(f_from_cassandra) { 01548 return f_context->getRowSlices(*this, row_predicate); 01549 } 01550 return 0; 01551 } 01552 01567 QSharedPointer<QCassandraRow> QCassandraTable::row(const QString& row_name) 01568 { 01569 return row(row_name.toUtf8()); 01570 } 01571 01586 QSharedPointer<QCassandraRow> QCassandraTable::row(const QByteArray& row_key) 01587 { 01588 // row already exists? 01589 QCassandraRows::iterator ri(f_rows.find(row_key)); 01590 if(ri != f_rows.end()) { 01591 return ri.value(); 01592 } 01593 01594 // this is a new row, allocate it 01595 QSharedPointer<QCassandraRow> c(new QCassandraRow(this, row_key)); 01596 f_rows.insert(row_key, c); 01597 return c; 01598 } 01599 01610 const QCassandraRows& QCassandraTable::rows() const 01611 { 01612 return f_rows; 01613 } 01614 01631 QSharedPointer<QCassandraRow> QCassandraTable::findRow(const QString& row_name) const 01632 { 01633 QCassandraRows::iterator ri(f_rows.find(row_name.toUtf8())); 01634 if(ri == f_rows.end()) { 01635 QSharedPointer<QCassandraRow> null; 01636 return null; 01637 } 01638 return *ri; 01639 } 01640 01657 QSharedPointer<QCassandraRow> QCassandraTable::findRow(const QByteArray& row_key) const 01658 { 01659 QCassandraRows::iterator ri(f_rows.find(row_key)); 01660 if(ri == f_rows.end()) { 01661 QSharedPointer<QCassandraRow> null; 01662 return null; 01663 } 01664 return *ri; 01665 } 01666 01675 bool QCassandraTable::exists(const QString& row_name) const 01676 { 01677 return exists(row_name.toUtf8()); 01678 } 01679 01689 bool QCassandraTable::exists(const QByteArray& row_key) const 01690 { 01691 QCassandraRows::iterator ri(f_rows.find(row_key)); 01692 if(ri != f_rows.end()) { 01693 return true; 01694 } 01695 01696 // in this case we're not given a column name so we cannot just 01697 // use the getValue() function to find out whether the row exists 01698 // instead we need to get a slice using this row key as the 01699 // slice parameter 01700 01701 QCassandraRowPredicate row_predicate; 01702 row_predicate.setStartRowKey(row_key); 01703 row_predicate.setEndRowKey(row_key); 01704 01705 // define a key range that is quite unlikely to match any column 01706 QSharedPointer<QCassandraColumnRangePredicate> column_predicate(new QCassandraColumnRangePredicate); 01707 QByteArray key; 01708 setInt32Value(key, 0x00000000); 01709 column_predicate->setStartColumnKey(key); 01710 setInt32Value(key, 0x00000001); 01711 column_predicate->setFinishColumnKey(key); 01712 column_predicate->setCount(1); 01713 row_predicate.setColumnPredicate(column_predicate); 01714 01715 return const_cast<QCassandraTable *>(this)->readRows(row_predicate) != 0; 01716 } 01717 01731 QCassandraRow& QCassandraTable::operator [] (const QString& row_name) 01732 { 01733 // in this case we may create the row and that's fine! 01734 return *row(row_name).data(); 01735 } 01736 01750 QCassandraRow& QCassandraTable::operator[] (const QByteArray& row_key) 01751 { 01752 // in this case we may create the row and that's fine! 01753 return *row(row_key).data(); 01754 } 01755 01774 const QCassandraRow& QCassandraTable::operator[] (const QString& row_name) const 01775 { 01776 const QCassandraRow *row(findRow(row_name).data()); 01777 if(row == NULL) { 01778 throw std::runtime_error("row does not exist so it cannot be read from"); 01779 } 01780 return *row; 01781 } 01782 01801 const QCassandraRow& QCassandraTable::operator[] (const QByteArray& row_key) const 01802 { 01803 const QCassandraRow *row(findRow(row_key).data()); 01804 if(row == NULL) { 01805 throw std::runtime_error("row does not exist so it cannot be read from"); 01806 } 01807 return *row; 01808 } 01809 01866 void QCassandraTable::dropRow(const QByteArray& row_key, QCassandraValue::timestamp_mode_t mode, int64_t timestamp, consistency_level_t consistency_level) 01867 { 01868 if(QCassandraValue::TIMESTAMP_MODE_AUTO != mode && QCassandraValue::TIMESTAMP_MODE_DEFINED != mode) { 01869 throw std::runtime_error("invalid timestamp mode in dropRow()"); 01870 } 01871 01872 // default to the timestamp of the value (which is most certainly 01873 // what people want in 99.9% of the cases.) 01874 if(QCassandraValue::TIMESTAMP_MODE_AUTO == mode) { 01875 // at this point I think the best default for the drop is now 01876 timestamp = QCassandra::timeofday(); 01877 } 01878 01879 // use an empty key as the column key so the entire row gets removed 01880 QByteArray empty_key; 01881 remove(row_key, empty_key, timestamp, consistency_level); 01882 01883 QSharedPointer<QCassandraRow> r(row(row_key)); 01884 r->unparent(); 01885 01886 f_rows.remove(row_key); 01887 } 01888 01900 void QCassandraTable::dropRow(const QString& row_name, QCassandraValue::timestamp_mode_t mode, int64_t timestamp, consistency_level_t consistency_level) 01901 { 01902 dropRow(row_name.toUtf8(), mode, timestamp, consistency_level); 01903 } 01904 01914 void QCassandraTable::insertValue(const QByteArray& row_key, const QByteArray& column_key, const QCassandraValue& value) 01915 { 01916 if(f_context == NULL) { 01917 throw std::runtime_error("table was dropped and is not attached to a context anymore"); 01918 } 01919 if(f_from_cassandra) { 01920 f_context->insertValue(tableName(), row_key, column_key, value); 01921 } 01922 } 01923 01933 void QCassandraTable::getValue(const QByteArray& row_key, const QByteArray& column_key, QCassandraValue& value) 01934 { 01935 if(f_context == NULL) { 01936 throw std::runtime_error("table was dropped and is not attached to a context anymore"); 01937 } 01938 if(f_from_cassandra) { 01939 f_context->getValue(tableName(), row_key, column_key, value); 01940 } 01941 } 01942 01956 void QCassandraTable::assignRow(const QByteArray& row_key, const QByteArray& column_key, const QCassandraValue& value) 01957 { 01958 QSharedPointer<QCassandraRow> r(row(row_key)); 01959 QSharedPointer<QCassandraCell> c(r->cell(column_key)); 01960 c->assignValue(value); // assign the value to the cell so we avoid re-reading it 01961 } 01962 01973 int32_t QCassandraTable::getCellCount(const QByteArray& row_key, const QCassandraColumnPredicate& column_predicate) 01974 { 01975 if(f_context == NULL) { 01976 throw std::runtime_error("table was dropped and is not attached to a context anymore"); 01977 } 01978 if(f_from_cassandra) { 01979 return f_context->getCellCount(tableName(), row_key, column_predicate); 01980 } 01981 01982 // return the count from the memory cache 01983 return f_rows[row_key]->cells().size(); 01984 } 01985 01993 void QCassandraTable::getColumnSlice(const QByteArray& row_key, const QCassandraColumnPredicate& column_predicate) 01994 { 01995 if(f_context == NULL) { 01996 throw std::runtime_error("table was dropped and is not attached to a context anymore"); 01997 } 01998 if(f_from_cassandra) { 01999 f_context->getColumnSlice(*this, row_key, column_predicate); 02000 } 02001 } 02002 02013 void QCassandraTable::remove(const QByteArray& row_key, const QByteArray& column_key, int64_t timestamp, consistency_level_t consistency_level) 02014 { 02015 if(f_context == NULL) { 02016 throw std::runtime_error("table was dropped and is not attached to a context anymore"); 02017 } 02018 if(f_from_cassandra) { 02019 f_context->remove(tableName(), row_key, column_key, timestamp, consistency_level); 02020 } 02021 } 02022 02034 void QCassandraTable::unparent() 02035 { 02036 f_context = NULL; 02037 clearCache(); 02038 } 02039 02040 } // namespace QtCassandra 02041 // vim: ts=4 sw=4 et
This document is part of the libQtCassandra Project.
Copyright by Made to Order Software Corp.