COOPY » Guide
version 0.6.5
|
00001 #ifndef COOPY_POLYSHEET 00002 #define COOPY_POLYSHEET 00003 00004 #include <coopy/DataSheet.h> 00005 #include <coopy/SheetSchema.h> 00006 00007 namespace coopy { 00008 namespace store { 00009 class PolySheet; 00010 } 00011 } 00012 00013 class coopy::store::PolySheet : public DataSheet { 00014 private: 00015 DataSheet *sheet; 00016 bool owned; 00017 SheetSchema *schema; 00018 bool owned_schema; 00019 int dh; 00020 bool may_sniff; 00021 public: 00022 PolySheet() { 00023 sheet = 0/*NULL*/; 00024 owned = false; 00025 schema = 0/*NULL*/; 00026 owned_schema = false; 00027 dh = 0; 00028 may_sniff = true; 00029 } 00030 00031 PolySheet(DataSheet *sheet, bool owned) : sheet(sheet), owned(owned) { 00032 if (sheet!=0/*NULL*/&&owned) { 00033 sheet->addReference(); 00034 } 00035 schema = 0/*NULL*/; 00036 owned_schema = false; 00037 dh = 0; 00038 may_sniff = true; 00039 } 00040 00041 PolySheet(const PolySheet& alt) { 00042 owned = alt.owned; 00043 sheet = alt.sheet; 00044 dh = alt.dh; 00045 if (sheet!=0/*NULL*/&&owned) { 00046 sheet->addReference(); 00047 } 00048 schema = alt.schema; 00049 owned_schema = alt.owned_schema; 00050 if (schema!=0/*NULL*/&&owned_schema) { 00051 schema->addReference(); 00052 } 00053 may_sniff = alt.may_sniff; 00054 } 00055 00056 const PolySheet& operator=(const PolySheet& alt) { 00057 clear(); 00058 owned = alt.owned; 00059 sheet = alt.sheet; 00060 dh = alt.dh; 00061 if (sheet!=0/*NULL*/&&owned) { 00062 sheet->addReference(); 00063 } 00064 schema = alt.schema; 00065 owned_schema = alt.owned_schema; 00066 if (schema!=0/*NULL*/&&owned_schema) { 00067 schema->addReference(); 00068 } 00069 may_sniff = alt.may_sniff; 00070 return *this; 00071 } 00072 00073 virtual ~PolySheet() { 00074 clear(); 00075 } 00076 00077 void setSchema(SheetSchema *schema, bool owned) { 00078 clearSchema(); 00079 this->schema = schema; 00080 this->owned_schema = owned; 00081 if (schema!=0/*NULL*/&&owned_schema) { 00082 schema->addReference(); 00083 } 00084 } 00085 00086 virtual SheetSchema *getSchema() const { 00087 if (schema!=0/*NULL*/) return schema; 00088 if (sheet==0/*NULL*/) return 0/*NULL*/; 00089 return sheet->getSchema(); 00090 } 00091 00092 void clear() { 00093 clearSheet(); 00094 clearSchema(); 00095 may_sniff = true; 00096 } 00097 00098 void clearSheet() { 00099 if (sheet==0/*NULL*/) return; 00100 if (owned) { 00101 int ref = sheet->removeReference(); 00102 if (ref==0) { 00103 delete sheet; 00104 } 00105 } 00106 sheet = 0/*NULL*/; 00107 } 00108 00109 void clearSchema() { 00110 if (schema==0/*NULL*/) return; 00111 if (owned_schema) { 00112 int ref = schema->removeReference(); 00113 if (ref==0) { 00114 delete schema; 00115 } 00116 } 00117 schema = 0/*NULL*/; 00118 } 00119 00120 bool isValid() const { 00121 return sheet!=0/*NULL*/; 00122 } 00123 00124 virtual int width() const { 00125 if (!sheet) return 0; 00126 return sheet->width(); 00127 } 00128 00129 virtual int height() const { 00130 if (!sheet) return 0; 00131 return sheet->height()-dh; 00132 } 00133 00134 virtual std::string cellString(int x, int y) const { 00135 COOPY_ASSERT(sheet); 00136 return sheet->cellString(x,y+dh); 00137 } 00138 00139 virtual std::string cellString(int x, int y, bool& escaped) const { 00140 COOPY_ASSERT(sheet); 00141 return sheet->cellString(x,y+dh,escaped); 00142 } 00143 00144 virtual bool cellString(int x, int y, const std::string& str) { 00145 COOPY_ASSERT(sheet); 00146 return sheet->cellString(x,y+dh,str); 00147 } 00148 00149 virtual bool cellString(int x, int y, const std::string& str, bool escaped) { 00150 COOPY_ASSERT(sheet); 00151 return sheet->cellString(x,y+dh,str,escaped); 00152 } 00153 00154 virtual SheetCell cellSummary(int x, int y) const { 00155 COOPY_ASSERT(sheet); 00156 return sheet->cellSummary(x,y+dh); 00157 } 00158 00159 virtual bool cellSummary(int x, int y, const SheetCell& c) { 00160 COOPY_ASSERT(sheet); 00161 return sheet->cellSummary(x,y+dh,c); 00162 } 00163 00164 std::string encode(const SheetStyle& style) const { 00165 COOPY_ASSERT(sheet); 00166 return sheet->encode(style); 00167 } 00168 00169 //virtual SheetSchema *getSchema() { 00170 //return sheet->getSchema(); 00171 //} 00172 00173 virtual bool deleteColumn(const ColumnRef& column) { 00174 COOPY_ASSERT(sheet); 00175 bool ok = sheet->deleteColumn(column); 00176 if (!ok) return false; 00177 SheetSchema *s = getSchema(); 00178 if (s) { 00179 if (!s->isShadow()) { 00180 //if (ok&&owned_schema&&schema!=0/*NULL*/) { 00181 s->deleteColumn(column); 00182 } 00183 } 00184 return ok; 00185 } 00186 00187 virtual ColumnRef insertColumn(const ColumnRef& base) { 00188 COOPY_ASSERT(sheet); 00189 ColumnRef result = sheet->insertColumn(base); 00190 if (!result.isValid()) return result; 00191 SheetSchema *s = getSchema(); 00192 if (s) { 00193 if (!s->isShadow()) { 00194 ColumnRef result2 = s->insertColumn(base,ColumnInfo()); 00195 COOPY_ASSERT(result2.getIndex()==result.getIndex()); 00196 } 00197 } 00198 return result; 00199 } 00200 00201 virtual ColumnRef insertColumn(const ColumnRef& base, 00202 const ColumnInfo& info); 00203 00204 virtual bool modifyColumn(const ColumnRef& base, 00205 const ColumnInfo& info); 00206 00207 // move a column before base; if base is invalid move after all columns 00208 virtual ColumnRef moveColumn(const ColumnRef& src, const ColumnRef& base) { 00209 COOPY_ASSERT(sheet); 00210 ColumnRef result = sheet->moveColumn(src,base); 00211 if (!result.isValid()) return result; 00212 SheetSchema *s = getSchema(); 00213 if (s) { 00214 if (!s->isShadow()) { 00215 ColumnRef result2 = s->moveColumn(src,base); 00216 COOPY_ASSERT(result2.getIndex()==result.getIndex()); 00217 } 00218 } 00219 return result; 00220 } 00221 00222 virtual bool deleteRow(const RowRef& src) { 00223 COOPY_ASSERT(sheet); 00224 return sheet->deleteRow((dh==0)?src:src.delta(dh)); 00225 } 00226 00227 virtual bool deleteRows(const RowRef& first, const RowRef& last) { 00228 COOPY_ASSERT(sheet); 00229 return sheet->deleteRows((dh==0)?first:first.delta(dh), 00230 (dh==0)?last:last.delta(dh)); 00231 } 00232 00233 // insert a row before base; if base is invalid insert after all rows 00234 virtual RowRef insertRow(const RowRef& base) { 00235 COOPY_ASSERT(sheet); 00236 return fixRow(sheet->insertRow((dh==0)?base:base.delta(dh))); 00237 } 00238 00239 // move a row before base; if base is invalid move after all rows 00240 virtual RowRef moveRow(const RowRef& src, const RowRef& base) { 00241 COOPY_ASSERT(sheet); 00242 return fixRow(sheet->moveRow(src,(dh==0)?base:base.delta(dh))); 00243 } 00244 00245 virtual bool copyData(const DataSheet& src) { 00246 COOPY_ASSERT(sheet); 00247 return sheet->copyData(src); 00248 } 00249 00250 virtual bool canWrite() { 00251 COOPY_ASSERT(sheet); 00252 return sheet->canWrite(); 00253 } 00254 00255 virtual bool canResize() { 00256 COOPY_ASSERT(sheet); 00257 return sheet->canResize(); 00258 } 00259 00260 virtual bool resize(int w, int h) { 00261 COOPY_ASSERT(sheet); 00262 return sheet->resize(w,h+dh); 00263 } 00264 00265 virtual Poly<SheetRow> insertRow() { 00266 COOPY_ASSERT(sheet); 00267 Poly<SheetRow> row = sheet->insertRow(); 00268 row->setDelta(-dh); 00269 return row; 00270 } 00271 00272 virtual Poly<SheetRow> insertRowOrdered(const RowRef& base) { 00273 COOPY_ASSERT(sheet); 00274 Poly<SheetRow> row = sheet->insertRowOrdered((dh==0)?base:base.delta(dh)); 00275 row->setDelta(-dh); 00276 return row; 00277 } 00278 00279 virtual bool applySchema(const SheetSchema& ss) { 00280 COOPY_ASSERT(sheet); 00281 return sheet->applySchema(ss); 00282 } 00283 00284 virtual bool applyRowCache(const RowCache& cache, int row, SheetCell *result) { 00285 COOPY_ASSERT(sheet); 00286 return sheet->applyRowCache(cache,row,result); 00287 } 00288 00289 virtual bool deleteData(int start = 0) { 00290 COOPY_ASSERT(sheet); 00291 return sheet->deleteData(dh+start); 00292 } 00293 00294 virtual bool hasDimension() const { 00295 COOPY_ASSERT(sheet); 00296 return sheet->hasDimension(); 00297 } 00298 00299 virtual bool forceWidth(int width) { 00300 COOPY_ASSERT(sheet); 00301 return sheet->forceWidth(width); 00302 } 00303 00304 virtual bool forceHeight(int height) { 00305 COOPY_ASSERT(sheet); 00306 return sheet->forceHeight(height+dh); 00307 } 00308 00309 virtual bool hasExternalColumnNames() const { 00310 if (dh!=0) return true; 00311 COOPY_ASSERT(sheet); 00312 return sheet->hasExternalColumnNames(); 00313 } 00314 00315 00316 virtual std::string getDescription() const { 00317 return "poly"; 00318 } 00319 00320 virtual std::vector<std::string> getNestedDescription() const { 00321 COOPY_ASSERT(sheet); 00322 std::vector<std::string> v = sheet->getNestedDescription(); 00323 std::string name = getDescription(); 00324 v.insert(v.begin(),name); 00325 return v; 00326 } 00327 00328 virtual std::string getHash(bool cache) const { 00329 if (dh==0) { 00330 COOPY_ASSERT(sheet); 00331 return sheet->getHash(cache); 00332 } 00333 return DataSheet::getHash(cache); 00334 } 00335 00336 00337 virtual std::string getRawHash() const { 00338 if (dh==0) { 00339 COOPY_ASSERT(sheet); 00340 return sheet->getRawHash(); 00341 } 00342 return DataSheet::getRawHash(); 00343 } 00344 00345 virtual DataSheet& tail() { 00346 if (dh!=0) { 00347 return *this; 00348 } 00349 COOPY_ASSERT(sheet); 00350 return sheet->tail(); 00351 } 00352 00353 virtual const DataSheet& tail_const() const { 00354 if (dh!=0) { 00355 return *this; 00356 } 00357 COOPY_ASSERT(sheet); 00358 return sheet->tail_const(); 00359 } 00360 00361 virtual const DataSheet& dataTail() const { 00362 COOPY_ASSERT(sheet); 00363 return sheet->dataTail(); 00364 } 00365 00366 virtual bool isSequential() const { 00367 COOPY_ASSERT(sheet); 00368 return sheet->isSequential(); 00369 } 00370 00371 virtual DataSheet *getNestedSheet(int x, int y) { 00372 COOPY_ASSERT(sheet); 00373 return sheet->getNestedSheet(x,y); 00374 } 00375 00376 bool setRowOffset(int dh) { 00377 this->dh = dh; 00378 return true; 00379 } 00380 00381 virtual bool hasRowOffset() const { 00382 if (dh==0 && sheet) { 00383 return sheet->hasRowOffset(); 00384 } 00385 return dh!=0; 00386 } 00387 00388 bool setRowOffset() { 00389 COOPY_ASSERT(sheet); 00390 if (dh>0) return true; 00391 SheetSchema *schema = getSchema(); 00392 if (!schema) { 00393 schema = sheet->getSchema(); 00394 } 00395 if (!schema) return true; 00396 if (sheet->hasExternalColumnNames()) return true; 00397 if (schema->headerHeight()>=0) { 00398 setRowOffset(schema->headerHeight()+1); 00399 } 00400 return true; 00401 } 00402 00403 bool createHeaders() { 00404 if (dh>0) return false; 00405 if (!hasExternalColumnNames()) { 00406 SheetSchema *schema = getSchema(); 00407 if (schema) { 00408 insertRow(RowRef(0)); 00409 for (int i=0; i<schema->getColumnCount(); i++) { 00410 cellString(i,0,schema->getColumnInfo(i).getName()); 00411 } 00412 setRowOffset(1); 00413 schema->setHeaderHeight(1); 00414 return true; 00415 } 00416 } 00417 return false; 00418 } 00419 00420 bool hideHeaders() { 00421 if (!hasExternalColumnNames()) { 00422 if (getSchema()==0/*NULL*/) { 00423 setRowOffset(1); 00424 } else { 00425 setRowOffset(getSchema()->headerHeight()); 00426 } 00427 } 00428 return false; 00429 } 00430 00431 virtual Poly<Appearance> getCellAppearance(int x, int y) { 00432 COOPY_ASSERT(sheet); 00433 return sheet->getCellAppearance(x,y+dh); 00434 } 00435 00436 virtual Poly<Appearance> getRowAppearance(int y) { 00437 COOPY_ASSERT(sheet); 00438 return sheet->getRowAppearance(y+dh); 00439 } 00440 00441 virtual Poly<Appearance> getColAppearance(int x) { 00442 COOPY_ASSERT(sheet); 00443 return sheet->getColAppearance(x); 00444 } 00445 00446 virtual bool hasSheetName() const { 00447 COOPY_ASSERT(sheet); 00448 return sheet->hasSheetName(); 00449 } 00450 00451 virtual bool addedHeader() { 00452 COOPY_ASSERT(sheet); 00453 return sheet->addedHeader(); 00454 } 00455 00456 bool mustHaveSchema(); 00457 00458 void forbidSchema() { 00459 may_sniff = false; 00460 } 00461 00462 virtual bool setPool(Pool *pool) { 00463 COOPY_ASSERT(sheet); 00464 return sheet->setPool(pool); 00465 } 00466 00467 virtual Pool *getPool() const { 00468 COOPY_ASSERT(sheet); 00469 return sheet->getPool(); 00470 } 00471 00472 virtual void setMeta(SheetSchema *hint) { 00473 COOPY_ASSERT(sheet); 00474 sheet->setMeta(hint); 00475 } 00476 00477 virtual void setMeta() { 00478 COOPY_ASSERT(sheet); 00479 SheetSchema *schema = getSchema(); 00480 if (!schema) return; 00481 setMeta(schema->clone()); 00482 } 00483 00484 virtual SheetSchema *getMeta() const { 00485 COOPY_ASSERT(sheet); 00486 return sheet->getMeta(); 00487 } 00488 00489 virtual bool beginTransaction() { 00490 COOPY_ASSERT(sheet); 00491 return sheet->beginTransaction(); 00492 } 00493 00494 virtual bool rollbackTransaction() { 00495 COOPY_ASSERT(sheet); 00496 return sheet->rollbackTransaction(); 00497 } 00498 00499 virtual bool endTransaction() { 00500 COOPY_ASSERT(sheet); 00501 return sheet->endTransaction(); 00502 } 00503 00504 virtual void *getDatabase() const { 00505 COOPY_ASSERT(sheet); 00506 return sheet->getDatabase(); 00507 } 00508 00509 virtual coopy::cmp::Compare *getComparisonMethod() { 00510 COOPY_ASSERT(sheet); 00511 return sheet->getComparisonMethod(); 00512 } 00513 00514 private: 00515 RowRef fixRow(const RowRef& r) { 00516 if (dh==0) return r; 00517 int idx = r.getIndex(); 00518 if (idx==-1) return r; 00519 return r.delta(-dh); 00520 } 00521 00522 SheetSchema *preApplyInfo(const ColumnInfo& info); 00523 bool postApplyInfo(const ColumnInfo& info, const ColumnRef& result); 00524 }; 00525 00526 #endif