COOPY » Guide
version 0.6.5
|
00001 #include <coopy/MergeOutputHumanDiff.h> 00002 #include <coopy/SheetStyle.h> 00003 #include <coopy/DataSheet.h> 00004 00005 #include <stdio.h> 00006 #include <stdlib.h> 00007 00008 #define WANT_MAP2STRING 00009 #define WANT_VECTOR2STRING 00010 #include <coopy/Stringer.h> 00011 00012 using namespace std; 00013 using namespace coopy::store; 00014 using namespace coopy::cmp; 00015 00016 static string encoder(const string& x) { 00017 //SheetStyle style; 00018 //string result = DataSheet::encodeCell(x,style); 00019 //return (result!="")?result:"\"\""; 00020 string result = stringer_encoder(x); 00021 if (result.find("=")!=result.npos) { 00022 if (result[0]!='"') { 00023 // force quoting of any material containing the "=" symbol 00024 result = string("\"")+result+string("\""); 00025 } 00026 } 00027 return result; 00028 } 00029 00030 static string encoder(const SheetCell& x) { 00031 return encoder(x.text); 00032 } 00033 00034 static string cond(const vector<string>& names, 00035 const map<string,SheetCell>& conds, 00036 const map<string,SheetCell>& vals, 00037 bool act) { 00038 string c = ""; 00039 string pv = ""; 00040 string v = ""; 00041 bool nontrivial_past = false; 00042 for (vector<string>::const_iterator it = names.begin(); 00043 it!=names.end(); 00044 it++) { 00045 string name = *it; 00046 if (act) { 00047 //if (conds.find(name)!=conds.end()) { 00048 //fprintf(stderr,"Missing condition for %s\n", name.c_str()); 00049 //exit(1); 00050 if (vals.find(name)!=vals.end()) { 00051 SheetCell pval; 00052 SheetCell val = vals.find(name)->second; 00053 if (conds.find(name)!=conds.end()) { 00054 pval = conds.find(name)->second; 00055 if (pval.text!="") { 00056 nontrivial_past = true; 00057 } 00058 } 00059 if (pv!="") pv += ","; 00060 pv += encoder(pval); 00061 if (v!="") v += ","; 00062 v += encoder(val); 00063 if (c!="") c += ","; 00064 c += encoder(name); 00065 } 00066 //} 00067 } else { 00068 if (conds.find(name)!=conds.end()) { 00069 if (vals.find(name)==vals.end()) { 00070 SheetCell val = conds.find(name)->second; 00071 if (c!="") c += ","; 00072 c += encoder(name); 00073 if (v!="") v += ","; 00074 v += encoder(val); 00075 } 00076 } 00077 } 00078 } 00079 if (act) { 00080 if (pv == "" || !nontrivial_past) { 00081 return c + " = " + v; 00082 } 00083 return c + " = " + pv + " -> " + v; 00084 } 00085 return c + " = " + v; 00086 } 00087 00088 static string cond(const vector<string>& names, 00089 const map<string,SheetCell>& vals, 00090 string val_label, string cond_label) { 00091 SheetStyle style; 00092 string c = ""; 00093 string v = ""; 00094 size_t ct = 0; 00095 for (vector<string>::const_iterator it = names.begin(); 00096 it!=names.end(); 00097 it++) { 00098 string name = *it; 00099 if (vals.find(name)!=vals.end()) { 00100 ct++; 00101 SheetCell val = vals.find(name)->second; 00102 if (c!="") c += " "; 00103 c += encoder(name); 00104 if (v!="") v += " "; 00105 v += encoder(val); 00106 } 00107 } 00108 if (ct==names.size()) { 00109 c = "*"; 00110 return string(" ") + val_label + " " + v; 00111 } 00112 return string(" ") + cond_label + " " + c + "\n " + val_label + " " + v; 00113 } 00114 00115 static string cond(const vector<string>& names) { 00116 string c = ""; 00117 for (vector<string>::const_iterator it = names.begin(); 00118 it!=names.end(); 00119 it++) { 00120 string name = *it; 00121 if (c!="") c += " "; 00122 c += encoder(name); 00123 } 00124 return c; 00125 } 00126 00127 MergeOutputHumanDiff::MergeOutputHumanDiff() { 00128 } 00129 00130 bool MergeOutputHumanDiff::mergeStart() { 00131 fprintf(out,"dtbl: human-readable table difference format version 0.3\n\n"); 00132 showed_initial_columns = false; 00133 return true; 00134 } 00135 00136 bool MergeOutputHumanDiff::mergeDone() { 00137 checkMessage(); 00138 return true; 00139 } 00140 00141 bool MergeOutputHumanDiff::changeColumn(const OrderChange& change) { 00142 checkMessage(); 00143 //printf("Got order change %s -> %s\n", 00144 //vector2string(change.namesBefore).c_str(), 00145 //vector2string(change.namesAfter).c_str()); 00146 switch (change.mode) { 00147 case ORDER_CHANGE_DELETE: 00148 fprintf(out,"delete column: %s\n before %s\n after %s\n\n", 00149 change.namesBefore[change.subject].c_str(), 00150 vector2string(change.namesBefore).c_str(), 00151 vector2string(change.namesAfter).c_str()); 00152 break; 00153 case ORDER_CHANGE_INSERT: 00154 fprintf(out,"insert column: %s\n before %s\n after %s\n\n", 00155 change.namesAfter[change.subject].c_str(), 00156 vector2string(change.namesBefore).c_str(), 00157 vector2string(change.namesAfter).c_str()); 00158 break; 00159 case ORDER_CHANGE_MOVE: 00160 fprintf(out,"move column: %s\n before %s\n after %s\n\n", 00161 change.namesBefore[change.subject].c_str(), 00162 vector2string(change.namesBefore).c_str(), 00163 vector2string(change.namesAfter).c_str()); 00164 break; 00165 default: 00166 fprintf(out," Unknown column operation\n\n"); 00167 exit(1); 00168 break; 00169 } 00170 return true; 00171 } 00172 00173 bool MergeOutputHumanDiff::changeRow(const RowChange& change) { 00174 checkMessage(); 00175 //printf("Got row change %s ==> %s\n", 00176 // map2string(change.cond).c_str(), 00177 // map2string(change.val).c_str()); 00178 switch (change.mode) { 00179 case ROW_CHANGE_INSERT: 00180 fprintf(out,"insert row:\n%s\n\n", 00181 cond(change.names,change.val,"add","where").c_str()); 00182 break; 00183 case ROW_CHANGE_DELETE: 00184 fprintf(out,"delete row:\n%s\n\n", 00185 cond(change.names,change.cond,"remove","where").c_str()); 00186 break; 00187 case ROW_CHANGE_UPDATE: 00188 fprintf(out,"update row:\n where %s\n set %s\n\n", 00189 cond(change.names,change.cond,change.val,false).c_str(), 00190 cond(change.names,change.cond,change.val,true).c_str()); 00191 break; 00192 default: 00193 fprintf(out," Unknown row operation\n\n"); 00194 exit(1); 00195 break; 00196 } 00197 return true; 00198 } 00199 00200 00201 bool MergeOutputHumanDiff::declareNames(const std::vector<std::string>& names, 00202 bool final) { 00203 string tag = "original "; 00204 string now = ""; 00205 if (final) { 00206 tag = ""; 00207 if (showed_initial_columns&&pending_message=="") { 00208 now = " now"; 00209 } 00210 } else { 00211 showed_initial_columns = true; 00212 } 00213 string result = tag+"column names are"+now+": "+cond(names); 00214 pending_message = result; 00215 return true; 00216 } 00217 00218 00219 void MergeOutputHumanDiff::checkMessage() { 00220 if (pending_message!="") { 00221 fprintf(out,"%s\n\n", pending_message.c_str()); 00222 pending_message = ""; 00223 } 00224 } 00225 00226