void MTable::fieldGet( TConfig &cfg ) { int i_ln, i_clm; //Alloc resource ResAlloc res(mRes, false); //Get key line if((i_ln=findKeyLine(cfg)) < 0) throw err_sys(_("The field is not present.")); //Get config fields list vector<string> cf_el; cfg.cfgList(cf_el); //Write data to cfg for(unsigned i_cf = 0; i_cf < cf_el.size(); i_cf++) { TCfg &e_cfg = cfg.cfg(cf_el[i_cf]); // Find collumn db_str_rec *fld_rec; for(i_clm = 0; (fld_rec = basa->getField(i_clm)) != NULL; i_clm++) if(cf_el[i_cf].compare(0,10,fld_rec->name) == 0) break; if(fld_rec == NULL) continue; // Get table volume string val; if(basa->GetFieldIt(i_ln,i_clm,val) < 0) throw err_sys(_("Error the cell.")); // Write value setVal(e_cfg, val); } }
void MTable::fieldDel( TConfig &cfg ) { if( tblStrct.empty() ) throw TError(TSYS::DBTableEmpty,nodePath().c_str(),_("Table is empty.")); mLstUse = time(NULL); //> Get config fields list vector<string> cf_el; cfg.cfgList(cf_el); //> Prepare request string req = "DELETE FROM '"+mod->sqlReqCode(name())+"' WHERE "; //>> Add key list to queue bool next = false; for( unsigned i_el = 0; i_el < cf_el.size(); i_el++ ) { TCfg &u_cfg = cfg.cfg(cf_el[i_el]); if( u_cfg.fld().flg()&TCfg::Key && u_cfg.keyUse() ) { req = req + (next?" AND \"":"\"") + mod->sqlReqCode(cf_el[i_el],'"') + "\"='" + mod->sqlReqCode(getVal(u_cfg)) + "' "; next = true; } } req += ";"; try{ owner().sqlReq(req, NULL, true); } catch( TError err ) { if( (err.cod-100) == SQLITE_READONLY ) throw TError(TSYS::DBReadOnly,nodePath().c_str(),_("Deletion is not permitted. Data base is read only.")); throw; } }
bool MTable::fieldSeek( int i_ln, TConfig &cfg, vector< vector<string> > *full ) { int i_clm; ResAlloc res(mRes, false); if((i_ln=findKeyLine(cfg,i_ln,true)) < 0) return false; //Get config fields list vector<string> cf_el; cfg.cfgList(cf_el); //Seek and get data for(unsigned i_cf = 0; i_cf < cf_el.size(); i_cf++) { TCfg &e_cfg = cfg.cfg(cf_el[i_cf]); // Find collumn db_str_rec *fld_rec; for(i_clm = 0; (fld_rec=basa->getField(i_clm)) != NULL; i_clm++) if(cf_el[i_cf].compare(0,10,fld_rec->name) == 0) break; if(fld_rec == NULL) continue; // Get table volume string val; if(basa->GetFieldIt(i_ln,i_clm,val) < 0) throw err_sys(_("Error the cell.")); // Write value setVal(e_cfg, val); } return true; }
void MTable::fieldGet( TConfig &cfg ) { MtxAlloc resource(owner().connRes, true); if(!owner().enableStat()) return; mLstUse = SYS->sysTm(); vector<string> cf_el; //Request preparing cfg.cfgList(cf_el); char *attrs[cf_el.size()+1]; string fltr; int fltrN = 0; for(unsigned iC = 0, iA = 0; iC < cf_el.size(); iC++) { TCfg &cf = cfg.cfg(cf_el[iC]); if(cf.isKey()) { fltr += "("+cf_el[iC]+"="+getVal(cf)+")"; fltrN++; } else if(cf.view()) { attrs[iA++] = (char*)cf_el[iC].c_str(); attrs[iA] = NULL; setVal(cf, ""); //Clear from previous value } } if(fltrN > 1) fltr = "&"+fltr; if(fltr.empty()) fltr = "(objectclass=*)"; //Request int rez; LDAPMessage *result = NULL, *entry; try { if((rez=ldap_search_s(owner().ldp,("ou="+name()+","+owner().bdn).c_str(),LDAP_SCOPE_ONE,fltr.c_str(),attrs,0,&result)) != LDAP_SUCCESS) throw err_sys(_("SEARCH: %s"), ldap_err2string(rez)); if(!ldap_count_entries(owner().ldp,result) || !(entry=ldap_first_entry(owner().ldp,result))) throw err_sys(_("Entry \"%s\" is not present."), fltr.c_str()); char *a, **vals; BerElement *ber; for(a = ldap_first_attribute(owner().ldp,entry,&ber); a != NULL; a = ldap_next_attribute(owner().ldp,entry,ber)) { string attr = a; ldap_memfree(a); string val; if((vals=ldap_get_values(owner().ldp,entry,attr.c_str())) != NULL) { for(int iV = 0; vals[iV] != NULL; iV++) val += vals[iV]; ldap_value_free(vals); } TCfg *cf = NULL; //cfg.at(attr, true); for(unsigned iC = 0; iC < cf_el.size() && !cf; iC++) if(strcasecmp(attr.c_str(),cf_el[iC].c_str()) == 0) { cf = cfg.at(cf_el[iC], true); attr = cf_el[iC]; } if(cf) setVal(*cf, val); } ldap_msgfree(result); } catch(TError&) { if(result) ldap_msgfree(result); throw; } }
int MTable::findKeyLine( TConfig &cfg, int cnt, bool useKey, int off ) { int i_ln, i_clm, i_cnt = 0; mLstUse = time(NULL); //Get config fields list vector<string> cf_el; cfg.cfgList(cf_el); //Left only keys into list for(unsigned i_cf = 0; i_cf < cf_el.size(); ) if(cfg.cfg(cf_el[i_cf]).isKey()) i_cf++; else cf_el.erase(cf_el.begin()+i_cf); //Find want field for(i_ln = off; i_ln < basa->GetCountItems(); i_ln++) { int cnt_key = 0; for(unsigned i_cf = 0; i_cf < cf_el.size(); i_cf++) { if(useKey && !cfg.cfg(cf_el[i_cf]).keyUse()) { cnt_key++; continue; } //Check key // Find collumn db_str_rec *fld_rec; for(i_clm = 0; (fld_rec = basa->getField(i_clm)) != NULL; i_clm++) if(cf_el[i_cf].compare(0,10,fld_rec->name) == 0) break; if(fld_rec == NULL) throw err_sys(_("The key column '%s' is not present."), cf_el[i_cf].c_str()); // Get table volume string val; if(basa->GetFieldIt(i_ln,i_clm,val) < 0) throw err_sys(_("Error the cell.")); // Remove spaces from end int i; for(i = val.size(); i > 0 && val[i-1] == ' '; i--) ; if(i != (int)val.size()) val.resize(i); // Compare value if(val != cfg.cfg(cf_el[i_cf]).getS(TCfg::ExtValTwo)/*getVal(cfg.cfg(cf_el[i_cf]))*/) { cnt_key = 0; break; } cnt_key++; } if(cnt_key && cnt <= i_cnt++) break; } if(i_ln >= basa->GetCountItems()) return -1; return i_ln; }
void MTable::fieldSet( TConfig &cfg ) { int i_ln, i_clm; //Alloc resource ResAlloc res(mRes, true); //Get config fields list vector<string> cf_el; cfg.cfgList(cf_el); //Check for write access if(!(access(nTable.c_str(),F_OK|W_OK) == 0 || (access(nTable.c_str(),F_OK) != 0 && access(owner().addr().c_str(),W_OK) == 0))) throw err_sys(_("Access to the file '%s' is read only."), nTable.c_str()); bool forceUpdt = cfg.reqKeys(), appMode = forceUpdt || (cfg.incomplTblStruct() && !basa->isEmpty()); //Only for append no present fields //Check and fix structure of table for(unsigned i_cf = 0; i_cf < cf_el.size(); i_cf++) { TCfg &e_cfg = cfg.cfg(cf_el[i_cf]); // Find collumn db_str_rec *fld_rec; for(i_clm = 0;(fld_rec = basa->getField(i_clm)) != NULL;i_clm++) if(cf_el[i_cf].compare(0,10,fld_rec->name) == 0) break; if(fld_rec == NULL) { // Create new collumn db_str_rec n_rec; fieldPrmSet(e_cfg, n_rec); if(basa->addField(i_cf,&n_rec) < 0) throw err_sys(_("Error the column.")); } else if(!appMode) { // Check collumn parameters switch(e_cfg.fld().type()) { case TFld::String: if(fld_rec->tip_fild == 'C' && e_cfg.fld().len() == fld_rec->len_fild) continue; break; case TFld::Integer: if(fld_rec->tip_fild == 'N' && e_cfg.fld().len() == fld_rec->len_fild) continue; break; case TFld::Real: if(fld_rec->tip_fild == 'N' && e_cfg.fld().len() == fld_rec->len_fild && e_cfg.fld().dec() == fld_rec->dec_field) continue; break; case TFld::Boolean: if(fld_rec->tip_fild == 'L') continue; break; default: break; } db_str_rec n_rec; fieldPrmSet(e_cfg, n_rec); if(basa->setField(i_clm,&n_rec) < 0) throw err_sys(_("Error the column.")); } } //Del no used collumn db_str_rec *fld_rec; for(i_clm = 0; !appMode && (fld_rec=basa->getField(i_clm)) != NULL; i_clm++) { unsigned i_cf; for(i_cf = 0; i_cf < cf_el.size(); i_cf++) if(cf_el[i_cf].compare(0,10,fld_rec->name) == 0) break; if(i_cf >= cf_el.size() && basa->DelField(i_clm) < 0) throw err_sys(_("Error deleting the field.")); } //Write to all records //Get key line bool isEnd = false; for(i_ln = 0; !isEnd; i_ln++) { if((i_ln=findKeyLine(cfg,0,false,i_ln)) < 0) { if(forceUpdt) return; i_ln = basa->CreateItems(-1); } //Write data to bd for(unsigned i_cf = 0; i_cf < cf_el.size(); i_cf++) { TCfg &e_cfg = cfg.cfg(cf_el[i_cf]); if(!e_cfg.view()) continue; // Find collumn db_str_rec *fld_rec; for(i_clm = 0; (fld_rec=basa->getField(i_clm)) != NULL; i_clm++) if(cf_el[i_cf].compare(0,10,fld_rec->name) == 0) break; if(fld_rec == NULL) continue; // Set table volume if(basa->ModifiFieldIt(i_ln,i_clm,getVal(e_cfg,fld_rec).c_str()) < 0) throw err_sys(_("Error the cell.")); } if(!forceUpdt) isEnd = true; } mModify = SYS->sysTm(); }
void MTable::fieldFix( TConfig &cfg ) { bool fix = false; string all_flds; string req; bool isVarTextTransl = (!Mess->lang2CodeBase().empty() && !cfg.noTransl() && Mess->lang2Code() != Mess->lang2CodeBase()); //> Get config fields list vector<string> cf_el; cfg.cfgList(cf_el); if( !tblStrct.empty() ) { //> Check structure bool next = false; //>> Check present fields and find new fields for( unsigned i_cf = 0, i_fld; i_cf < cf_el.size(); i_cf++ ) { TCfg &u_cfg = cfg.cfg(cf_el[i_cf]); for( i_fld = 1; i_fld < tblStrct.size(); i_fld++ ) if( cf_el[i_cf] == tblStrct[i_fld][1] ) { all_flds = all_flds + (next?",\"":"\"") + mod->sqlReqCode(tblStrct[i_fld][1],'"') + "\""; next = true; if( !fix ) switch( u_cfg.fld().type() ) { case TFld::String: if( tblStrct[i_fld][2] != "TEXT") fix = true; break; case TFld::Integer: case TFld::Boolean: if( tblStrct[i_fld][2] != "INTEGER") fix = true; break; case TFld::Real: if( tblStrct[i_fld][2] != "DOUBLE" ) fix = true; break; default: fix = true; } //> Put other languages to all list an find column for current language if( u_cfg.fld().flg()&TCfg::TransltText ) { bool col_cur = false; for( unsigned i_c = i_fld; i_c < tblStrct.size(); i_c++ ) if( tblStrct[i_c][1].size() > 3 && tblStrct[i_c][1].substr(2) == ("#"+cf_el[i_cf]) && tblStrct[i_c][1].substr(0,2) != Mess->lang2Code() ) { all_flds = all_flds + ",\"" + mod->sqlReqCode(tblStrct[i_c][1],'"') + "\""; if( tblStrct[i_c][1].substr(0,2) == Mess->lang2Code() ) col_cur = true; } if( !col_cur && isVarTextTransl ) fix = true; } break; } if( i_fld >= tblStrct.size() ) fix = true; } //>> Check delete fields for( unsigned i_fld = 1, i_cf; i_fld < tblStrct.size() && !fix; i_fld++ ) { for( i_cf = 0; i_cf < cf_el.size(); i_cf++ ) if( cf_el[i_cf] == tblStrct[i_fld][1] || (cfg.cfg(cf_el[i_cf]).fld().flg()&TCfg::TransltText && tblStrct[i_fld][1].size() > 3 && tblStrct[i_fld][1].substr(2) == ("#"+cf_el[i_cf]) && tblStrct[i_fld][1].substr(0,2) != Mess->lang2Code()) ) break; if( i_cf >= cf_el.size() ) fix = true; } if( !fix ) return; //Structure OK! //>> Fix structure //>>> Move data to temporary DB req = "CREATE TEMPORARY TABLE 'temp_"+mod->sqlReqCode(name())+"'("+all_flds+");" "INSERT INTO 'temp_"+mod->sqlReqCode(name())+"' SELECT "+all_flds+" FROM '"+mod->sqlReqCode(name())+"';" "DROP TABLE '"+mod->sqlReqCode(name())+"';"; owner().sqlReq(req, NULL, false); } //> Create new table req = "CREATE TABLE IF NOT EXISTS '"+mod->sqlReqCode(name())+"' ("; bool next = false; bool next_key = false; string pr_keys, tpCfg; for( unsigned i_cf = 0; i_cf < cf_el.size(); i_cf++ ) { TCfg &cf = cfg.cfg(cf_el[i_cf]); req = req + (next?",\"":"\"") + mod->sqlReqCode(cf_el[i_cf],'"') + "\" "; next = true; //>> Type param switch(cf.fld().type()) { case TFld::String: tpCfg = "TEXT DEFAULT '" + mod->sqlReqCode(cf.fld().def()) + "' "; break; case TFld::Integer: case TFld::Boolean: tpCfg = "INTEGER DEFAULT '" + mod->sqlReqCode(cf.fld().def()) + "' "; break; case TFld::Real: tpCfg = "DOUBLE DEFAULT '" + mod->sqlReqCode(cf.fld().def()) + "' "; break; default: break; } req += tpCfg; //> Other languages for translation process if( cf.fld().flg()&TCfg::TransltText ) { bool col_cur = false; for( unsigned i_c = 1; i_c < tblStrct.size(); i_c++ ) if( tblStrct[i_c][1].size() > 3 && tblStrct[i_c][1].substr(2) == ("#"+cf_el[i_cf]) && tblStrct[i_c][1].substr(0,2) != Mess->lang2Code() ) { req = req + ",\"" + mod->sqlReqCode(tblStrct[i_c][1],'"') + "\" "+tpCfg; if( tblStrct[i_c][1].substr(0,2) == Mess->lang2Code() ) col_cur = true; } if( !col_cur && isVarTextTransl ) req = req + ",\"" + mod->sqlReqCode(Mess->lang2Code()+"#"+cf_el[i_cf],'"') + "\" "+tpCfg; } //>> Primary key else if( cf.fld().flg()&TCfg::Key ) { pr_keys = pr_keys + (next_key?",\"":"\"") + mod->sqlReqCode(cf_el[i_cf],'"') + "\""; next_key = true; } } req += ", PRIMARY KEY ("+pr_keys+"));"; owner().sqlReq(req, NULL, false); //> Copy data from temporary DB if( fix ) { req = "INSERT INTO '"+mod->sqlReqCode(name())+"'("+all_flds+") SELECT "+all_flds+" FROM 'temp_"+mod->sqlReqCode(name())+"';" "DROP TABLE 'temp_"+mod->sqlReqCode(name())+"';"; owner().sqlReq(req, NULL, false); } //> Update table structure req ="PRAGMA table_info('"+mod->sqlReqCode(name())+"');"; owner().sqlReq(req, &tblStrct, false); }
void MTable::fieldSet( TConfig &cfg ) { vector< vector<string> > tbl; if( tblStrct.empty() ) fieldFix(cfg); mLstUse = time(NULL); string sid, sval; bool isVarTextTransl = (!Mess->lang2CodeBase().empty() && !cfg.noTransl() && Mess->lang2Code() != Mess->lang2CodeBase()); //> Get config fields list vector<string> cf_el; cfg.cfgList(cf_el); //> Check for translation present bool trPresent = isVarTextTransl, trDblDef = false; for( unsigned i_fld = 1; i_fld < tblStrct.size(); i_fld++ ) { if( (trPresent || cfg.noTransl()) && (!isVarTextTransl || trDblDef) ) break; sid = tblStrct[i_fld][1]; if( sid.size() > 3 ) { if( !trPresent && sid.substr(0,3) == (Mess->lang2Code()+"#") ) trPresent = true; if( Mess->lang2Code() == Mess->lang2CodeBase() && !trDblDef && sid.compare(0,3,Mess->lang2CodeBase()+"#") == 0 ) trDblDef = true; } } if( trDblDef ) fieldFix(cfg); //> Get present fields list string req_where = "WHERE "; //>> Add key list to queue bool next = false; for( unsigned i_el = 0; i_el < cf_el.size(); i_el++ ) { TCfg &u_cfg = cfg.cfg(cf_el[i_el]); if( !(u_cfg.fld().flg()&TCfg::Key) ) continue; req_where = req_where + (next?" AND \"":"\"") + mod->sqlReqCode(cf_el[i_el],'"') + "\"='" + mod->sqlReqCode(getVal(u_cfg)) + "' "; next = true; } //> Prepare query string req = "SELECT 1 FROM '" + mod->sqlReqCode(name()) + "' " + req_where + ";"; try{ owner().sqlReq(req, &tbl, true); } catch(TError err) { if( (err.cod-100) == SQLITE_READONLY ) return; fieldFix(cfg); owner().sqlReq(req, NULL, true); } if( tbl.size() < 2 ) { //> Add new record req = "INSERT INTO '" + mod->sqlReqCode(name()) + "' "; string ins_name, ins_value; next = false; for( unsigned i_el = 0; i_el < cf_el.size(); i_el++ ) { TCfg &u_cfg = cfg.cfg(cf_el[i_el]); if( !(u_cfg.fld().flg()&TCfg::Key) && !u_cfg.view() ) continue; bool isTransl = (u_cfg.fld().flg()&TCfg::TransltText && trPresent && !u_cfg.noTransl()); ins_name = ins_name + (next?",\"":"\"") + mod->sqlReqCode(cf_el[i_el],'"') + "\" " + (isTransl ? (",\"" + mod->sqlReqCode(Mess->lang2Code()+"#"+cf_el[i_el],'"') + "\" ") : ""); sval = getVal(u_cfg); ins_value = ins_value + (next?",'":"'") + mod->sqlReqCode(sval) + "' " + (isTransl ? (",'" + mod->sqlReqCode(sval) + "' ") : ""); next = true; } req = req + "("+ins_name+") VALUES ("+ins_value+")"; } else { //> Update present record req = "UPDATE '" + mod->sqlReqCode(name()) + "' SET "; next = false; for( unsigned i_el = 0; i_el < cf_el.size(); i_el++ ) { TCfg &u_cfg = cfg.cfg(cf_el[i_el]); if( u_cfg.fld().flg()&TCfg::Key || !u_cfg.view() ) continue; bool isTransl = (u_cfg.fld().flg()&TCfg::TransltText && trPresent && !u_cfg.noTransl()); sid = isTransl ? (Mess->lang2Code()+"#"+cf_el[i_el]) : cf_el[i_el]; sval = getVal(u_cfg); req = req + (next?",\"":"\"") + mod->sqlReqCode(sid,'"') + "\"='" + mod->sqlReqCode(sval) + "' "; next = true; } req = req + req_where; } req += ";"; //> Query try { owner().sqlReq(req, NULL, true); } catch(TError err) { if( (err.cod-100) == SQLITE_READONLY ) return; fieldFix(cfg); owner().sqlReq(req, NULL, true); } }
void MTable::fieldSet( TConfig &cfg ) { MtxAlloc resource(owner().connRes, true); if(!owner().enableStat()) return; mLstUse = SYS->sysTm(); vector<string> cf_el; //Find for need entry // Request preparing cfg.cfgList(cf_el); char *attrs[cf_el.size()+1]; LDAPMod mods[cf_el.size()]; LDAPMod *mods_[cf_el.size()+1]; mods_[0] = NULL; string vals[cf_el.size()]; char *vals_[cf_el.size()][2]; string fltr; int fltrN = 0; for(unsigned iC = 0, iA = 0; iC < cf_el.size(); iC++) { TCfg &cf = cfg.cfg(cf_el[iC]); if(cf.isKey()) { fltr += "("+cf_el[iC]+"="+getVal(cf)+")"; fltrN++; } else if(cf.view()) { attrs[iA++] = (char*)cf_el[iC].c_str(); attrs[iA] = NULL; } } if(fltrN > 1) fltr = "&"+fltr; if(fltr.empty()) fltr = "(objectclass=*)"; // Request int rez; LDAPMessage *result = NULL, *entry; char *chDN = NULL; try { if((rez=ldap_search_s(owner().ldp,("ou="+name()+","+owner().bdn).c_str(),LDAP_SCOPE_ONE,fltr.c_str(),attrs,0,&result)) != LDAP_SUCCESS) throw err_sys(_("SEARCH: %s"), ldap_err2string(rez)); if(!ldap_count_entries(owner().ldp,result) || !(entry=ldap_first_entry(owner().ldp,result))) { ldap_msgfree(result); throw err_sys(_("Entry \"%s\" is not present."), fltr.c_str()); } //Get DN of the entry chDN = ldap_get_dn(owner().ldp, entry); if(!chDN) throw err_sys(_("Get DN of the entry \"%s\" error."), fltr.c_str()); //Check for changed attributes of the entry to replace their. int iA = 0; char *a, **tvals; BerElement *ber; for(a = ldap_first_attribute(owner().ldp,entry,&ber); a != NULL; a = ldap_next_attribute(owner().ldp,entry,ber)) { string attr = a; ldap_memfree(a); string val; if((tvals=ldap_get_values(owner().ldp,entry,attr.c_str())) != NULL) { for(int iV = 0; tvals[iV] != NULL; iV++) val += tvals[iV]; ldap_value_free(tvals); } TCfg *cf = NULL; //cfg.at(attr, true); unsigned iC = 0; for( ; iC < cf_el.size(); iC++) if(strcasecmp(attr.c_str(),cf_el[iC].c_str()) == 0) { cf = cfg.at(cf_el[iC], true); attr = cf_el[iC]; break; } if(cf && (vals[iA]=getVal(*cf)) != val) { vals_[iA][0] = (char*)vals[iA].c_str(); vals_[iA][1] = NULL; mods[iA].mod_op = LDAP_MOD_REPLACE; mods[iA].mod_type = (char*)cf_el[iC].c_str(); mods[iA].mod_values = vals_[iA]; mods_[iA] = &mods[iA]; mods_[++iA] = NULL; } } //Call the generic modify request if((rez=ldap_modify_s(owner().ldp,chDN,mods_)) != LDAP_SUCCESS) throw err_sys(_("MODIFY: %s"), ldap_err2string(rez)); ldap_memfree(chDN); ldap_msgfree(result); } catch(TError&) { if(chDN) ldap_memfree(chDN); if(result) ldap_msgfree(result); throw; } }
bool MTable::fieldSeek( int row, TConfig &cfg, vector< vector<string> > *full ) { MtxAlloc resource(owner().connRes, true); if(!owner().enableStat()) return false; mLstUse = SYS->sysTm(); vector< vector<string> > inTbl, &tbl = full ? *full : inTbl; //Request if(!full || !full->size() || row == 0) { tbl.clear(); vector<string> row, cf_el; // Request preparing map<string,int> headers; cfg.cfgList(cf_el); char *attrs[cf_el.size()+1]; row.reserve(cf_el.size()); string fltr; int fltrN = 0; for(unsigned iC = 0, iA = 0; iC < cf_el.size(); iC++) { TCfg &cf = cfg.cfg(cf_el[iC]); if(cf.isKey() && cf.keyUse()) { fltr += "("+cf_el[iC]+"="+getVal(cf)+")"; fltrN++; } else if(cf.isKey() || cf.view()) { headers[cf_el[iC]] = row.size(); row.push_back(cf_el[iC]); attrs[iA++] = (char*)cf_el[iC].c_str(); attrs[iA] = NULL; } } tbl.push_back(row); if(fltrN > 1) fltr = "&"+fltr; if(fltr.empty())fltr = "(objectclass=*)"; // Request LDAPMessage *result, *entry; if(ldap_search_s(owner().ldp,("ou="+name()+","+owner().bdn).c_str(),LDAP_SCOPE_ONE,fltr.c_str(),attrs,0,&result) != LDAP_SUCCESS) return false; for(entry = ldap_first_entry(owner().ldp,result); entry; entry = ldap_next_entry(owner().ldp,entry)) { row.clear(); row.resize(headers.size()); char *a, **vals; BerElement *ber; bool entrMatch = true; for(a = ldap_first_attribute(owner().ldp,entry,&ber); a != NULL && entrMatch; a = ldap_next_attribute(owner().ldp,entry,ber)) { string attr = a; ldap_memfree(a); string val; if((vals=ldap_get_values(owner().ldp,entry,attr.c_str())) != NULL) { for(int iV = 0; vals[iV] != NULL; iV++) val += vals[iV]; ldap_value_free(vals); } TCfg *cf = NULL; //cfg.at(attr, true); for(unsigned iC = 0; iC < cf_el.size() && !cf; iC++) if(strcasecmp(attr.c_str(),cf_el[iC].c_str()) == 0) { cf = cfg.at(cf_el[iC], true); attr = cf_el[iC]; } if(cf) { if(cf->isKey() && (val.empty() || (cf->keyUse() && getVal(*cf) != val))) entrMatch = false; if(headers.find(attr) != headers.end()) row[headers[attr]] = val; } } if(entrMatch) { // Late checking for keys for(unsigned iC = 0; iC < cf_el.size() && entrMatch; iC++) { TCfg &cf = cfg.cfg(cf_el[iC]); if(cf.isKey() && !cf.keyUse() && row[headers[cf_el[iC]]].empty()) entrMatch = false; } if(entrMatch) tbl.push_back(row); } } ldap_msgfree(result); } if(tbl.size() < 2 || (full && (row+1) >= tbl.size())) return false; //Processing of the query row = full ? row+1 : 1; for(unsigned iFld = 0; iFld < tbl[0].size(); iFld++) { string sid = tbl[0][iFld]; TCfg *cf = cfg.at(sid, true); if(cf) setVal(*cf, tbl[row][iFld]); } return true; }
void MTable::fieldFix( TConfig &cfg ) { bool toUpdate = false, appMode = cfg.reqKeys() || (cfg.incomplTblStruct() && !tblStrct.empty()), //Only for append no present fields isVarTextTransl = (!Mess->lang2CodeBase().empty() && Mess->lang2Code() != Mess->lang2CodeBase()); //Get config fields list vector<string> cf_el; cfg.cfgList(cf_el); //Create request variables string all_flds, pr_keys, tpCfg, req, crtReq = "CREATE TABLE IF NOT EXISTS '" + mod->sqlReqCode(name()) + "' ("; bool next = false, next_key = false; //Curent context copy list if(appMode) { if(tblStrct.empty()) return; for(unsigned i_fld = 1; i_fld < tblStrct.size(); i_fld++) { all_flds += (all_flds.size()?",\"":"\"") + mod->sqlReqCode(tblStrct[i_fld][1],'"') + "\""; crtReq += (next?",\"":"\"") + mod->sqlReqCode(tblStrct[i_fld][1],'"') + "\" "+ tblStrct[i_fld][2]+" DEFAULT " + tblStrct[i_fld][4] + " "; next = true; if(tblStrct[i_fld][5] == "1") { pr_keys += (next_key?",\"":"\"") + mod->sqlReqCode(tblStrct[i_fld][1],'"') + "\""; next_key = true; } } } //Check for need append or modify for(unsigned i_cf = 0, i_fld; i_cf < cf_el.size(); i_cf++) { TCfg &cf = cfg.cfg(cf_el[i_cf]); // Check for update needs for(i_fld = 1; i_fld < tblStrct.size(); i_fld++) if(cf_el[i_cf] == tblStrct[i_fld][1]) { if(appMode) break; switch(cf.fld().type()) { case TFld::String: if(tblStrct[i_fld][2] != "TEXT") toUpdate = true; break; case TFld::Integer: case TFld::Boolean: if(tblStrct[i_fld][2] != "INTEGER") toUpdate = true; break; case TFld::Real: if(tblStrct[i_fld][2] != "DOUBLE") toUpdate = true; break; default: toUpdate = true; } all_flds += (all_flds.size()?",\"":"\"") + mod->sqlReqCode(tblStrct[i_fld][1],'"') + "\""; break; } // Type switch(cf.fld().type()) { case TFld::String: tpCfg = "TEXT DEFAULT '" + mod->sqlReqCode(cf.fld().def()) + "' "; break; case TFld::Integer: case TFld::Boolean: tpCfg = "INTEGER DEFAULT '" + mod->sqlReqCode(cf.fld().def()) + "' "; break; case TFld::Real: tpCfg = "DOUBLE DEFAULT '" + mod->sqlReqCode(cf.fld().def()) + "' "; break; default: break; } // Append if(i_fld >= tblStrct.size() || !appMode) { crtReq += (next?",\"":"\"") + mod->sqlReqCode(cf_el[i_cf],'"') + "\" " + tpCfg; next = true; if(i_fld >= tblStrct.size()) toUpdate = true; } // Other languages for translation process if(cf.fld().flg()&TCfg::TransltText) { bool col_cur = false; for(unsigned i_c = 1; i_c < tblStrct.size(); i_c++) if(tblStrct[i_c][1].size() > 3 && tblStrct[i_c][1].substr(2) == ("#"+cf_el[i_cf])) { all_flds += ",\"" + mod->sqlReqCode(tblStrct[i_c][1],'"') + "\""; crtReq += ",\"" + mod->sqlReqCode(tblStrct[i_c][1],'"') + "\" " + tpCfg; if(tblStrct[i_c][1].compare(0,2,Mess->lang2Code()) == 0) col_cur = true; } if(!col_cur && isVarTextTransl) { toUpdate = true; crtReq += ",\"" + mod->sqlReqCode(Mess->lang2Code()+"#"+cf_el[i_cf],'"') + "\" " + tpCfg; } } // Primary key else if(cf.fld().flg()&TCfg::Key && !appMode) { pr_keys += (next_key?",\"":"\"") + mod->sqlReqCode(cf_el[i_cf],'"') + "\""; next_key = true; } } //Check deleted fields for(unsigned i_fld = 1, i_cf; i_fld < tblStrct.size() && !toUpdate && !appMode; i_fld++) { for(i_cf = 0; i_cf < cf_el.size(); i_cf++) if(cf_el[i_cf] == tblStrct[i_fld][1] || (cfg.cfg(cf_el[i_cf]).fld().flg()&TCfg::TransltText && tblStrct[i_fld][1].size() > 3 && tblStrct[i_fld][1].substr(2) == ("#"+cf_el[i_cf]) && tblStrct[i_fld][1].compare(0,2,Mess->lang2Code()) != 0)) break; if(i_cf >= cf_el.size()) toUpdate = true; } if(!toUpdate) return; //Copy need for save to temporary table if(all_flds.size()) { req = "CREATE TEMPORARY TABLE 'temp_" + mod->sqlReqCode(name()) + "'(" + all_flds + ");" "INSERT INTO 'temp_" + mod->sqlReqCode(name()) + "' SELECT " + all_flds + " FROM '" + mod->sqlReqCode(name()) + "';" "DROP TABLE '" + mod->sqlReqCode(name()) + "';"; owner().sqlReq(req, NULL, true); } //Create new, updated table crtReq += ", PRIMARY KEY (" + pr_keys + "));"; owner().sqlReq(crtReq, NULL, true); //Restore data from temporary table if(all_flds.size()) { req = "INSERT INTO '" + mod->sqlReqCode(name()) + "'(" + all_flds + ") SELECT " + all_flds + " FROM 'temp_" + mod->sqlReqCode(name()) + "';DROP TABLE 'temp_" + mod->sqlReqCode(name()) + "';"; owner().sqlReq(req, NULL, true); } //Update the table structure req = "PRAGMA table_info('" + mod->sqlReqCode(name()) + "');"; owner().sqlReq(req, &tblStrct, false); }
void MTable::fieldSet( TConfig &cfg ) { vector< vector<string> > tbl; if(tblStrct.empty()) { if(cfg.reqKeys()) return; fieldFix(cfg); } mLstUse = SYS->sysTm(); string sid, sval; bool isVarTextTransl = (!Mess->lang2CodeBase().empty() && Mess->lang2Code() != Mess->lang2CodeBase()); //Get config fields list vector<string> cf_el; cfg.cfgList(cf_el); //Check for translation present bool trPresent = isVarTextTransl, trDblDef = false; for(unsigned i_fld = 1; i_fld < tblStrct.size(); i_fld++) { if(trPresent && (!isVarTextTransl || trDblDef)) break; sid = tblStrct[i_fld][1]; if(sid.size() > 3) { if(!trPresent && !Mess->translDyn() && sid.compare(0,3,Mess->lang2Code()+"#") == 0) trPresent = true; if(Mess->lang2Code() == Mess->lang2CodeBase() && !trDblDef && sid.compare(0,3,Mess->lang2CodeBase()+"#") == 0) trDblDef = true; } } if(trDblDef && !cfg.reqKeys()) fieldFix(cfg); //Get present fields list string req_where = "WHERE "; // Add key list to queue bool next = false, noKeyFld = false, isForceUpdt = cfg.reqKeys(); //Force update by ReqKeys or reqKey() present for(unsigned i_el = 0; i_el < cf_el.size(); i_el++) { TCfg &u_cfg = cfg.cfg(cf_el[i_el]); if(!u_cfg.isKey()) continue; req_where += (next?" AND \"":"\"") + mod->sqlReqCode(cf_el[i_el],'"') + "\"=" + getVal(u_cfg,true,TCfg::DblValTwo); next = true; if(!isForceUpdt && u_cfg.dblVal()) isForceUpdt = true; // Check for no key fields if(noKeyFld) continue; unsigned i_fld = 1; for( ; i_fld < tblStrct.size(); i_fld++) if(u_cfg.name() == tblStrct[i_fld][1]) break; if(i_fld >= tblStrct.size()) noKeyFld = true; } if(noKeyFld) { if(cfg.reqKeys()) return; fieldFix(cfg); } //Prepare query for presenting detect string req; if(!isForceUpdt) { req = "SELECT 1 FROM '" + mod->sqlReqCode(name()) + "' " + req_where + ";"; owner().sqlReq(req, &tbl, true); if(tbl.size() < 2) { //Add new record req = "INSERT INTO '" + mod->sqlReqCode(name()) + "' "; string ins_name, ins_value; next = false; for(unsigned i_el = 0; i_el < cf_el.size(); i_el++) { TCfg &u_cfg = cfg.cfg(cf_el[i_el]); if(!u_cfg.isKey() && !u_cfg.view()) continue; bool isTransl = (u_cfg.fld().flg()&TCfg::TransltText && trPresent && !u_cfg.noTransl()); ins_name += (next?",\"":"\"") + mod->sqlReqCode(cf_el[i_el],'"') + "\" " + (isTransl ? (",\""+mod->sqlReqCode(Mess->lang2Code()+"#"+cf_el[i_el],'"')+"\" ") : ""); sval = getVal(u_cfg); ins_value += (next?",":"") + sval + " " + (isTransl?(","+sval+" "):""); next = true; } req += "(" + ins_name + ") VALUES (" + ins_value + ")"; } else isForceUpdt = true; } //Update present record if(isForceUpdt) { req = "UPDATE '" + mod->sqlReqCode(name()) + "' SET "; next = false; for(unsigned i_el = 0; i_el < cf_el.size(); i_el++) { TCfg &u_cfg = cfg.cfg(cf_el[i_el]); if((u_cfg.isKey() && !u_cfg.dblVal()) || !u_cfg.view()) continue; bool isTransl = (u_cfg.fld().flg()&TCfg::TransltText && trPresent && !u_cfg.noTransl()); sid = isTransl ? (Mess->lang2Code()+"#"+cf_el[i_el]) : cf_el[i_el]; req += (next?",\"":"\"") + mod->sqlReqCode(sid,'"') + "\"=" + getVal(u_cfg) + " "; next = true; } req += req_where; } req += ";"; //Query try { owner().sqlReq(req, NULL, true); } catch(TError err) { if((err.cod-100) == SQLITE_READONLY) throw; fieldFix(cfg); owner().sqlReq(req, NULL, true); } }
bool MTable::fieldSeek( int row, TConfig &cfg ) { vector< vector<string> > tbl; if(tblStrct.empty()) throw TError(nodePath().c_str(), _("Table is empty.")); mLstUse = SYS->sysTm(); //Check for no present and no empty keys allow if(row == 0) { vector<string> cf_el; cfg.cfgList(cf_el); for(unsigned i_c = 0; i_c < cf_el.size(); i_c++) { TCfg &cf = cfg.cfg(cf_el[i_c]); if(!cf.isKey() || !cf.getS().size()) continue; unsigned i_fld = 1; for( ; i_fld < tblStrct.size(); i_fld++) if(cf.name() == tblStrct[i_fld][1]) break; if(i_fld >= tblStrct.size()) return false; } } string sid; //Make WHERE string req = "SELECT "; string req_where = "WHERE "; // Add use keys to list bool first_sel = true, next = false, trPresent = false; for(unsigned i_fld = 1; i_fld < tblStrct.size(); i_fld++) { sid = tblStrct[i_fld][1]; TCfg *u_cfg = cfg.at(sid,true); if(!u_cfg && !Mess->translDyn() && sid.compare(0,3,Mess->lang2Code()+"#") == 0) { u_cfg = cfg.at(sid.substr(3),true); if(u_cfg && !(u_cfg->fld().flg()&TCfg::TransltText)) continue; trPresent = true; } if(!u_cfg) continue; if(u_cfg->isKey() && u_cfg->keyUse()) { req_where += (next?" AND \"":"\"") + mod->sqlReqCode(sid,'"') + "\"=" + getVal(*u_cfg) + " "; next = true; } else if(u_cfg->isKey() || u_cfg->view()) { req += (first_sel?"\"":",\"")+mod->sqlReqCode(sid,'"')+"\""; first_sel = false; } } //Request if(first_sel) return false; req += " FROM '" + mod->sqlReqCode(name()) + "' " + ((next)?req_where:"") + " LIMIT " + i2s(row) + ",1;"; owner().sqlReq(req, &tbl/*, false*/); // For seek to deletion into save context do not set to "false" if(tbl.size() < 2) return false; //Processing of the query for(unsigned i_fld = 0; i_fld < tbl[0].size(); i_fld++) { sid = tbl[0][i_fld]; TCfg *u_cfg = cfg.at(sid, true); if(u_cfg) setVal(*u_cfg, tbl[1][i_fld]); else if(trPresent && sid.compare(0,3,Mess->lang2Code()+"#") == 0 && tbl[1][i_fld].size() && (u_cfg=cfg.at(sid.substr(3),true))) setVal(*u_cfg, tbl[1][i_fld], true); } return true; }
bool MTable::fieldSeek( int row, TConfig &cfg, vector< vector<string> > *full ) { vector< vector<string> > inTbl, &tbl = full ? *full : inTbl; if(tblStrct.empty()) throw err_sys(_("Table is empty.")); mLstUse = SYS->sysTm(); //Check for not present and not empty keys allow if(row == 0) { vector<string> cf_el; cfg.cfgList(cf_el); for(unsigned iC = 0; iC < cf_el.size(); iC++) { TCfg &cf = cfg.cfg(cf_el[iC]); if(!cf.isKey() || !cf.getS().size()) continue; unsigned iFld = 1; for( ; iFld < tblStrct.size(); iFld++) if(cf.name() == tblStrct[iFld][1]) break; if(iFld >= tblStrct.size()) return false; } } string sid; //Make WHERE string req = "SELECT "; string req_where = "WHERE "; // Add use keys to list bool first_sel = true, next = false, trPresent = false; for(unsigned iFld = 1; iFld < tblStrct.size(); iFld++) { sid = tblStrct[iFld][1]; TCfg *u_cfg = cfg.at(sid, true); if(!u_cfg && !Mess->translDyn() && sid.compare(0,3,Mess->lang2Code()+"#") == 0) { u_cfg = cfg.at(sid.substr(3),true); if(u_cfg && !(u_cfg->fld().flg()&TFld::TransltText)) continue; trPresent = true; } if(!u_cfg) continue; if(u_cfg->isKey() && u_cfg->keyUse()) { req_where += (next?" AND \"":"\"") + TSYS::strEncode(sid,TSYS::SQL,"\"") + "\"=" + getVal(*u_cfg) + " "; next = true; } else if(u_cfg->isKey() || u_cfg->view()) { req += (first_sel?"\"":",\"")+TSYS::strEncode(sid,TSYS::SQL,"\"")+"\""; first_sel = false; } } //Request if(!full || !full->size() || (row%SEEK_PRELOAD_LIM) == 0) { if(first_sel) return false; req += " FROM '" + TSYS::strEncode(name(),TSYS::SQL,"'") + "' " + ((next)?req_where:""); if(!full) req += " LIMIT " + i2s(row) + ",1"; else req += " LIMIT " + i2s((row/SEEK_PRELOAD_LIM)*SEEK_PRELOAD_LIM) + "," + i2s(SEEK_PRELOAD_LIM); req += ";"; tbl.clear(); owner().sqlReq(req, &tbl/*, false*/); // For seek to deletion into save context do not set to "false" } row = full ? (row%SEEK_PRELOAD_LIM)+1 : 1; if(tbl.size() < 2 || (full && row >= (int)tbl.size())) return false; //Processing of the query for(unsigned iFld = 0; iFld < tbl[0].size(); iFld++) { sid = tbl[0][iFld]; TCfg *u_cfg = cfg.at(sid, true); if(u_cfg) setVal(*u_cfg, tbl[row][iFld]); else if(trPresent && sid.compare(0,3,Mess->lang2Code()+"#") == 0 && tbl[row][iFld].size() && (u_cfg=cfg.at(sid.substr(3),true))) setVal(*u_cfg, tbl[row][iFld], true); } return true; }