COOPY » Guide
version 0.6.5
|
00001 #include <coopy/MergeOutputFilter.h> 00002 00003 using namespace std; 00004 00005 using namespace coopy::cmp; 00006 using namespace coopy::store; 00007 00008 bool MergeOutputFilter::mergeAllDone() { 00009 Pool *pool = getFlags().pool; 00010 if (pool) { 00011 // default assumption is that IDs from parent are shared with remote 00012 // if assumption is not true, don't do the following. 00013 00014 map<string,int> seen; 00015 for (std::list<RowUnit>::iterator it=rows.begin(); it!=rows.end(); it++) { 00016 RowUnit& unit = *it; 00017 RowChange& change = unit.change; 00018 if (change.mode == ROW_CHANGE_INSERT) { 00019 const std::string& name = unit.sheet_name; 00020 00021 if (seen.find(name)==seen.end()) { 00022 PolySheet sheet; 00023 TextBook *book = getBook(); 00024 if (!book) { 00025 fprintf(stderr,"Cannot find input\n"); 00026 } else { 00027 sheet = getBook()->readSheet(name); 00028 if (sheet.isValid()) { 00029 addPoolsFromFlags(sheet,false); 00030 NameSniffer sniffer(sheet,getFlags()); 00031 addPoolsFromSchema(sheet,sniffer,name,false); 00032 } 00033 seen[name] = 1; 00034 } 00035 } 00036 00037 for (RowChange::txt2cell::const_iterator it = change.val.begin(); 00038 it!=change.val.end(); it++) { 00039 PoolColumnLink link = pool->lookup(name,it->first); 00040 if (link.isInventor()) { 00041 PoolRecord& rec = link.getColumn().put(it->second,SheetCell()); 00042 rec.linked = false; 00043 } 00044 } 00045 } 00046 } 00047 pool->setScanned(); 00048 } 00049 00050 if (desired_sheets.size()<2) { 00051 for (std::list<RowUnit>::iterator it=rows.begin(); it!=rows.end(); it++) { 00052 emitRow(*it); 00053 } 00054 for (std::map<std::string,SheetUnit>::iterator it=sheet_units.begin(); 00055 it!=sheet_units.end(); it++) { 00056 emitPreambleIfNeeded(it->second); 00057 } 00058 } else { 00059 const CompareFlags& flags = getFlags(); 00060 // could do with some optimization... 00061 for (int i=0; i<(int)flags.ordered_tables.size(); i++) { 00062 string name = flags.ordered_tables[i]; 00063 for (std::list<RowUnit>::iterator it=rows.begin(); it!=rows.end(); it++) { 00064 if (it->sheet_name == name) { 00065 emitRow(*it); 00066 } 00067 } 00068 emitPreambleIfNeeded(sheet_units[name]); 00069 } 00070 } 00071 chain->mergeDone(); 00072 00073 return chain->mergeAllDone(); 00074 } 00075 00076 00077 bool MergeOutputFilter::emitRow(const RowUnit& row) { 00078 string name = row.sheet_name; 00079 if (name!=last_sheet_name) { 00080 emitPreamble(sheet_units[name]); 00081 } 00082 string resolve = getFlags().resolve; 00083 if (resolve!="") { 00084 if (row.change.conflicted) { 00085 if (resolve=="ours") { 00086 return true; 00087 } 00088 RowChange change2 = row.change; 00089 if (resolve=="theirs") { 00090 for (RowChange::txt2cell::iterator it = change2.conflictingVal.begin(); 00091 it != change2.conflictingVal.end(); it++) { 00092 change2.val[it->first] = it->second; 00093 } 00094 } else if (resolve=="neither") { 00095 for (RowChange::txt2cell::iterator it = 00096 change2.conflictingParentVal.begin(); 00097 it != change2.conflictingParentVal.end(); it++) { 00098 change2.val[it->first] = it->second; 00099 } 00100 } 00101 change2.conflictingVal.clear(); 00102 change2.conflictingParentVal.clear(); 00103 change2.conflicted = false; 00104 return chain->changeRow(change2); 00105 } 00106 } 00107 return chain->changeRow(row.change); 00108 } 00109 00110 bool MergeOutputFilter::emitPreamble(const SheetUnit& preamble) { 00111 string name = preamble.sheet_name; 00112 //printf("emit [%s]?\n", name.c_str()); 00113 if (name==last_sheet_name) { return false; } 00114 //printf("emit [%s]!\n", name.c_str()); 00115 00116 TextBook *book = getBook(); 00117 if (getFlags().create_unknown_sheets && book) { 00118 PolySheet sheet; 00119 sheet = book->readSheet(name); 00120 if (sheet.isValid()) { 00121 if (getFlags().clean_sheets) { 00122 sheet.deleteData(); 00123 } 00124 } else { 00125 dbg_printf("I need to create %s\n", name.c_str()); 00126 00127 for (std::list<PoolChange>::const_iterator it=preamble.pools.begin(); 00128 it != preamble.pools.end(); it++) { 00129 dbg_printf("apply pool\n"); 00130 applyPool(*it); 00131 } 00132 00133 vector<string> names; 00134 if (preamble.have_name1) { 00135 names = preamble.name1.names; 00136 } else if (preamble.have_name0) { 00137 names = preamble.name1.names; 00138 } 00139 00140 if (names.size()==0) { 00141 fprintf(stderr,"Do not know column names to create %s\n", name.c_str()); 00142 exit(1); 00143 } 00144 SimpleSheetSchema sss0, sss1; 00145 sss0.setSheetName(name.c_str()); 00146 for (int i=0; i<(int)names.size(); i++) { 00147 sss0.addColumn(names[i].c_str()); 00148 } 00149 book->setPool(getFlags().pool); 00150 book->fixSchema(sss0,sss1); 00151 book->addSheet(sss1); 00152 } 00153 } 00154 00155 if (name!="") { 00156 chain->setSheet(name.c_str()); 00157 } 00158 last_sheet_name = name; 00159 if (started_sheets.find(name)!=started_sheets.end()) { 00160 return true; 00161 } 00162 started_sheets[name] = 1; 00163 00164 if (preamble.have_name0) { 00165 chain->changeName(preamble.name0); 00166 } 00167 for (std::list<OrderChange>::const_iterator it = preamble.orders.begin(); 00168 it != preamble.orders.end(); it++) { 00169 chain->changeColumn(*it); 00170 } 00171 if (preamble.have_name1) { 00172 chain->changeName(preamble.name1); 00173 } 00174 for (std::list<PoolChange>::const_iterator it = preamble.pools.begin(); 00175 it != preamble.pools.end(); it++) { 00176 chain->changePool(*it); 00177 } 00178 return true; 00179 } 00180 00181 00182 bool MergeOutputFilter::mergeStart() { 00183 const CompareFlags& flags = getFlags(); 00184 for (int i=0; i<(int)flags.ordered_tables.size(); i++) { 00185 desired_sheets[flags.ordered_tables[i]] = 1; 00186 } 00187 return chain->mergeStart(); 00188 } 00189 00190 00191 bool MergeOutputFilter::emitPreambleIfNeeded(const SheetUnit& preamble) { 00192 if (preamble.row_count==0) { 00193 if (getFlags().canSchema()||preamble.orders.size()>0|| 00194 preamble.pools.size()>0) { 00195 return emitPreamble(preamble); 00196 } 00197 } 00198 return true; 00199 } 00200 00201 00202 bool MergeOutputFilter::changeRow(const RowChange& change) { 00203 if (!isActiveTable()) return false; 00204 SheetUnit unit = getSheetUnit(); 00205 if (!(unit.have_name0||unit.have_name1)) { 00206 NameChange nc; 00207 nc.mode = NAME_CHANGE_DECLARE; 00208 nc.constant = true; 00209 nc.final = true; 00210 nc.names = change.allNames; 00211 changeName(nc); 00212 } 00213 switch (change.mode) { 00214 case ROW_CHANGE_INSERT: 00215 if (!getFlags().canInsert()) { return false; } 00216 break; 00217 case ROW_CHANGE_DELETE: 00218 if (!getFlags().canDelete()) { return false; } 00219 break; 00220 case ROW_CHANGE_UPDATE: 00221 case ROW_CHANGE_MOVE: 00222 if (!getFlags().canUpdate()) { return false; } 00223 break; 00224 } 00225 rows.push_back(RowUnit(sheet_name,change)); 00226 getSheetUnit().row_count++; 00227 return true; 00228 } 00229