COOPY » Guide
version 0.6.5
|
00001 #ifndef COOPY_PATCHER 00002 #define COOPY_PATCHER 00003 00004 #include <string> 00005 #include <vector> 00006 #include <map> 00007 00008 #include <coopy/SheetCell.h> 00009 #include <coopy/CompareFlags.h> 00010 #include <coopy/SheetCell.h> 00011 #include <coopy/PolySheet.h> 00012 #include <coopy/TextBook.h> 00013 #include <coopy/NameSniffer.h> 00014 00015 namespace coopy { 00016 namespace cmp { 00017 class ConfigChange; 00018 class OrderChange; 00019 class RowChangeContext; 00020 class RowChange; 00021 class NameChange; 00022 class TableField; 00023 class PoolChange; 00024 class LinkDeclare; 00025 class Patcher; 00026 00027 enum { 00028 ORDER_CHANGE_NONE, 00029 ORDER_CHANGE_DELETE, 00030 ORDER_CHANGE_INSERT, 00031 ORDER_CHANGE_MOVE, 00032 ORDER_CHANGE_RENAME, 00033 }; 00034 00035 enum { 00036 ROW_CHANGE_NONE, 00037 ROW_CHANGE_DELETE, 00038 ROW_CHANGE_INSERT, 00039 ROW_CHANGE_UPDATE, 00040 ROW_CHANGE_CONTEXT, 00041 ROW_CHANGE_MOVE, 00042 }; 00043 00044 enum { 00045 NAME_CHANGE_NONE, 00046 NAME_CHANGE_DECLARE, 00047 NAME_CHANGE_SELECT, 00048 }; 00049 00050 enum { 00051 LINK_DECLARE_NONE, 00052 LINK_DECLARE_LOCAL, 00053 LINK_DECLARE_REMOTE, 00054 LINK_DECLARE_MERGE, 00055 }; 00056 } 00057 } 00058 00062 class coopy::cmp::ConfigChange { 00063 public: 00064 bool ordered; 00065 bool complete; 00066 bool trustNames; 00067 00068 ConfigChange() { 00069 ordered = true; 00070 complete = true; 00071 trustNames = false; 00072 } 00073 }; 00074 00078 class coopy::cmp::TableField { 00079 public: 00080 std::string tableName; 00081 std::string fieldName; 00082 bool invented; 00083 00084 TableField() { 00085 invented = false; 00086 } 00087 00088 TableField(const std::string& tableName, 00089 const std::string& fieldName, 00090 bool invented = false) : tableName(tableName), 00091 fieldName(fieldName), 00092 invented(invented) { 00093 } 00094 00095 std::string toString() const { 00096 return tableName + ":" + fieldName + (invented?"(create)":""); 00097 } 00098 }; 00099 00103 class coopy::cmp::PoolChange { 00104 public: 00105 std::string poolName; 00106 std::string tableName; 00107 std::vector<coopy::cmp::TableField> pool; 00108 }; 00109 00113 class coopy::cmp::OrderChange { 00114 public: 00115 // local-to-global mapping before and after change 00116 std::vector<int> indicesBefore; 00117 std::vector<std::string> namesBefore; 00118 std::vector<int> indicesAfter; 00119 std::vector<std::string> namesAfter; 00120 00121 int subject; // subject in local (prior-to-action) coords 00122 int object; // object in local (prior-to-action) coords 00123 00124 int mode; 00125 00126 int identityToIndex(int id) const; 00127 int identityToIndexAfter(int id) const; 00128 00129 OrderChange() { 00130 subject = object = -1; 00131 mode = -1; 00132 } 00133 00134 std::string modeString() const { 00135 switch (mode) { 00136 case ORDER_CHANGE_NONE: 00137 return "none"; 00138 case ORDER_CHANGE_DELETE: 00139 return "delete"; 00140 case ORDER_CHANGE_INSERT: 00141 return "insert"; 00142 case ORDER_CHANGE_MOVE: 00143 return "move"; 00144 case ORDER_CHANGE_RENAME: 00145 return "rename"; 00146 } 00147 return "unknown"; 00148 } 00149 }; 00150 00154 class coopy::cmp::RowChangeContext { 00155 public: 00156 typedef std::map<std::string,coopy::store::SheetCell> row; 00157 typedef std::vector<row> rows; 00158 rows before; 00159 rows after; 00160 00161 std::map<std::string,coopy::store::SheetCell> getRow(int index) const { 00162 if (index>=0) { 00163 return after[index]; 00164 } 00165 return before[-index-1]; 00166 } 00167 00168 int afterCount() const { 00169 return (int)after.size(); 00170 } 00171 00172 int beforeCount() const { 00173 return (int)before.size(); 00174 } 00175 }; 00176 00177 00181 class coopy::cmp::RowChange { 00182 private: 00183 void copy(const RowChange& alt); 00184 public: 00185 typedef std::map<std::string,coopy::store::SheetCell> txt2cell; 00186 typedef std::map<std::string,bool> txt2bool; 00187 00188 int mode; // One of ROW_CHANGE_*, see below 00189 txt2cell cond; // conditions for a match 00190 txt2cell val; // values to be assigned 00191 txt2cell conflictingVal; 00192 txt2cell conflictingParentVal; 00193 std::vector<std::string> names; 00194 std::vector<std::string> allNames; 00195 txt2bool indexes; // conditions which are indexical, rather than confirming 00196 bool sequential; 00197 bool conflicted; 00198 //RowChangeContext context; 00199 int pRow, lRow, rRow; 00200 00201 RowChange() { 00202 mode = ROW_CHANGE_NONE; 00203 sequential = true; 00204 conflicted = false; 00205 pRow = lRow = rRow = -2; 00206 } 00207 00208 RowChange(const RowChange& alt) { 00209 copy(alt); 00210 } 00211 00212 const RowChange& operator= (const RowChange& alt) { 00213 copy(alt); 00214 return *this; 00215 } 00216 00217 bool rowsKnown() const { 00218 return pRow>=-1; 00219 } 00220 00221 std::string modeString() const { 00222 switch (mode) { 00223 case ROW_CHANGE_NONE: 00224 return "none"; 00225 case ROW_CHANGE_DELETE: 00226 return "delete"; 00227 case ROW_CHANGE_INSERT: 00228 return "insert"; 00229 case ROW_CHANGE_UPDATE: 00230 return "update"; 00231 case ROW_CHANGE_MOVE: 00232 return "move"; 00233 case ROW_CHANGE_CONTEXT: 00234 return "context"; 00235 } 00236 return "unknown"; 00237 } 00238 00239 void show(); 00240 }; 00241 00242 00246 class coopy::cmp::NameChange { 00247 public: 00248 int mode; 00249 bool final; 00250 bool constant; 00251 bool loud; 00252 bool strong; 00253 std::vector<std::string> names; 00254 00255 NameChange() { 00256 mode = -1; 00257 final = false; 00258 constant = false; 00259 loud = false; 00260 strong = false; 00261 } 00262 00263 std::string modeString() const { 00264 switch (mode) { 00265 case NAME_CHANGE_NONE: 00266 return "none"; 00267 case NAME_CHANGE_DECLARE: 00268 return "declare"; 00269 case NAME_CHANGE_SELECT: 00270 return "select"; 00271 } 00272 return "unknown"; 00273 } 00274 }; 00275 00279 class coopy::cmp::LinkDeclare { 00280 public: 00281 int mode; 00282 bool column; 00283 00284 int rc_id_pivot; 00285 int rc_id_local; 00286 int rc_id_remote; 00287 bool rc_deleted; 00288 std::string rc_str_pivot; 00289 std::string rc_str_local; 00290 std::string rc_str_remote; 00291 00292 // should also give all necessary info to show indexes 00293 coopy::store::PolySheet pivot; 00294 coopy::store::PolySheet local; 00295 coopy::store::PolySheet remote; 00296 }; 00297 00301 class coopy::cmp::Patcher { 00302 private: 00303 int ct; 00304 coopy::store::PolySheet getSheetBase(); 00305 00306 protected: 00307 CompareFlags flags; 00308 FILE *out; 00309 coopy::store::PolySheet patch_sheet; 00310 coopy::store::PolySheet active_sheet; 00311 coopy::store::TextBook *patch_book; 00312 coopy::store::TextBook *output_book; 00313 bool conflicted; 00314 bool pending; 00315 public: 00316 Patcher() { 00317 ct = 0; 00318 out = stdout; 00319 patch_book = 0; 00320 output_book = 0; 00321 conflicted = false; 00322 pending = true; 00323 } 00324 00325 virtual ~Patcher() {} 00326 00327 virtual bool wantLinks() { return false; } 00328 00329 virtual bool changeConfig(const ConfigChange& change) { return false; } 00330 00331 virtual bool changeColumn(const OrderChange& change) { return false; } 00332 00333 virtual bool changeRow(const RowChange& change) { return false; } 00334 00335 virtual bool changePool(const PoolChange& change) { return false; } 00336 00337 virtual bool declareLink(const LinkDeclare& decl) { return false; } 00338 00351 virtual bool declareNames(const std::vector<std::string>& names, bool isFinal) { 00352 return false; 00353 } 00354 00355 virtual bool changeName(const NameChange& change) { 00356 if (change.mode==NAME_CHANGE_DECLARE) { 00357 return declareNames(change.names,change.final); 00358 } 00359 return false; 00360 } 00361 00362 virtual bool mergeStart() { 00363 return true; 00364 } 00365 00366 virtual bool mergeDone() { 00367 return true; 00368 } 00369 00370 virtual bool mergeAllDone() { 00371 return true; 00372 } 00373 00374 virtual bool setSheet(const char *name) { 00375 ct++; 00376 return (ct<=1); 00377 } 00378 00379 virtual bool addSheet(const char *name, 00380 const coopy::store::PolySheet& sheet) { 00381 return false; 00382 } 00383 00384 virtual bool removeSheet(const char *name) { 00385 return false; 00386 } 00387 00388 virtual bool renameSheet(const char *name0, const char *name1) { 00389 return false; 00390 } 00391 00392 virtual bool setFlags(const CompareFlags& flags); 00393 00394 const CompareFlags& getFlags() const { 00395 return flags; 00396 } 00397 00398 CompareFlags& getMutableFlags() { 00399 return flags; 00400 } 00401 00402 // Old stuff, still used but not very important 00403 00404 virtual bool wantDiff() { return true; } 00405 00406 virtual bool addRow(const char *tag, 00407 const std::vector<coopy::store::SheetCell>& row, 00408 const std::string& blank) { return false; } 00409 00410 virtual bool addRow(const char *tag, 00411 const std::vector<std::string>& row, 00412 const std::string& blank) { 00413 std::vector<coopy::store::SheetCell> row2; 00414 for (int i=0; i<(int)row.size(); i++) { 00415 row2.push_back(coopy::store::SheetCell(row[i],false)); 00416 } 00417 return addRow(tag,row2,blank); 00418 } 00419 00420 virtual bool addHeader(const char *tag, 00421 const std::vector<coopy::store::SheetCell>& row, 00422 const std::string& blank) { 00423 return addRow(tag,row,blank); 00424 } 00425 00426 virtual bool addHeader(const char *tag, 00427 const std::vector<std::string>& row, 00428 const std::string& blank) { 00429 std::vector<coopy::store::SheetCell> row2; 00430 for (int i=0; i<(int)row.size(); i++) { 00431 row2.push_back(coopy::store::SheetCell(row[i],false)); 00432 } 00433 return addHeader(tag,row2,blank); 00434 } 00435 00436 virtual bool stripMarkup() { return false; } 00437 00438 //virtual bool metaHint(const coopy::store::SheetSchema *schema) { 00439 //return false; 00440 //} 00441 00442 virtual void attachSheet(coopy::store::PolySheet sheet) { 00443 patch_sheet = sheet; 00444 } 00445 00446 void attachBook(coopy::store::TextBook& book); 00447 00448 coopy::store::TextBook *getBook() { 00449 return patch_book; 00450 } 00451 00452 static Patcher *createByName(const char *name, const char *version = NULL); 00453 00454 virtual bool startOutput(const std::string& output, CompareFlags& flags); 00455 00456 virtual bool stopOutput(const std::string& output, CompareFlags& flags); 00457 00458 virtual bool needOutputBook() { 00459 return false; 00460 } 00461 00462 virtual bool outputStartsFromInput() { 00463 return false; 00464 } 00465 00466 void attachOutputBook(coopy::store::TextBook& book) { 00467 output_book = &book; 00468 } 00469 00470 coopy::store::TextBook *getOutputBook() { 00471 return output_book; 00472 } 00473 00474 virtual int getChangeCount() { 00475 return 0; 00476 } 00477 00478 static bool copyFile(const char *src, const char *dest); 00479 00480 virtual void setConflicted() { 00481 conflicted = true; 00482 } 00483 00484 virtual bool isConflicted() const { 00485 return conflicted; 00486 } 00487 00488 bool applyPool(const PoolChange& change); 00489 00490 bool addPoolsFromFlags(const coopy::store::DataSheet& sheet, bool msg=true); 00491 00492 bool addPoolsFromSchema(const coopy::store::DataSheet& sheet, 00493 const coopy::store::NameSniffer& sniffer, 00494 const std::string& sheetName, 00495 bool msg=true); 00496 00497 00498 virtual coopy::store::PolySheet getSheet(); 00499 00500 virtual bool metaHint(const coopy::store::DataSheet& sheet); 00501 00502 virtual bool setNames(bool forceSheetChange = false) { return true; } 00503 00504 }; 00505 00506 00507 00508 #endif