hce-node application  1.4.3
HCE Hierarchical Cluster Engine node application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SphinxAdminCommand.cpp
Go to the documentation of this file.
1 #include <fstream>
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <dirent.h>
5 #include <errno.h>
6 
7 #include <Poco/JSON/Object.h>
8 #include <Poco/JSON/Array.h>
9 #include <Poco/JSON/JSON.h>
10 #include <Poco/JSON/Stringifier.h>
11 #include <Poco/JSON/Parser.h>
12 #include <Poco/JSON/JSONException.h>
13 #include <Poco/Dynamic/Var.h>
14 #include <Poco/URI.h>
15 #include <Poco/String.h>
16 
17 #include "EncodeDecodeBase64.hpp"
18 #include "SphinxAdminCommand.hpp"
19 #include "SphinxDataSource.hpp"
20 #include "SphinxDataFile.hpp"
21 #include "SphinxSchemaFile.hpp"
22 #include "SphinxError.hpp"
23 #include "ProcExec.hpp"
24 #include "SphinxConfigCreator.hpp"
25 #include "XMLCleaner.hpp"
27 #include "SphinxConfigOptions.hpp"
28 #include "SphinxMessageConst.hpp"
29 
30 namespace HCE
31 {
32 namespace sphinx
33 {
34 //-----------------------------------------------------------------------------
36 : inherited(), fObj(fObj_), resultData(""), message(fObj.getCustomMessage())
37 {
38 }
39 //-----------------------------------------------------------------------------
40 bool SphinxAdminCommand::makeDir(const std::string& path)
41 {
42  bool result = false;
43  mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
44  struct stat st;
45 
46  if (stat(path.c_str(), &st) != 0)
47  {
48  if (mkdir(path.c_str(), mode) != 0)
49  errorMsg = strerror(errno);
50  else
51  result = true;
52  }
53  else if (!S_ISDIR(st.st_mode))
54  {
55  errorMsg = strerror(ENOTDIR);
56  }
57 
58  if (!result)
60 
61  return result;
62 }
63 //-----------------------------------------------------------------------------
64 bool SphinxAdminCommand::cleanDir(const std::string& path)
65 {
66  bool result = false;
67  if (isExistDir(path))
68  {
69  struct dirent* ent = nullptr;
70  DIR* dir = opendir (path.c_str());
71  if (dir != nullptr)
72  {
73  result = true;
74  std::string fileName;
75  while ((ent = readdir (dir)) != nullptr)
76  {
77  fileName = ent->d_name;
78  if (fileName != "." && fileName != "..")
79  {
80  fileName = path+"/"+ent->d_name;
81 
82  if (remove(fileName.c_str())==-1)
83  result = false;
84  }
85  }
86  if (closedir(dir)==-1)
87  result = false;
88  }
89  }
90  if (!result)
91  {
93  errorMsg = strerror(errno);
94  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::ERROR_CLEAN_DIR, errorMsg) << flush;
95  }
96  return result;
97 }
98 //-----------------------------------------------------------------------------
99 bool SphinxAdminCommand::isExistDir(const std::string& path)
100 {
101  bool result = false;
102  DIR* dir = nullptr;
103 
104  dir = opendir (path.c_str());
105  if (dir != nullptr)
106  {
107  if (closedir(dir)==-1)
108  errorMsg = strerror(errno);
109  else
110  result = true;
111  }
112  else
113  {
114  if (errno!=ENOENT)
115  errorMsg = strerror(errno);
116  }
117 
118  return result;
119 }
120 //-----------------------------------------------------------------------------
121 bool SphinxAdminCommand::isExistFile(const std::string& file)
122 {
123  return (access(file.c_str(), F_OK)==0);
124 }
125 //-----------------------------------------------------------------------------
126 bool SphinxAdminCommand::isAllowedString(const std::string& str)
127 {
128  return (str.find_first_not_of(sphinx_admin_command_const::allowedSimbols)==std::string::npos);
129 }
130 //-----------------------------------------------------------------------------
131 bool SphinxAdminCommand::copyFile(const std::string& srcFile, const std::string& dstFile)
132 {
133  bool result = false;
134  try
135  {
136  if (!isExistFile(srcFile))
137  throw Poco::Exception(srcFile+" not exists", ERROR_COPY_FILE);
138 
139  std::string cmd("cp");
140  std::vector<std::string> args = {srcFile, dstFile};
141 
142  std::stringstream outMsg;
143  ProcExec procExec(cmd, args);
144  if (!procExec.exec(outMsg, outMsg))
145  throw Poco::Exception("Copy '"+srcFile+"' to '"+dstFile+"' fail", ERROR_COPY_FILE);
146 
147  if (isExistError(outMsg.str()))
148  throw Poco::Exception(outMsg.str(), ERROR_COPY_FILE);
149 
150  result = true;
151  }
152  catch(Poco::Exception& e)
153  {
154  errorMsg = e.message();
155  errorCode = e.code();
156  }
157  return result;
158 }
159 //-----------------------------------------------------------------------------
160 bool SphinxAdminCommand::moveFile(const std::string& srcFile, const std::string& dstFile)
161 {
162  bool result = false;
163  try
164  {
165  if (!isExistFile(srcFile))
166  throw Poco::Exception(srcFile+" not exists", ERROR_MOVE_FILE);
167 
168  std::string cmd("mv");
169  std::vector<std::string> args = {srcFile, dstFile};
170 
171  std::stringstream outMsg;
172  ProcExec procExec(cmd, args);
173  if (!procExec.exec(outMsg, outMsg))
174  throw Poco::Exception("Move '"+srcFile+"' to '"+dstFile+"' fail", ERROR_MOVE_FILE);
175 
176  if (isExistError(outMsg.str()))
177  throw Poco::Exception(outMsg.str(), ERROR_MOVE_FILE);
178 
179  result = true;
180  }
181  catch(Poco::Exception& e)
182  {
183  errorMsg = e.message();
184  errorCode = e.code();
185  }
186  return result;
187 }
188 //-----------------------------------------------------------------------------
189 bool SphinxAdminCommand::removeFile(const std::string& file)
190 {
191  bool result = false;
192  if (remove(file.c_str())==0)
193  result = true;
194  else
195  {
196  errorMsg = strerror(errno);
198  }
199  return result;
200 }
201 //-----------------------------------------------------------------------------
202 bool SphinxAdminCommand::moveIndexFiles(const std::string& indexFileName, const std::string& srcPath, const std::string& dstPath)
203 {
204  errorMsg.clear();
205  bool result = false;
206 
207  struct dirent *d;
208  DIR* dir = opendir(srcPath.c_str());
209  if (dir != NULL)
210  {
211  result = true;
212  std::string oldName, newName;
213  while((d = readdir(dir)))
214  {
215  oldName = d->d_name;
216  if (oldName.find(indexFileName) != std::string::npos)
217  {
218  oldName = srcPath + "/" + d->d_name;
219  newName = dstPath + "/" + d->d_name;
220  if (!moveFile(oldName, newName))
221  {
222  result = false;
223  break;
224  }
225  }
226  }
227  if (closedir(dir)==-1)
228  {
229  errorMsg.append(" ").append(strerror(errno));
230  result = false;
231  }
232  }
233  return result;
234 }
235 //-----------------------------------------------------------------------------
236 bool SphinxAdminCommand::copyIndexFiles(const std::string& indexFileName, const std::string& srcPath, const std::string& dstPath)
237 {
238  errorMsg.clear();
239  bool result = false;
240 
241  struct dirent *d;
242  DIR* dir = opendir(srcPath.c_str());
243  if (dir != NULL)
244  {
245  result = true;
246  std::string oldName, newName;
247  while((d = readdir(dir)))
248  {
249  oldName = d->d_name;
250  if (oldName.find(indexFileName) != std::string::npos)
251  {
252  oldName = srcPath + "/" + d->d_name;
253  newName = dstPath + "/" + d->d_name;
254  if (!copyFile(oldName, newName))
255  {
256  result = false;
257  break;
258  }
259  }
260  }
261  if (closedir(dir)==-1)
262  {
263  errorMsg.append(" ").append(strerror(errno));
264  result = false;
265  }
266  }
267  return result;
268 }
269 //-----------------------------------------------------------------------------
270 bool SphinxAdminCommand::removeIndexFile(const std::string& indexFileName, const std::string& path)
271 {
272  errorMsg.clear();
273  bool result = false;
274 
275  struct dirent *d;
276  DIR* dir = opendir(path.c_str());
277  if (dir != NULL)
278  {
279  result = true;
280  std::string fileName;
281  std::vector<std::string> files;
282  while((d = readdir(dir)))
283  {
284  fileName = d->d_name;
285  if (fileName.compare(0, indexFileName.length(), indexFileName)==0)
286  {
287  if (!(d->d_name == std::string(".") || d->d_name == std::string("..")))
288  {
289  fileName = path + "/" + d->d_name;
290  files.push_back(fileName);
291  }
292  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::FOUND_INDEX_FILE, fileName) << flush;
293  }
294  }
295  if (closedir(dir)==-1)
296  {
297  errorMsg.append(" ").append(strerror(errno));
298  result = false;
299  }
300  // remove all found index files
301  for (size_t i=0;i<files.size();++i)
302  {
303  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::REMOVE_INDEX_FILE, files[i]) << flush;
304  if (remove(files[i].c_str())!=0)
305  {
306  result = false;
308  }
309  }
310  }
311  else
313 
314  if (!errorMsg.empty())
315  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::REMOVE_INDEX_FILE, errorMsg) << flush;
316 
317  return result;
318 }
319 //-----------------------------------------------------------------------------
320 bool SphinxAdminCommand::getFileList(const std::string& path, std::vector<std::string>& vFiles, const std::string& ext)
321 {
322  bool result = false;
323  DIR* dir = nullptr;
324 
325  std::string findExtension = "."+ext;
326  dir = opendir (path.c_str());
327  if (dir != nullptr)
328  {
329  struct dirent* ent = nullptr;
330  while ((ent = readdir (dir)) != nullptr)
331  {
332  std::string sourceFileName(ent->d_name);
333  size_t found = sourceFileName.find(findExtension);
334  if (found !=std::string::npos)
335  {
336  sourceFileName = sourceFileName.substr(0, found);
337  vFiles.push_back(sourceFileName);
338  }
339  }
340  if (closedir(dir)==-1)
341  errorMsg = strerror(errno);
342  else
343  result = true;
344  }
345  else
346  errorMsg = strerror(errno);
347 
348  if (!result)
349  {
351  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::ERROR_GET_FILE_LIST, errorMsg) << flush;
352  }
353 
354  return result;
355 }
356 //-----------------------------------------------------------------------------
357 bool SphinxAdminCommand::getIndexList(const std::string& path, std::vector<std::string>& vIndexes)
358 {
359  vIndexes.clear();
360  bool result = false;
361  DIR* dir = nullptr;
362  struct dirent* ent = nullptr;
363 
364  dir = opendir (path.c_str());
365  if (dir != nullptr)
366  {
367  std::set<std::string> sIndexes;
368  std::string fileName;
369  while ((ent = readdir (dir)) != nullptr)
370  {
371  if (!(ent->d_name == std::string(".") || ent->d_name == std::string("..")))
372  {
373  fileName = ent->d_name;
374  size_t found = fileName.find_last_of('.');
375  if (found!=std::string::npos)
376  {
377  sIndexes.insert(fileName.substr(0, found));
378  }
379  }
380  }
381  if (closedir(dir)==-1)
382  errorMsg = strerror(errno);
383  else
384  {
385  vIndexes.assign(sIndexes.begin(), sIndexes.end());
386  result = true;
387  }
388  }
389  else
390  errorMsg = strerror(errno);
391 
392  if (!result)
393  {
395  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::ERROR_GET_INDEX_LIST, errorMsg) << flush;
396  }
397 
398  return result;
399 }
400 //-----------------------------------------------------------------------------
402 {
403  bool result = false;
404 
405  try
406  {
407  if (fObj.getDataDir().empty())
408  throw Poco::Exception(message(message_const::EMPTY_DATA_DIR));
409 
410  std::set<unsigned int> ports;
411  DIR* dir = nullptr;
412  struct dirent* ent = nullptr;
413 
414  dir = opendir (fObj.getDataDir().c_str());
415  if (dir == nullptr)
416  throw Poco::Exception(message(message_const::OPEN_DIR_FAIL, fObj.getDataDir())+message(message_const::ERROR, strerror(errno)));
417 
418  Poco::AutoPtr<SphinxConfigCreator> pConf = nullptr;
419  while ((ent = readdir (dir)) != nullptr)
420  {
421  std::string name = ent->d_name;
422  if (!(name=="."||name==".."))
423  {
424  if (isExistDir(fObj.getDataDir()+"/"+name))
425  {
426  const std::string propFile = fObj.getDataDir()+"/"+ent->d_name+"/"+sphinx_search_const::sphinxPropertyFile;
427 
428  try
429  {
430  pConf = new SphinxConfigCreator(propFile);
431 
432  std::string host;
433  unsigned int port;
435  ports.insert(port);
436  }
437  catch(std::exception& exc)
438  {
439  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::TRY_OPEN_FILE_FAIL, propFile) << message(message_const::ERROR, exc.what()) << flush;
440  }
441  }
442  else
443  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::TRY_USE_AS_DIRECTORY_WAS_CANCELED) << "'" << fObj.getDataDir() << "/" << name << "'" << flush;
444  }
445  }
446 
447  if (closedir(dir)==-1)
448  throw Poco::Exception(message(message_const::CLOSE_DIR_FAIL)+message(message_const::ERROR, strerror(errno)));
449 
451  {
452  std::set<unsigned int>::iterator iter = ports.find(i);
453  if (iter==ports.end())
454  {
455  res = i;
456  break;
457  }
458  }
459  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::FOUND_FREE_ALLOWED_PORT, res) << flush;
460  result = true;
461  }
462  catch(Poco::Exception& e)
463  {
464  errorMsg = e.message();
466  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::ERROR_GET_FREE_ALLOWED_PORT, errorMsg) << flush;
467  }
468  return result;
469 }
470 //-----------------------------------------------------------------------------
471 bool SphinxAdminCommand::makeTrunkConfig(const std::string& trunkName, const std::string& indexName, const std::string& indexFileName,
472  SphinxConfigOptions& configOptions)
473 {
474  bool result = false;
475  const std::string path = fObj.getDataDir()+"/"+indexName;
476  const std::string propFile = path+"/"+sphinx_search_const::sphinxPropertyFile;
477  const std::string sphinxConfigFile = path+"/"+sphinx_search_const::sphinxConfigName;
478  try
479  {
480  Poco::AutoPtr<SphinxConfigCreator> pConf = new SphinxConfigCreator(propFile);
481 
482  // saved for possibility restore
483  configOptions.setCreatedDate(pConf->getUInt64(sphinx_admin_command_const::optionsCreatedDate, 0));
484  pConf->remove(sphinx_admin_command_const::sectionOptions); // remove need to sphinx indexer
485 
486  std::vector<std::string> keys;
487  pConf->keys(keys);
488 
489  for (size_t i=0;i<keys.size();++i)
490  {
491  if (keys[i].find(sphinx_search_const::sourceNameField)!=std::string::npos)
492  {
493  std::string name = keys[i]+"."+sphinx_search_const::xmlpipeCommandNameField;
494  std::string value = "cat "+path+"/"+sphinx_admin_command_const::dataDir+"/"+indexFileName+"."+sphinx_admin_command_const::sourceFileExtension;
495  pConf->setString(name, value);
496  }
497  }
499  std::string value = path+"/"+trunkName;
500  pConf->setString(name, value);
501 
502  value = fObj.getLogDir()+"/"+indexName+"/"+sphinx_search_const::searchdLogFile;
503  pConf->setString(sphinx_search_const::searchdLogName, value);
504 
505  value = fObj.getRunDir()+"/"+/*indexName+"/"+*/
506  sphinx_search_const::searchdPidFileName+"_"+indexName+"."+
508  pConf->setString(sphinx_search_const::searchdPidName, value);
509 
510  value = fObj.getLogDir()+"/"+indexName+"/"+sphinx_search_const::searchdQueryLogFile;
511  pConf->setString(sphinx_search_const::searchdQueryLogName, value);
512 
513  pConf->save(propFile);
514  pConf->setPropertyFileConfiguration(propFile);
515 
516  std::ofstream ofs(sphinxConfigFile.c_str(), std::fstream::trunc);
517  ofs << *pConf;
518  ofs.close();
519 
520  // apply property options to config
521  writePropertyOptions(*pConf, configOptions);
522  pConf->save(propFile);
523 
524  result = true;
525  }
526  catch(Poco::Exception& e)
527  {
528  errorMsg = e.message();
529  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::ERROR_MAKE_CONFIG, errorMsg) << flush;
530  }
531  return result;
532 }
533 //-----------------------------------------------------------------------------
534 bool SphinxAdminCommand::isExistError(const std::string& procExecMsg)
535 {
536  return ((procExecMsg.find(sphinx_admin_command_const::procExecErrorMsg)!=std::string::npos) ||
537  (procExecMsg.find(sphinx_admin_command_const::procExecFatalMsg)!=std::string::npos));
538 }
539 //-----------------------------------------------------------------------------
540 std::string SphinxAdminCommand::getPropertyFileName(const std::string& indexPath, const std::string& branchName)
541 {
543 }
544 //-----------------------------------------------------------------------------
545 std::string SphinxAdminCommand::getConfigFileName(const std::string& indexPath, const std::string& branchName)
546 {
547  return indexPath+"/"+sphinx_admin_command_const::dataDir+"/"+branchName+"_"+sphinx_search_const::branchConfigFile;
548 }
549 //-----------------------------------------------------------------------------
551 {
552  configCreator.setUInt64(sphinx_admin_command_const::optionsMaxDocId, configOptions.getMaxDocId());
553  configCreator.setUInt64(sphinx_admin_command_const::optionsCreatedDate, configOptions.getCreatedDate());
554  configCreator.setUInt64(sphinx_admin_command_const::optionsMergedDate, configOptions.getMergedDate());
555  configCreator.setString(sphinx_admin_command_const::optionsBranches, configOptions.getBranchesAsString());
556  configCreator.setUInt(sphinx_admin_command_const::optionsRanker, configOptions.getRanker());
557  configCreator.setString(sphinx_admin_command_const::optionsRankerExpression, configOptions.getRankerExpression());
558 }
559 //-----------------------------------------------------------------------------
560 //-----------------------------------------------------------------------------
561 Poco::SharedPtr<SphinxAdminCommand> SphinxAdminCommandFactory::create(SphinxFunctionalObject& fObj, const std::string& commandString)
562 {
563  Poco::SharedPtr<SphinxAdminCommand> pCmd;
564 
565  if (commandString == "INDEX_CREATE")
566  pCmd = new IndexCreate(fObj);
567  else if (commandString == "INDEX_CHECK")
568  pCmd = new IndexCheck(fObj);
569  else if (commandString == "INDEX_STORE_DATA_FILE")
570  pCmd = new IndexStoreDataFile(fObj);
571  else if (commandString == "INDEX_STORE_SCHEMA_FILE")
572  pCmd = new IndexStoreSchemaFile(fObj);
573  else if (commandString == "INDEX_REBUILD")
574  pCmd = new IndexRebuild(fObj);
575 // else if (commandString == "INDEX_SET_DATA_DIR") // not use
576 // pCmd = new IndexSetDataDir(fObj);
577  else if (commandString == "INDEX_START")
578  pCmd = new IndexStart(fObj);
579  else if (commandString == "INDEX_STOP")
580  pCmd = new IndexStop(fObj);
581  else if (commandString == "INDEX_MERGE")
582  pCmd = new IndexMerge(fObj);
583  else if (commandString == "INDEX_MERGE_TRUNK")
584  pCmd = new IndexMergeTrunk(fObj);
585  else if (commandString == "INDEX_DELETE_DATA_FILE")
586  pCmd = new IndexDeleteDataFile(fObj);
587  else if (commandString == "INDEX_DELETE_SCHEMA_FILE")
588  pCmd = new IndexDeleteSchemaFile(fObj);
589  else if (commandString == "INDEX_APPEND_DATA_FILE")
590  pCmd = new IndexAppendDataFile(fObj);
591  else if (commandString == "INDEX_DELETE_DOC")
592  pCmd = new IndexDeleteDoc(fObj);
593  else if (commandString == "INDEX_DELETE_DOC_NUMBER")
594  pCmd = new IndexDeleteDocNumber(fObj);
595  else if (commandString == "INDEX_PACK_DOC_DATA")
596  pCmd = new IndexPackDocData(fObj);
597  else if (commandString == "INDEX_REMOVE")
598  pCmd = new IndexRemove(fObj);
599  else if (commandString == "INDEX_COPY")
600  pCmd = new IndexCopy(fObj);
601  else if (commandString == "INDEX_RENAME")
602  pCmd = new IndexRename(fObj);
603  else if (commandString == "INDEX_SET_CONFIG_VAR")
604  pCmd = new IndexSetConfigVar(fObj);
605  else if (commandString == "INDEX_GET_CONFIG_VAR")
606  pCmd = new IndexGetConfigVar(fObj);
607  else if (commandString == "INDEX_CHECK_SCHEMA")
608  pCmd = new IndexCheckSchema(fObj);
609  else if (commandString == "INDEX_STATUS_SEARCHD")
610  pCmd = new IndexStatusSearchd(fObj);
611  else if (commandString == "INDEX_STATUS")
612  pCmd = new IndexStatus(fObj);
613  else if (commandString == "INDEX_MAX_DOC_ID")
614  pCmd = new IndexMaxDocId(fObj);
615  else if (commandString == "INDEX_DATA_LIST")
616  pCmd = new IndexDataList(fObj);
617  else if (commandString == "INDEX_BRANCHES_LIST")
618  pCmd = new IndexBranchesList(fObj);
619  else if (commandString == "INDEX_BRANCHES_INFO")
620  pCmd = new IndexBranchesInfo(fObj);
621  else if (commandString == "INDEX_BRANCHES_STATUS")
622  pCmd = new IndexBranchesStatus(fObj);
623  else if (commandString == "INDEX_CONNECT")
624  pCmd = new IndexConnect(fObj);
625  else if (commandString == "INDEX_DISCONNECT")
626  pCmd = new IndexDisconnect(fObj);
627 
628  return pCmd;
629 }
630 //-----------------------------------------------------------------------------
631 //-----------------------------------------------------------------------------
633 :inherited(fObj), indexName("")
634 {
635 }
636 //-----------------------------------------------------------------------------
637 bool IndexCreate::serialize(std::string& json)
638 {
639  _isError = true;
640  errorMsg.clear();
641  try
642  {
643  Poco::JSON::Object::Ptr obj = new Poco::JSON::Object();
645 
646  std::stringstream ostr;
647  Poco::JSON::Stringifier::stringify(obj, ostr);
648  json = ostr.str();
649 
650  _isError = false;
651  }
652  catch(std::exception& e)
653  {
654  errorMsg = e.what();
656  }
657  return !_isError;
658 }
659 //-----------------------------------------------------------------------------
660 bool IndexCreate::unserialize(const std::string& json)
661 {
662  indexName.clear();
663  errorMsg.clear();
664  _isError = true;
665  try
666  {
667  Poco::JSON::Parser parser;
668  Poco::Dynamic::Var res = parser.parse(json);
669  Poco::JSON::Object::Ptr obj = res.extract<Poco::JSON::Object::Ptr>();
670 
671  Poco::Dynamic::Var tmp = obj->get(sphinx_admin_command_const::indexName);
672  if (tmp.isString())
673  indexName = tmp.convert<std::string>();
674 
675  _isError = false;
676  }
677  catch(Poco::JSON::JSONException& e)
678  {
679  errorMsg = e.displayText();
681  }
682  return !_isError;
683 }
684 //-----------------------------------------------------------------------------
686 {
687  errorMsg.clear();
689  _isError = true;
690  try
691  {
692  std::string path = fObj.getDataDir()+"/"+indexName;
693 
694  if (isExistDir(path))
696 
697  unsigned int allowedPort = sphinx_search_const::defaultPort;
698 
699  if (!getFreeAllowedPort(allowedPort))
700  throw Poco::Exception(errorMsg, ERROR_CREATE_INDEX);
701 
702  if (!makeDir(path))
704 
705  std::string indexDir = path+"/"+sphinx_admin_command_const::indexDir;
706  std::string dataDir = path+"/"+sphinx_admin_command_const::dataDir;
707 
708  if (!makeDir(indexDir))
710 
711  if (!makeDir(dataDir))
713 
714  if (!isExistDir(indexDir))
715  throw Poco::Exception(message(message_const::DONT_CREATED_DIR, indexDir), ERROR_CREATE_INDEX);
716 
717  if (!isExistDir(dataDir))
718  throw Poco::Exception(message(message_const::DONT_CREATED_DIR, dataDir), ERROR_CREATE_INDEX);
719 
720  std::string srcFile = fObj.getEtcDir()+"/"+sphinx_search_const::sphinxSchemaFile;
721  std::string dstFile = path+"/"+sphinx_search_const::sphinxSchemaFile;
722 
723  if (copyFile(srcFile, dstFile))
724  {
726  dstFile = path+"/"+sphinx_search_const::sphinxPropertyFile;
727 
728  Poco::AutoPtr<SphinxConfigCreator> pConf = new SphinxConfigCreator(srcFile);
729 
730  std::vector<std::string> keys;
731  pConf->keys(keys);
732 
733  for (size_t i=0;i<keys.size();++i)
734  {
735  if (keys[i].find(sphinx_search_const::sourceNameField)!=std::string::npos)
736  {
737  std::string name = keys[i]+"."+sphinx_search_const::xmlpipeCommandNameField;
738  std::string value = pConf->getString(name);
739  size_t pos = value.find_last_of(' ');
740  if (pos!=std::string::npos)
741  value = value.substr(pos+1);
742 
743  std::stringstream str;
744  str << "cat " << dataDir << '/' << value;
745  pConf->setString(name, str.str());
746  }
747 
748  if (keys[i].find(sphinx_search_const::indexNameField)!=std::string::npos)
749  {
750  std::string name = keys[i]+"."+sphinx_search_const::pathNameField;
751  std::string value = pConf->getString(name);
752 
753  std::stringstream str;
754  str << indexDir << '/' << value;
755  pConf->setString(name, str.str());
756  }
757  }
758  // create structure run dir
759  std::string runDir = fObj.getRunDir();
760  if (!isExistDir(runDir))
761  if (!makeDir(runDir))
763 
764  // create structure log dir
765  std::string logDir = fObj.getLogDir();
766  if (!isExistDir(logDir))
767  if (!makeDir(logDir))
769 
770  logDir = fObj.getLogDir()+"/"+indexName;
771  if (!isExistDir(logDir))
772  if (!makeDir(logDir))
774 
775  // create content of property file
776  std::string value = logDir+"/"+sphinx_search_const::searchdLogFile;
777  pConf->setString(sphinx_search_const::searchdLogName, value);
778 
779  value = logDir+"/"+sphinx_search_const::searchdQueryLogFile;
780  pConf->setString(sphinx_search_const::searchdQueryLogName, value);
781 
782  value = runDir+"/"+sphinx_search_const::searchdPidFileName+"_"+indexName+"."+sphinx_search_const::searchdPidFileExt; // make pid file name
783  pConf->setString(sphinx_search_const::searchdPidName, value);
784 
785  value = fObj.getServerHost()+":"+std::to_string(allowedPort);
786  pConf->setString(sphinx_search_const::searchdListen, value);
787 
788  pConf->save(dstFile);
789  pConf->setPropertyFileConfiguration(dstFile);
790 
791  std::string sphinxConfig = path+"/"+sphinx_search_const::sphinxConfigName;
792  std::ofstream ofs(sphinxConfig.c_str(), std::fstream::trunc);
793  ofs << *pConf;
794  ofs.close();
795 
796  SphinxConfigOptions configOptions;
797  writePropertyOptions(*pConf, configOptions);
798  pConf->save(dstFile);
799  pConf->setPropertyFileConfiguration(dstFile);
800 
801  _isError = false;
802  }
803  }
804  catch(Poco::Exception& e)
805  {
806  errorMsg = e.message();
807  errorCode = e.code();
808  }
809  return !_isError;
810 }
811 //-----------------------------------------------------------------------------
812 //-----------------------------------------------------------------------------
814 :inherited(fObj)
815 {
816 }
817 //-----------------------------------------------------------------------------
819 {
820  errorMsg.clear();
822  _isError = true;
823  try
824  {
825  std::string path = fObj.getDataDir()+"/"+indexName;
826 
827  if (!isExistDir(path))
828  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path), ERROR_CHECK_INDEX);
829 
832 
835 
836  if (!isExistDir(fObj.getLogDir()+"/"+indexName))
838 
839  if (!isExistDir(fObj.getRunDir()))
841 
844 
847 
850 
851  _isError = false;
852  }
853  catch(Poco::Exception& e)
854  {
855  resultData = "0";
856  errorMsg = e.message();
857  errorCode = e.code();
858  }
859  resultData = (!_isError)?"1":"0";
860  return !_isError;
861 }
862 //-----------------------------------------------------------------------------
863 //-----------------------------------------------------------------------------
865 : inherited(fObj), indexName(""), branchName(""), dataContent("")
866 {
867 }
868 //-----------------------------------------------------------------------------
869 bool IndexStoreDataFile::serialize(std::string& json)
870 {
871  errorMsg.clear();
873  _isError = true;
874  try
875  {
876  Poco::JSON::Object::Ptr obj = new Poco::JSON::Object();
880 
881  std::stringstream ostr;
882  Poco::JSON::Stringifier::stringify(obj, ostr);
883  json = ostr.str();
884 
885  _isError = false;
886  }
887  catch(std::exception& e)
888  {
889  errorMsg = e.what();
891  }
892  return !_isError;
893 }
894 //-----------------------------------------------------------------------------
895 bool IndexStoreDataFile::unserialize(const std::string& json)
896 {
897  indexName.clear();
898  branchName.clear();
899  dataContent.clear();
900  errorMsg.clear();
901  _isError = true;
902  try
903  {
904  Poco::JSON::Parser parser;
905  Poco::Dynamic::Var res = parser.parse(json);
906  Poco::JSON::Object::Ptr obj = res.extract<Poco::JSON::Object::Ptr>();
907 
908  Poco::Dynamic::Var tmp = obj->get(sphinx_admin_command_const::indexName);
909  if (tmp.isString())
910  indexName = tmp.convert<std::string>();
911 
913  if (tmp.isString())
914  branchName = tmp.convert<std::string>();
915 
917  if (tmp.isString())
918  dataContent = tmp.convert<std::string>();
919 
920  _isError = false;
921  }
922  catch(Poco::JSON::JSONException& e)
923  {
924  errorMsg = e.displayText();
926  }
927  return !_isError;
928 }
929 //-----------------------------------------------------------------------------
931 {
932  errorMsg.clear();
934  _isError = true;
935  try
936  {
937  std::string path = fObj.getDataDir()+"/"+indexName;
938  if (!isExistDir(path))
939  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path), ERROR_STORE_DATA_FILE);
940 
941  path.append("/").append(sphinx_admin_command_const::dataDir);
942  if (!isExistDir(path))
943  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path), ERROR_STORE_DATA_FILE);
944 
945  std::stringstream str(HCE::decodeBase64(dataContent));
946  if (str.str().empty())
948 
950  {
951  SphinxDataFile dataFile;
952  dataFile.validateData(str);
953  if (dataFile.isError())
954  throw Poco::Exception(dataFile.getErrorMsg(), ERROR_STORE_DATA_FILE);
955  }
956 
958  {
962 
963  std::set<std::string> delList;
964  std::string outString = xmlCleaner.process(str.str(), delList);
965  str.str(outString);
966  }
967 
968  path.append("/").append(branchName).append(".dat");
969 
970  std::ofstream ofs(path.c_str(), std::fstream::trunc);
971  if (!ofs.is_open())
972  throw Poco::Exception(message(message_const::FILE_NOT_OPEN, path), ERROR_STORE_DATA_FILE);
973 
974  ofs << str.str();
975  ofs.close();
976  _isError = false;
977  }
978  catch(Poco::Exception& e)
979  {
980  errorMsg = e.displayText();
981  errorCode = e.code();
982  }
983  catch(std::exception& e)
984  {
985  errorMsg = e.what();
987  }
988  return !_isError;
989 }
990 //-----------------------------------------------------------------------------
991 //-----------------------------------------------------------------------------
992 //-----------------------------------------------------------------------------
994 : inherited(fObj), indexName(""), schemaContent("")
995 {
996 }
997 //-----------------------------------------------------------------------------
998 bool IndexStoreSchemaFile::serialize(std::string& json)
999 {
1000  _isError = true;
1001  errorMsg.clear();
1002  try
1003  {
1004  Poco::JSON::Object::Ptr obj = new Poco::JSON::Object();
1007 
1008  std::stringstream ostr;
1009  Poco::JSON::Stringifier::stringify(obj, ostr);
1010  json = ostr.str();
1011 
1012  _isError = false;
1013  }
1014  catch(std::exception& e)
1015  {
1016  errorMsg = e.what();
1018  }
1019  return !_isError;
1020 }
1021 //-----------------------------------------------------------------------------
1022 bool IndexStoreSchemaFile::unserialize(const std::string& json)
1023 {
1024  indexName.clear();
1025  schemaContent.clear();
1026  errorMsg.clear();
1027  _isError = true;
1028  try
1029  {
1030  Poco::JSON::Parser parser;
1031  Poco::Dynamic::Var res = parser.parse(json);
1032  Poco::JSON::Object::Ptr obj = res.extract<Poco::JSON::Object::Ptr>();
1033 
1034  Poco::Dynamic::Var tmp = obj->get(sphinx_admin_command_const::indexName);
1035  if (tmp.isString())
1036  indexName = tmp.convert<std::string>();
1037 
1039  if (tmp.isString())
1040  schemaContent = tmp.convert<std::string>();
1041 
1042  _isError = false;
1043  }
1044  catch(Poco::JSON::JSONException& e)
1045  {
1046  errorMsg = e.displayText();
1048  }
1049  return !_isError;
1050 }
1051 //-----------------------------------------------------------------------------
1053 {
1054  errorMsg.clear();
1055  errorCode = NO_ERROR;
1056  _isError = true;
1057  try
1058  {
1059  std::string path = fObj.getDataDir()+"/"+indexName;
1060  if (!isExistDir(path))
1061  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path), ERROR_STORE_SCHEMA_FILE);
1062 
1063  std::stringstream str(HCE::decodeBase64(schemaContent));
1064  if (str.str().empty())
1066 
1068  {
1069  SphinxSchemaFile schemaFile(str);
1070  std::vector<std::pair<std::string, int> > schemaVec;
1071  if (!schemaFile.getFields(schemaVec))
1073  }
1074  path.append("/").append(sphinx_search_const::sphinxSchemaFile);
1075 
1076  std::ofstream ofs(path.c_str(), std::fstream::trunc);
1077  if (!ofs.is_open())
1078  throw Poco::Exception(message(message_const::FILE_NOT_OPEN, path), ERROR_STORE_SCHEMA_FILE);
1079 
1081  ofs.close();
1082  _isError = false;
1083  }
1084  catch(Poco::Exception& e)
1085  {
1086  errorMsg = e.message();
1087  errorCode = e.code();
1088  }
1089  return !_isError;
1090 }
1091 //-----------------------------------------------------------------------------
1092 //-----------------------------------------------------------------------------
1094 : inherited(fObj), indexName(""), branches()
1095 {
1096 }
1097 //-----------------------------------------------------------------------------
1098 bool IndexRebuild::serialize(std::string& json)
1099 {
1100  _isError = true;
1101  errorMsg.clear();
1102  try
1103  {
1104  Poco::JSON::Object::Ptr obj = new Poco::JSON::Object();
1106 
1107  Poco::JSON::Array::Ptr vecBranches = new Poco::JSON::Array();
1108  obj->set(sphinx_admin_command_const::branches, vecBranches);
1109 
1110  for (size_t i=0;i<branches.size();++i)
1111  vecBranches->add(branches[i]);
1112 
1113  std::stringstream ostr;
1114  Poco::JSON::Stringifier::stringify(obj, ostr);
1115  json = ostr.str();
1116 
1117  _isError = false;
1118  }
1119  catch(std::exception& e)
1120  {
1121  errorMsg = e.what();
1123  }
1124  return !_isError;
1125 }
1126 //-----------------------------------------------------------------------------
1127 bool IndexRebuild::unserialize(const std::string& json)
1128 {
1129  indexName.clear();
1130  branches.clear();
1131  errorMsg.clear();
1132  _isError = true;
1133  try
1134  {
1135  Poco::JSON::Parser parser;
1136  Poco::Dynamic::Var res = parser.parse(json);
1137  Poco::JSON::Object::Ptr obj = res.extract<Poco::JSON::Object::Ptr>();
1138 
1139  Poco::Dynamic::Var tmp = obj->get(sphinx_admin_command_const::indexName);
1140  if (tmp.isString())
1141  indexName = tmp.convert<std::string>();
1142 
1143  Poco::JSON::Array::Ptr vecBranches = obj->getArray(sphinx_admin_command_const::branches);
1144  if (!vecBranches.isNull())
1145  {
1146  for (size_t k = 0;k<vecBranches->size();++k)
1147  {
1148  Poco::Dynamic::Var tmp = vecBranches->get(k);
1149  if (tmp.isString())
1150  {
1151  std::string branchName = tmp.convert<std::string>();
1152  if (isAllowedString(branchName))
1153  branches.push_back(branchName);
1154  else
1155  {
1158  if (!resultData.empty())
1159  resultData.append(",");
1160  resultData.append(branchName);
1161  }
1162  }
1163  }
1164  }
1165 
1166  _isError = false;
1167  }
1168  catch(Poco::JSON::JSONException& e)
1169  {
1170  errorMsg = e.displayText();
1172  }
1173  return !_isError;
1174 }
1175 //-----------------------------------------------------------------------------
1176 bool IndexRebuild::makeSource(const std::string& schemaFile, const std::string& branchName, const std::string& sourcePath, const std::string& configPath)
1177 {
1178  bool result = false;
1179  try
1180  {
1181  std::ifstream ifsSchema(schemaFile.c_str());
1182  if (!ifsSchema.is_open())
1183  throw Poco::Exception(message(message_const::FILE_NOT_OPEN, schemaFile), ERROR_MAKE_SOURCE);
1184 
1185  std::string dataFileName = sourcePath+"/"+branchName+"."+sphinx_admin_command_const::dataFileExtension;
1186  std::ifstream ifsDoc(dataFileName.c_str());
1187  if (!ifsDoc.is_open())
1188  {
1189  ifsSchema.close();
1190  throw Poco::Exception(message(message_const::FILE_NOT_OPEN, dataFileName), ERROR_MAKE_SOURCE);
1191  }
1192 
1193  std::string outputFileName = sourcePath+"/"+branchName+"."+sphinx_admin_command_const::sourceFileExtension;
1194 
1195  SphinxDataSource dataSource(ifsSchema, ifsDoc);
1196  std::fstream outputSource(outputFileName.c_str(), std::fstream::out | std::fstream::trunc);
1197  try
1198  {
1199  outputSource << dataSource << flush;
1200  result = makeIndex(outputFileName, branchName, configPath, dataSource.getMaxDocId());
1201  }
1202  catch(Poco::Exception& e)
1203  {
1206  }
1207  outputSource.close();
1208  ifsDoc.close();
1209  ifsSchema.close();
1210  }
1211  catch(Poco::Exception& e)
1212  {
1213  errorMsg = e.message();
1214  errorCode = e.code();
1215  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::MAKE_SOURCE) << errorMsg << flush;
1216  }
1217  return result;
1218 }
1219 //-----------------------------------------------------------------------------
1220 bool IndexRebuild::makeIndex(const std::string& sourceFile, const std::string& branchName, const std::string& configPath, unsigned long long maxDocId)
1221 {
1222  const std::string propertyFile = getPropertyFileName(configPath, branchName);
1223  const std::string configFile = getConfigFileName(configPath, branchName);
1224  const std::string propFile = configPath+"/"+sphinx_search_const::sphinxPropertyFile;
1225  bool result = false;
1226  try
1227  {
1228  Poco::AutoPtr<SphinxConfigCreator> pConf = new SphinxConfigCreator(propFile);
1229 
1230  SphinxConfigOptions configOptions;
1231  configOptions.setMaxDocId(maxDocId);
1232  configOptions.addBranch(branchName);
1233  configOptions.setCreatedDate(pConf->getUInt64(sphinx_admin_command_const::optionsCreatedDate, 0));
1234 
1236 
1237  std::vector<std::string> keys;
1238  pConf->keys(keys);
1239 
1240  std::string sectionName;
1241  for (size_t i=0;i<keys.size();++i)
1242  {
1243  if (keys[i].find(sphinx_search_const::sourceNameField)!=std::string::npos)
1244  {
1245  std::string name = keys[i]+"."+sphinx_search_const::xmlpipeCommandNameField;
1246  std::stringstream str;
1247  str << "cat " << sourceFile;
1248  pConf->setString(name, str.str());
1249  }
1250  if (keys[i].find(sphinx_search_const::indexNameField)!=std::string::npos)
1251  {
1252  std::string name = keys[i]+"."+sphinx_search_const::pathNameField;
1253  std::stringstream str;
1254  str << configPath+"/"+sphinx_admin_command_const::indexDir << "/" << branchName;
1255  pConf->setString(name, str.str());
1256  sectionName = keys[i];
1257  }
1258  }
1259 
1260  pConf->save(propertyFile);
1261  pConf->setPropertyFileConfiguration(propertyFile);
1262  pConf->renameSphinxConfigSection(sectionName, "index "+branchName);
1263 
1264  std::ofstream ofs(configFile.c_str(), std::fstream::trunc);
1265  ofs << *pConf;
1266  ofs.close();
1267 
1268  pConf->clear();
1269  pConf->setPropertyFileConfiguration(propertyFile);
1270  pConf->cloneSphinxConfigSection(sectionName, "index "+branchName);
1271  pConf->remove(sectionName);
1272 
1273  writePropertyOptions(*pConf, configOptions);
1274  pConf->save(propertyFile);
1275 
1276  std::stringstream outMsg, errMsg;
1277  const std::string cmd("indexer --config " +configFile+" --all");
1278  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::COMMAND_LINE, cmd) << flush;
1279 
1280  ProcExec procExec(cmd);
1281  if (!procExec.exec(outMsg, errMsg))
1282  throw Poco::Exception(message(message_const::INDEXATION_FAIL, branchName)+message(message_const::ERROR, errMsg.str()));
1283 
1284  if (isExistError(outMsg.str()))
1285  throw Poco::Exception(outMsg.str());
1286 
1287  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << outMsg.str() << flush;
1288  result = true; // (removeFile(propertyFile) && removeFile(configFile));
1289  }
1290  catch(Poco::Exception& e)
1291  {
1292  errorMsg = e.message();
1294  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::MAKE_INDEX) << errorMsg << flush;
1295  }
1296  return result;
1297 }
1298 //-----------------------------------------------------------------------------
1300 {
1301  errorMsg.clear();
1302  errorCode = NO_ERROR;
1303  _isError = true;
1304  try
1305  {
1306  if (branches.empty())
1308 
1309  std::string path = fObj.getDataDir()+"/"+indexName;
1310 
1311  if (!isExistDir(path))
1312  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path), ERROR_INDEX_REBUILD);
1313 
1314  std::string indexDir = path+"/"+sphinx_admin_command_const::indexDir;
1315  std::string dataDir = path+"/"+sphinx_admin_command_const::dataDir;
1316 
1317  if (!isExistDir(path+"/"+sphinx_admin_command_const::indexDir))
1318  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path+"/"+sphinx_admin_command_const::indexDir), ERROR_INDEX_REBUILD);
1319 
1320  if (!isExistDir(path+"/"+sphinx_admin_command_const::dataDir))
1321  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path+"/"+sphinx_admin_command_const::dataDir), ERROR_INDEX_REBUILD);
1322 
1323  const std::string schemaFileName = path+"/"+sphinx_search_const::sphinxSchemaFile;
1324  std::vector<std::string> vFiles;
1326  {
1327  unsigned int madeFailCount = 0;
1328  if (vFiles.size()==0)
1329  {
1331  }
1332  else if (branches.front()=="*")
1333  {
1334  if (!cleanDir(indexDir))
1335  throw Poco::Exception(errorMsg, errorCode);
1336 
1337  for (size_t i=0;i<vFiles.size();++i)
1338  {
1339  if (!makeSource(schemaFileName, vFiles[i], dataDir, path))
1340  {
1341  if (!resultData.empty())
1342  resultData.append(",");
1343  resultData.append(vFiles[i]);
1344  ++madeFailCount;
1345  }
1346  }
1347  }
1348  else
1349  {
1350  for (size_t k=0;k<branches.size();++k)
1351  for (size_t i=0;i<vFiles.size();++i)
1352  if (vFiles[i]==branches[k])
1353  {
1354  if (!makeSource(schemaFileName, vFiles[i], dataDir, path))
1355  {
1356  if (!resultData.empty())
1357  resultData.append(",");
1358  resultData.append(vFiles[i]);
1359  ++madeFailCount;
1360  }
1361  break;
1362  }
1363  }
1364  if (madeFailCount==0)
1365  _isError = false;
1366  }
1367  if (_isError)
1368  throw Poco::Exception(errorMsg, ERROR_INDEX_REBUILD);
1369  }
1370  catch(Poco::Exception& e)
1371  {
1372  errorMsg = e.message();
1373  errorCode = e.code();
1374  }
1375  return !_isError;
1376 }
1377 //-----------------------------------------------------------------------------
1378 //-----------------------------------------------------------------------------
1380 :inherited(fObj)
1381 {
1382 }
1383 //-----------------------------------------------------------------------------
1384 bool IndexSetDataDir::serialize(std::string& json)
1385 {
1386  //TODO
1387  return false;
1388 }
1389 //-----------------------------------------------------------------------------
1390 bool IndexSetDataDir::unserialize(const std::string& json)
1391 {
1392  //TODO
1393  return false;
1394 }
1395 //-----------------------------------------------------------------------------
1397 {
1398  //TODO
1399  return false;
1400 }
1401 //-----------------------------------------------------------------------------
1402 //-----------------------------------------------------------------------------
1404 :inherited(fObj)
1405 {
1406 }
1407 //-----------------------------------------------------------------------------
1409 {
1410  errorMsg.clear();
1411  errorCode = NO_ERROR;
1412  _isError = true;
1413  try
1414  {
1415  if (indexName.empty())
1417 
1418  // check and create if need structure run dir
1419  std::string runDir = fObj.getRunDir();
1420  if (!isExistDir(runDir))
1421  if (!makeDir(runDir))
1422  throw Poco::Exception(message(message_const::DONT_CREATED_DIR, runDir), ERROR_INDEX_START);
1423 
1424  // check and create if need structure log dir
1425  std::string logDir = fObj.getLogDir();
1426  if (!isExistDir(logDir))
1427  if (!makeDir(logDir))
1428  throw Poco::Exception(message(message_const::DONT_CREATED_DIR, logDir), ERROR_INDEX_START);
1429 
1430  // check and create if need structure log dir / index name
1431  logDir = fObj.getLogDir()+"/"+indexName;
1432  if (!isExistDir(logDir))
1433  if (!makeDir(logDir))
1434  throw Poco::Exception(message(message_const::DONT_CREATED_DIR, logDir), ERROR_INDEX_START);
1435 
1436  std::string path = fObj.getDataDir()+"/"+indexName;
1437 
1438  if (!isExistDir(path))
1439  throw Poco::Exception(message(message_const::INDEX_NOT_EXIST, path), ERROR_INDEX_START);
1440 
1441  path.append("/").append(sphinx_search_const::sphinxConfigName);
1442  if (!isExistFile(path))
1443  throw Poco::Exception(message(message_const::FILE_NOT_EXIST, path), ERROR_INDEX_START);
1444 
1447  {
1449  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::IS_RUN_SEARCHD) << std::boolalpha << isRunSearchd << flush;
1450  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::INDEX_NAME, fObj.getIndexName()) << flush;
1451 
1452  if (isRunSearchd)
1453  {
1454  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::STOPPED_SEARCHD) << std::boolalpha << fObj.stopSearchd() << flush;
1455  }
1456  if (!fObj.startSearchd())
1457  throw Poco::Exception(fObj.getErrorMsg(), fObj.getErrorCode());
1458 
1459  _isError = false;
1460  }
1461  }
1462  catch(Poco::Exception& e)
1463  {
1464  errorMsg = e.message();
1465  errorCode = e.code();
1466  }
1467  return !_isError;
1468 }
1469 //-----------------------------------------------------------------------------
1470 //-----------------------------------------------------------------------------
1472 :inherited(fObj)
1473 {
1474 }
1475 //-----------------------------------------------------------------------------
1477 {
1478  errorMsg.clear();
1479  errorCode = NO_ERROR;
1480  _isError = true;
1481 
1482  try
1483  {
1484  if (indexName!=fObj.getIndexName())
1486 
1487  std::string path = fObj.getDataDir()+"/"+indexName;
1488  if (!isExistDir(path))
1489  throw Poco::Exception(message(message_const::INDEX_NOT_EXIST, path), ERROR_INDEX_STOP);
1490 
1491  path.append("/").append(sphinx_search_const::sphinxConfigName);
1492  if (!isExistFile(path))
1493  throw Poco::Exception(message(message_const::FILE_NOT_EXIST, path), ERROR_INDEX_STOP);
1494 
1495  if (!fObj.stopSearchd())
1496  throw Poco::Exception(fObj.getErrorMsg(), fObj.getErrorCode());
1497 
1498  _isError = false;
1499  }
1500  catch(Poco::Exception& e)
1501  {
1502  errorMsg = e.message();
1503  errorCode = e.code();
1504  }
1505  return !_isError;
1506 }
1507 //-----------------------------------------------------------------------------
1508 //-----------------------------------------------------------------------------
1510 :inherited(fObj)
1511 {
1512 }
1513 //-----------------------------------------------------------------------------
1514 bool IndexMerge::makeMerge(const std::string& branchName, const std::string& configPath, const std::string& trunkName, unsigned long long& maxDocId)
1515 {
1516  bool result = false;
1517  const std::string propertyFile = configPath+"/"+sphinx_search_const::branchPropertyFile;
1518  const std::string configFile = configPath+"/"+sphinx_search_const::branchConfigFile;
1519  const std::string propFile = configPath+"/"+sphinx_search_const::sphinxPropertyFile;
1520  try
1521  {
1522  Poco::AutoPtr<SphinxConfigCreator> pConfBranch = new SphinxConfigCreator(getPropertyFileName(configPath, branchName));
1523  maxDocId = pConfBranch->getUInt64(sphinx_admin_command_const::optionsMaxDocId, 0);
1524 
1525  Poco::AutoPtr<SphinxConfigCreator> pConf = new SphinxConfigCreator(propFile);
1527 
1528  std::vector<std::string> keys;
1529  pConf->keys(keys);
1530 
1531  const std::string sourceFile = configPath+"/"+sphinx_admin_command_const::dataDir+"/"+branchName+"."+sphinx_admin_command_const::sourceFileExtension;
1532 
1533  std::string trunkSectionName, branchSource;
1534  for (size_t i=0;i<keys.size();++i)
1535  {
1536  size_t found = keys[i].find(sphinx_search_const::sourceNameField);
1537  if (found!=std::string::npos)
1538  {
1539  branchSource = keys[i];
1540 
1541  std::string name = keys[i]+"."+sphinx_search_const::xmlpipeCommandNameField;
1542  std::stringstream str;
1543  str << "cat " << sourceFile;
1544  pConf->setString(name, str.str());
1545  }
1546  if (keys[i].find(sphinx_search_const::indexNameField)!=std::string::npos && keys[i].find(trunkName)!=std::string::npos)
1547  {
1548  trunkSectionName = keys[i];
1549  }
1550  }
1551  if (trunkSectionName.empty())
1552  throw Poco::Exception(message(message_const::SECTION_NAME_NOT_VALID, trunkSectionName));
1553 
1554  std::string branchSectionName = sphinx_search_const::indexNameField+" "+branchName;
1555  pConf->cloneSphinxConfigSection(trunkSectionName, branchSectionName);
1556 
1557  std::string branchSourceName = branchSource;
1558  std::string trunkSourceName = sphinx_search_const::sourceNameField+" "+trunkName;
1559  pConf->cloneSphinxConfigSection(branchSourceName, trunkSourceName);
1560 
1561  std::string name = trunkSectionName+"."+sphinx_search_const::sourceNameField;
1562  std::string value = trunkSourceName;
1563  pConf->setString(name, value);
1564 
1565  name = trunkSourceName+"."+sphinx_search_const::xmlpipeCommandNameField;
1566  value = "echo \"\"";
1567  pConf->setString(name, value);
1568 
1569  name = branchSectionName+"."+sphinx_search_const::pathNameField;
1570  value = configPath+"/"+sphinx_admin_command_const::indexDir+"/"+branchName;
1571  pConf->setString(name, value);
1572 
1573  name = trunkSectionName+"."+sphinx_search_const::pathNameField;
1574  value = configPath+"/"+sphinx_admin_command_const::indexDir+"/"+trunkName;
1575  pConf->setString(name, value);
1576 
1578  pConf->setString(sphinx_search_const::searchdLogName, value);
1579 
1580  value = fObj.getRunDir()+"/"+/*indexName+"/"+*/
1583  pConf->setString(sphinx_search_const::searchdPidName, value);
1584 
1586  pConf->setString(sphinx_search_const::searchdQueryLogName, value);
1587 
1588  pConf->save(propertyFile);
1589  pConf->setPropertyFileConfiguration(propertyFile);
1590 
1591  std::ofstream ofs(configFile.c_str(), std::fstream::trunc);
1592  ofs << *pConf;
1593  ofs.close();
1594 
1595  std::stringstream outMsg;
1596  const std::string cmd("indexer");
1597  std::vector<std::string> args = {"--merge", trunkName, branchName, "--config", configFile};
1598  ProcExec procExec(cmd, args);
1599  bool ret = procExec.exec(outMsg, outMsg);
1600 
1601  if (!(removeFile(configFile) && removeFile(propertyFile)))
1602  throw Poco::Exception(errorMsg);
1603 
1604  if (!ret)
1605  throw Poco::Exception(message(message_const::MERGE_BRANCHES_FAIL, std::string(branchName)+" =>> "+trunkName));
1606 
1607  if (isExistError(outMsg.str()))
1608  throw Poco::Exception(outMsg.str());
1609 
1610  result = true;
1611  }
1612  catch(Poco::Exception& e)
1613  {
1614  errorMsg = e.message();
1616  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::ERROR_MAKE_MERGE, errorMsg) << flush;
1617  }
1618  catch(std::exception& e)
1619  {
1620  errorMsg = e.what();
1622  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::ERROR_MAKE_MERGE, errorMsg) << flush;
1623  }
1624 
1625  return result;
1626 }
1627 //-----------------------------------------------------------------------------
1628 bool IndexMerge::makeTrunk(const std::string& trunkName, const std::string& configPath,
1629  std::vector<std::string>& vIndexes, unsigned long long& maxDocId) throw (Poco::Exception)
1630 {
1631  if (vIndexes.empty())
1633 
1634  bool result = true;
1635  for (size_t i=0;i<vIndexes.size();++i)
1636  {
1637  if (vIndexes[i]==trunkName)
1638  {
1639  result = false;
1640  break;
1641  }
1642  }
1643 
1644  if (result)
1645  {
1646  const std::string propertyFile = configPath+"/"+sphinx_search_const::branchPropertyFile;
1647  const std::string configFile = configPath+"/"+sphinx_search_const::branchConfigFile;
1648  const std::string propFile = configPath+"/"+sphinx_search_const::sphinxPropertyFile;
1649 
1650  try
1651  {
1652  Poco::AutoPtr<SphinxConfigCreator> pConfBranch = new SphinxConfigCreator(getPropertyFileName(configPath, vIndexes.front()));
1653  maxDocId = pConfBranch->getUInt64(sphinx_admin_command_const::optionsMaxDocId, 0);
1654 
1655  Poco::AutoPtr<SphinxConfigCreator> pConf = new SphinxConfigCreator(propFile);
1657 
1658  std::vector<std::string> keys;
1659  pConf->keys(keys);
1660 
1661  for (size_t i=0;i<keys.size();++i)
1662  {
1663  if (keys[i].find(sphinx_search_const::sourceNameField)!=std::string::npos)
1664  {
1665  std::string name = keys[i]+"."+sphinx_search_const::xmlpipeCommandNameField;
1666  std::stringstream str;
1667  str << "cat " << configPath+"/"+sphinx_admin_command_const::dataDir << "/" << vIndexes.front() << "."
1669  pConf->setString(name, str.str());
1670  }
1671  if (keys[i].find(sphinx_search_const::indexNameField)!=std::string::npos && keys[i].find(trunkName)!=std::string::npos )
1672  {
1673  std::string name = keys[i]+"."+sphinx_search_const::pathNameField;
1674  std::stringstream str;
1675  str << configPath+"/"+sphinx_admin_command_const::indexDir << "/" << trunkName;
1676  pConf->setString(name, str.str());
1677  }
1678  }
1679  std::string value = fObj.getLogDir()+"/"+indexName+"/"+sphinx_search_const::searchdLogFile;
1680  pConf->setString(sphinx_search_const::searchdLogName, value);
1681 
1682  value = fObj.getRunDir()+"/"+/*indexName+"/"+*/
1685  pConf->setString(sphinx_search_const::searchdPidName, value);
1686 
1687  value = fObj.getLogDir()+"/"+indexName+"/"+sphinx_search_const::searchdQueryLogFile;
1688  pConf->setString(sphinx_search_const::searchdQueryLogName, value);
1689 
1690  pConf->save(propertyFile);
1691  pConf->setPropertyFileConfiguration(propertyFile);
1692 
1693  std::ofstream ofs(configFile.c_str(), std::fstream::trunc);
1694  ofs << *pConf;
1695  ofs.close();
1696 
1697  std::stringstream outMsg;
1698  const std::string cmd("indexer");
1699  std::vector<std::string> args = {"--quiet", trunkName, "--config", configFile};
1700  ProcExec procExec(cmd, args);
1701  bool ret = procExec.exec(outMsg, outMsg);
1702 
1703  if (!(removeFile(configFile) && removeFile(propertyFile)))
1704  throw Poco::Exception(errorMsg);
1705 
1706  if (!ret)
1707  throw Poco::Exception(message(message_const::INDEXATION_FAIL, trunkName));
1708 
1709  if (isExistError(outMsg.str()))
1710  throw Poco::Exception(outMsg.str());
1711 
1712  vIndexes.erase(vIndexes.begin());
1713  }
1714  catch(Poco::Exception& e)
1715  {
1716  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::ERROR_MAKE_TRUNK_INDEX, e.message()) << flush;
1717  throw Poco::Exception(e.message(), ERROR_MAKE_TRUNK_INDEX);
1718  }
1719  }
1720  return result;
1721 }
1722 //-----------------------------------------------------------------------------
1724 {
1725  errorMsg.clear();
1726  errorCode = NO_ERROR;
1727  _isError = true;
1728 
1729  try
1730  {
1731  if (indexName.empty())
1733 
1734  if (branches.empty())
1736 
1737  std::string path = fObj.getDataDir()+"/"+indexName;
1738  if (!isExistDir(path))
1739  throw Poco::Exception(message(message_const::INDEX_NOT_EXIST, path), ERROR_INDEX_MERGE);
1740 
1741  std::string indexDir = path+"/"+sphinx_admin_command_const::indexDir;
1742  if (!isExistDir(indexDir))
1743  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, indexDir), ERROR_INDEX_MERGE);
1744 
1746  if (!fObject.isLoadedConfig())
1747  throw Poco::Exception(fObject.getErrorMsg(), ERROR_INDEX_MERGE);
1748 
1749  fObject.setLogStream(fObj.log(LoggerStream::Priority::PRIO_INFORMATION));
1750  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::CALL_REMOVE_INDEX_NAME, fObject.getIndexFileName()) << flush;
1751 
1752  if (!removeIndexFile(fObject.getIndexFileName(), indexDir))
1753  throw Poco::Exception(errorMsg, errorCode);
1754 
1755  std::vector<std::string> vIndexes;
1756  if (getIndexList(indexDir, vIndexes))
1757  {
1758  if (vIndexes.empty())
1760 
1761  SphinxConfigOptions configOptions;
1762  unsigned long long maxDocId = 0;
1763  unsigned long long branchMaxDocId = 0;
1764 
1765  const std::string trunkFileName = *(vIndexes.begin());
1766  bool isMadeTrunk = makeTrunk(fObject.getIndexFileName(), path, vIndexes, maxDocId);
1767 
1768  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::PREPARE_MERGE, fObj.getIndexFileName()) << message(message_const::IS_MADE_TRUNK) << std::boolalpha << isMadeTrunk << flush;
1769  configOptions.addBranch(trunkFileName);
1770 
1771  unsigned int madeFailCount = 0;
1772  if (branches.front()=="*")
1773  {
1774  for (size_t i=0;i<vIndexes.size();++i)
1775  {
1776  if (!makeMerge(vIndexes[i], path, fObject.getIndexFileName(), branchMaxDocId))
1777  {
1778  if (!resultData.empty())
1779  resultData.append(",");
1780  resultData.append(vIndexes[i]);
1781  ++madeFailCount;
1782  }
1783  else
1784  {
1785  configOptions.addBranch(vIndexes[i]);
1786  if (maxDocId < branchMaxDocId)
1787  maxDocId = branchMaxDocId;
1788  }
1789  }
1790  }
1791  else
1792  {
1793  for (size_t k=0;k<branches.size();++k)
1794  for (size_t i=0;i<vIndexes.size();++i)
1795  if (vIndexes[i]==branches[k])
1796  {
1797  if (!makeMerge(vIndexes[i], path, fObject.getIndexFileName(), branchMaxDocId))
1798  {
1799  if (!resultData.empty())
1800  resultData.append(",");
1801  resultData.append(vIndexes[i]);
1802  ++madeFailCount;
1803  }
1804  else
1805  {
1806  configOptions.addBranch(vIndexes[i]);
1807  if (maxDocId < branchMaxDocId)
1808  maxDocId = branchMaxDocId;
1809  }
1810  break;
1811  }
1812  }
1813 
1814  bool isActive = fObject.isActiveSearchd(); // save state of daemon
1815  fObject.stopSearchd();
1816 
1817  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::INDEX_FILE_NAME, fObj.getIndexFileName()) << flush;
1818  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::IS_ACTIVE_SEARCHD) << std::boolalpha << isActive << flush;
1819 
1820  if (!moveIndexFiles(fObject.getIndexFileName(), indexDir, path))
1822 
1823  configOptions.setMaxDocId(maxDocId);
1824  configOptions.updateMargedDate();
1825 
1826  if (!makeTrunkConfig(fObject.getIndexFileName(), indexName, trunkFileName, configOptions))
1828 
1829  if (isActive) // restore source state
1830  if (!fObject.startSearchd())
1832 
1833  if (madeFailCount==0)
1834  _isError = false;
1835  }
1836  if (_isError)
1837  throw Poco::Exception(errorMsg, ERROR_INDEX_MERGE);
1838  }
1839  catch(Poco::Exception& e)
1840  {
1841  errorMsg = e.message();
1842  errorCode = e.code();
1843  _isError = true;
1844  }
1845  catch(std::exception& e)
1846  {
1847  errorMsg = e.what();
1849  _isError = true;
1850  }
1851  return !_isError;
1852 }
1853 //-----------------------------------------------------------------------------
1854 //-----------------------------------------------------------------------------
1856 :inherited(fObj)
1857 {
1858 }
1859 //-----------------------------------------------------------------------------
1861 {
1862  errorMsg.clear();
1863  errorCode = NO_ERROR;
1864  _isError = true;
1865 
1866  try
1867  {
1868  if (indexName.empty())
1870 
1871  if (branches.empty())
1873 
1874  std::string path = fObj.getDataDir()+"/"+indexName;
1875  if (!isExistDir(path))
1876  throw Poco::Exception(message(message_const::INDEX_NOT_EXIST, path), ERROR_INDEX_MERGE_TRUNK);
1877 
1878  std::string indexDir = path+"/"+sphinx_admin_command_const::indexDir;
1879  if (!isExistDir(indexDir))
1880  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, indexDir), ERROR_INDEX_MERGE_TRUNK);
1881 
1883  if (!fObject.isLoadedConfig())
1884  throw Poco::Exception(fObject.getErrorMsg(),ERROR_INDEX_MERGE_TRUNK);
1885 
1886  fObject.setLogStream(fObj.log(LoggerStream::Priority::PRIO_INFORMATION));
1887 
1888  std::vector<std::string> vIndexes;
1889  if (!getIndexList(indexDir, vIndexes))
1890  throw Poco::Exception(errorMsg, ERROR_INDEX_MERGE_TRUNK);
1891 
1892  if (vIndexes.empty())
1894 
1895  const std::string trunkFileName = *(vIndexes.begin());
1896  // copy trunk index files to index dir
1897  if (!copyIndexFiles(fObject.getIndexFileName(), path, indexDir))
1899 
1900  SphinxConfigOptions configOptions;
1901  unsigned long long maxDocId = 0;
1902  unsigned long long branchMaxDocId = 0;
1903 
1904  unsigned int madeFailCount = 0;
1905  for (size_t k=0;k<branches.size();++k)
1906  for (size_t i=0;i<vIndexes.size();++i)
1907  if (vIndexes[i]==branches[k])
1908  {
1909  if (!makeMerge(vIndexes[i], path, fObject.getIndexFileName(), branchMaxDocId))
1910  {
1911  if (!resultData.empty())
1912  resultData.append(",");
1913  resultData.append(vIndexes[i]);
1914  ++madeFailCount;
1915  }
1916  else
1917  {
1918  configOptions.addBranch(vIndexes[i]);
1919  if (maxDocId < branchMaxDocId)
1920  maxDocId = branchMaxDocId;
1921  }
1922  break;
1923  }
1924 
1925  bool isActive = fObject.isActiveSearchd(); // save state of daemon
1926  fObject.stopSearchd();
1927 
1928  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::INDEX_FILE_NAME, fObj.getIndexFileName()) << flush;
1929  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::IS_ACTIVE_SEARCHD) << std::boolalpha << isActive << flush;
1930 
1931  if (!moveIndexFiles(fObject.getIndexFileName(), indexDir, path))
1933 
1934  if (!makeTrunkConfig(fObject.getIndexFileName(), indexName, trunkFileName, configOptions))
1936 
1937  if (isActive) // restore source state
1938  if (!fObject.startSearchd())
1940 
1941  if (madeFailCount==0)
1942  _isError = false;
1943  }
1944  catch(Poco::Exception& e)
1945  {
1946  errorMsg = e.message();
1947  errorCode = e.code();
1948  _isError = true;
1949  }
1950  catch(std::exception& e)
1951  {
1952  errorMsg = e.what();
1954  _isError = true;
1955  }
1956  return !_isError;
1957 }
1958 //-----------------------------------------------------------------------------
1959 //-----------------------------------------------------------------------------
1961 :inherited(fObj)
1962 {
1963 }
1964 //-----------------------------------------------------------------------------
1965 bool IndexDeleteDataFile::removeFilesList(const std::string& path, std::vector<std::string>& branches, std::vector<std::string>& files, const std::string& ext) throw (Poco::Exception)
1966 {
1967  bool result = false;
1968  unsigned int madeFailCount = 0;
1969  if (branches.front()=="*")
1970  {
1971  for (size_t i=0;i<files.size();++i)
1972  {
1973  std::string fileName = path+"/"+files[i]+"."+ext;
1974  if (!removeFile(fileName))
1975  {
1976  if (!resultData.empty())
1977  resultData.append(",");
1978  resultData.append(fileName);
1979  ++madeFailCount;
1980  }
1981  }
1982  }
1983  else
1984  {
1985  for (size_t k=0;k<branches.size();++k)
1986  for (size_t i=0;i<files.size();++i)
1987  if (files[i]==branches[k])
1988  {
1989  std::string fileName = path+"/"+files[i]+"."+ext;
1990  if (!removeFile(fileName))
1991  {
1992  if (!resultData.empty())
1993  resultData.append(",");
1994  resultData.append(fileName);
1995  ++madeFailCount;
1996  }
1997  }
1998  }
1999  if (madeFailCount==0)
2000  result = true;
2001 
2002  return result;
2003 }
2004 //-----------------------------------------------------------------------------
2005 bool IndexDeleteDataFile::removeIndexFiles(const std::string& path, std::vector<std::string>& branches, std::vector<std::string>& files) throw (Poco::Exception)
2006 {
2007  bool result = false;
2008  unsigned int madeFailCount = 0;
2009 
2010  if (branches.front()=="*")
2011  {
2012  for (size_t i=0;i<files.size();++i)
2013  {
2014  if (!removeIndexFile(files[i], path))
2015  {
2016  if (!resultData.empty())
2017  resultData.append(",");
2018  resultData.append(files[i]);
2019  ++madeFailCount;
2020  }
2021  }
2022  }
2023  else
2024  {
2025  for (size_t k=0;k<branches.size();++k)
2026  for (size_t i=0;i<files.size();++i)
2027  if (files[i]==branches[k])
2028  {
2029  if (!removeIndexFile(files[i], path))
2030  {
2031  if (!resultData.empty())
2032  resultData.append(",");
2033  resultData.append(files[i]);
2034  ++madeFailCount;
2035  }
2036  }
2037  }
2038  if (madeFailCount==0)
2039  result = true;
2040 
2041  return result;
2042 }
2043 //-----------------------------------------------------------------------------
2045 {
2046  errorMsg.clear();
2047  errorCode = NO_ERROR;
2048  _isError = true;
2049  try
2050  {
2051  if (branches.empty())
2053 
2054  std::string path = fObj.getDataDir()+"/"+indexName;
2055  if (!isExistDir(path))
2057 
2058  std::string indexDir = path+"/"+sphinx_admin_command_const::indexDir;
2059  std::string dataDir = path+"/"+sphinx_admin_command_const::dataDir;
2060  if (!isExistDir(indexDir))
2061  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, indexDir), ERROR_INDEX_DELETE_DATA_FILE);
2062 
2063  if (!isExistDir(dataDir))
2064  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, dataDir), ERROR_INDEX_DELETE_DATA_FILE);
2065 
2066  std::vector<std::string> dataFiles, sourceFiles, configFiles, propertyFiles, indexes;
2071  getIndexList(indexDir, indexes))
2072  {
2073  if (dataFiles.size()==0 && sourceFiles.size()==0 && indexes.size()==0 && configFiles.size()==0 && propertyFiles.size()==0)
2074  {
2076  }
2077  else
2078  {
2079  _isError = !(removeFilesList(dataDir, branches, dataFiles, sphinx_admin_command_const::dataFileExtension) &&
2080  removeFilesList(dataDir, branches, sourceFiles, sphinx_admin_command_const::sourceFileExtension) &&
2081  removeFilesList(dataDir, branches, configFiles, sphinx_admin_command_const::branchConfigFileExtention) &&
2082  removeFilesList(dataDir, branches, propertyFiles, sphinx_admin_command_const::branchPropertyFileExtention) &&
2083  removeIndexFiles(indexDir, branches, indexes));
2084  }
2085  }
2086  if (_isError)
2087  throw Poco::Exception(errorMsg, ERROR_INDEX_DELETE_DATA_FILE);
2088  }
2089  catch(Poco::Exception& e)
2090  {
2091  errorMsg = e.message();
2092  errorCode = e.code();
2093  }
2094  return !_isError;
2095 }
2096 //-----------------------------------------------------------------------------
2097 //-----------------------------------------------------------------------------
2099 :inherited(fObj)
2100 {
2101 }
2102 //-----------------------------------------------------------------------------
2104 {
2105  errorMsg.clear();
2106  errorCode = NO_ERROR;
2107  _isError = true;
2108  try
2109  {
2110  std::string fileName = fObj.getDataDir()+"/"+indexName+"/"+sphinx_search_const::sphinxSchemaFile;
2111 
2112  if (!removeFile(fileName))
2113  throw Poco::Exception(errorMsg, ERROR_INDEX_DELETE_SCHEMA_FILE);
2114 
2115  if (isExistFile(fileName))
2116  throw Poco::Exception(message(message_const::REMOVE_FILE_FAIL, fileName), ERROR_INDEX_DELETE_SCHEMA_FILE);
2117 
2118  _isError = false;
2119  }
2120  catch(Poco::Exception& e)
2121  {
2122  errorMsg = e.message();
2123  errorCode = e.code();
2124  }
2125  return !_isError;
2126 }
2127 //-----------------------------------------------------------------------------
2128 //-----------------------------------------------------------------------------
2130 :inherited(fObj)
2131 {
2132 }
2133 //-----------------------------------------------------------------------------
2135 {
2136  errorMsg.clear();
2137  errorCode = NO_ERROR;
2138  _isError = true;
2139  try
2140  {
2141  std::string path = fObj.getDataDir()+"/"+indexName;
2142  if (!isExistDir(path))
2144 
2145  std::string dataDir = path+"/"+sphinx_admin_command_const::dataDir;
2146  if (!isExistDir(dataDir))
2147  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, dataDir), ERROR_INDEX_DELETE_DATA_FILE);
2148 
2149  const std::string dataFileName = dataDir+"/"+branchName+"."+sphinx_admin_command_const::dataFileExtension;
2150  std::stringstream oldContent;
2151  SphinxDataFile dataFile;
2152  std::ifstream ifs(dataFileName.c_str(), std::fstream::binary);
2153  if (ifs.is_open())
2154  {
2155  oldContent << ifs.rdbuf();
2156  _isError = !dataFile.append(oldContent);
2157  ifs.close();
2158  if (_isError)
2159  throw Poco::Exception(dataFile.getErrorMsg(), ERROR_INDEX_APPEND_DATA_FILE);
2160  }
2161 
2162  std::stringstream strAppendContent(HCE::decodeBase64(dataContent));
2163  if (!dataFile.append(strAppendContent))
2164  throw Poco::Exception(dataFile.getErrorMsg(), ERROR_INDEX_APPEND_DATA_FILE);
2165 
2166  std::fstream fst(dataFileName.c_str(), std::fstream::out|std::fstream::trunc|std::fstream::binary);
2167  fst << dataFile;
2168  fst.flush();
2169  fst.close();
2170 
2171  _isError = false;
2172  }
2173  catch(Poco::Exception& e)
2174  {
2175  errorMsg = e.message();
2176  errorCode = e.code();
2177  }
2178  return !_isError;
2179 }
2180 //-----------------------------------------------------------------------------
2182 :inherited(fObj), ids()
2183 {
2184 }
2185 //-----------------------------------------------------------------------------
2186 // cppcheck-suppress unusedFunction
2187 void IndexDeleteDoc::addId(unsigned long long id)
2188 {
2189  ids.push_back(id);
2190 }
2191 //-----------------------------------------------------------------------------
2192 bool IndexDeleteDoc::serialize(std::string& json)
2193 {
2194  _isError = true;
2195  errorMsg.clear();
2196  try
2197  {
2198  Poco::JSON::Object::Ptr obj = new Poco::JSON::Object();
2200 
2201  Poco::JSON::Array::Ptr array = new Poco::JSON::Array();
2202  for (size_t i=0;i<ids.size();++i)
2203  array->add(std::to_string(ids[i]));
2204  obj->set(sphinx_admin_command_const::documents, array);
2205 
2206  std::stringstream ostr;
2207  Poco::JSON::Stringifier::stringify(obj, ostr);
2208  json = ostr.str();
2209 
2210  _isError = false;
2211  }
2212  catch(std::exception& e)
2213  {
2214  errorMsg = e.what();
2216  }
2217  return !_isError;
2218 }
2219 //-----------------------------------------------------------------------------
2220 bool IndexDeleteDoc::unserialize(const std::string& json)
2221 {
2222  indexName.clear();
2223  ids.clear();
2224  errorMsg.clear();
2225  _isError = true;
2226  try
2227  {
2228  Poco::JSON::Parser parser;
2229  Poco::Dynamic::Var res = parser.parse(json);
2230  Poco::JSON::Object::Ptr obj = res.extract<Poco::JSON::Object::Ptr>();
2231 
2232  Poco::Dynamic::Var tmp = obj->get(sphinx_admin_command_const::indexName);
2233  if (tmp.isString())
2234  indexName = tmp.convert<std::string>();
2235 
2236  Poco::JSON::Array::Ptr vecDocs = obj->getArray(sphinx_admin_command_const::documents);
2237  if (!vecDocs.isNull())
2238  {
2239  for (size_t k = 0;k<vecDocs->size();++k)
2240  {
2241  Poco::Dynamic::Var tmp = vecDocs->get(k);
2242  if (tmp.isString())
2243  {
2244  try
2245  {
2246  unsigned long long id = std::stoull(tmp.convert<std::string>());
2247  ids.push_back(id);
2248  }
2249  catch(std::exception& e)
2250  {
2251  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << "Get bad doc ID: " << e.what() << flush;
2252  }
2253  }
2254  if (tmp.isNumeric())
2255  {
2256  unsigned long long id = tmp.convert<Poco::Int64>();
2257  ids.push_back(id);
2258  }
2259  }
2260  }
2261  _isError = false;
2262  }
2263  catch(Poco::JSON::JSONException& e)
2264  {
2265  errorMsg = e.displayText();
2267  }
2268  return !_isError;
2269 }
2270 //-----------------------------------------------------------------------------
2272 {
2273  errorMsg.clear();
2274  errorCode = NO_ERROR;
2275  _isError = true;
2276  try
2277  {
2278  std::string path = fObj.getDataDir()+"/"+indexName;
2279  if (!isExistDir(path))
2280  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path), ERROR_INDEX_DELETE_DOC);
2281 
2282  if (ids.size()==0)
2284 
2285  std::string fileName = path+"/"+sphinx_admin_command_const::deletedFileName;
2286  if (isExistFile(fileName))
2287  {
2288  std::fstream fst(fileName.c_str(), std::fstream::out|std::fstream::app);
2289  if (!fst.is_open())
2290  throw Poco::Exception(message(message_const::FILE_NOT_OPEN, fileName), ERROR_INDEX_DELETE_DOC);
2291 
2292  for (size_t i=0;i<ids.size();++i)
2293  fst << (unsigned long long)(ids[i]) << flush;
2294  fst.close();
2295  }
2296  else
2297  {
2298  std::ofstream ofs(fileName.c_str(), std::fstream::trunc);
2299  for (size_t i=0;i<ids.size();++i)
2300  ofs << ids[i] << flush;
2301  ofs.close();
2302  }
2303  _isError = false;
2304  }
2305  catch(Poco::Exception& e)
2306  {
2307  errorMsg = e.message();
2308  errorCode = e.code();
2309  }
2310  return !_isError;
2311 }
2312 //-----------------------------------------------------------------------------
2313 //-----------------------------------------------------------------------------
2315 :inherited(fObj)
2316 {
2317 }
2318 //-----------------------------------------------------------------------------
2320 {
2321  errorMsg.clear();
2322  errorCode = NO_ERROR;
2323  _isError = true;
2324  try
2325  {
2326  std::string path = fObj.getDataDir()+"/"+indexName;
2327  if (!isExistDir(path))
2329 
2330  std::string fileName = path+"/"+sphinx_admin_command_const::deletedFileName;
2331  size_t count = 0;
2332  if (isExistFile(fileName))
2333  {
2334  std::ifstream ifs(fileName.c_str());
2335  if (!ifs.is_open())
2336  throw Poco::Exception(message(message_const::FILE_NOT_OPEN, fileName), ERROR_INDEX_DELETE_DOC_NUMBER);
2337 
2338  std::string line;
2339  while(getline(ifs, line))
2340  {
2341  ++count;
2342  }
2343  ifs.close();
2344  }
2345  resultData = std::to_string(count);
2346  _isError = false;
2347  }
2348  catch(Poco::Exception& e)
2349  {
2350  errorMsg = e.message();
2351  errorCode = e.code();
2352  }
2353  catch(std::exception& e)
2354  {
2355  errorMsg = e.what();
2357  }
2358  return !_isError;
2359 }
2360 //-----------------------------------------------------------------------------
2361 //-----------------------------------------------------------------------------
2363 :inherited(fObj)
2364 {
2365 }
2366 //-----------------------------------------------------------------------------
2367 bool IndexPackDocData::packData(const std::string& file, std::set<std::string>& delList)
2368 {
2369  bool result = false;
2373  std::string xmlString;
2374  std::string outString;
2375  try
2376  {
2377  std::ifstream in(file.c_str());
2378  if (!in.is_open())
2379  throw Poco::Exception(message(message_const::FILE_NOT_OPEN, file));
2380 
2381  in.seekg(0, std::ios::end);
2382  xmlString.resize(in.tellg());
2383  in.seekg(0, std::ios::beg);
2384  in.read(&xmlString[0], xmlString.size());
2385  in.close();
2386 
2387  outString = xmlCleaner.process(xmlString, delList);
2388 
2389  std::ofstream ofs(file.c_str(), std::fstream::trunc);
2390  ofs << outString;
2391  ofs.close();
2392 
2393  result = true;
2394  }
2395  catch(Poco::Exception& e)
2396  {
2397  errorMsg = message(message_const::ERROR_PACK_DATA, e.displayText());
2398  }
2399  catch(std::exception& e)
2400  {
2402  }
2403  return result;
2404 }
2405 //-----------------------------------------------------------------------------
2406 bool IndexPackDocData::getDocumentCount(const std::string& file, size_t& documentCount)
2407 {
2408  bool result = false;
2409  try
2410  {
2411  std::ifstream ifs(file.c_str());
2412  if (!ifs.is_open())
2413  throw Poco::Exception(message(message_const::FILE_NOT_OPEN, file));
2414 
2415  SphinxDataFile dataFile;
2416  size_t count = dataFile.documentCount(ifs);
2417  ifs.close();
2418 
2419  if (dataFile.isError())
2420  throw Poco::Exception(dataFile.getErrorMsg());
2421 
2422  result = true;
2423  documentCount += count;
2424  }
2425  catch(Poco::Exception& e)
2426  {
2428  }
2429  catch(std::exception& e)
2430  {
2432  }
2433  return result;
2434 }
2435 //-----------------------------------------------------------------------------
2437 {
2438  errorMsg.clear();
2439  errorCode = NO_ERROR;
2440  _isError = true;
2441 
2442  try
2443  {
2444  resultData = "0";
2445 
2446  std::string path = fObj.getDataDir()+"/"+indexName;
2447  if (!isExistDir(path))
2448  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path), ERROR_INDEX_PACK_DOC_DATA);
2449 
2450  std::string dataDir = path+"/"+sphinx_admin_command_const::dataDir;
2451  if (!isExistDir(dataDir))
2452  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, dataDir), ERROR_INDEX_PACK_DOC_DATA);
2453 
2454  if (branches.empty())
2456 
2457  const std::string backupFile = path+"/"+sphinx_admin_command_const::deletedFileName+".backup";
2458  const std::string fileName = path+"/"+sphinx_admin_command_const::deletedFileName;
2459  std::set<std::string> delList;
2460 
2461  if (isExistFile(fileName))
2462  {
2463  std::ifstream ifs(fileName.c_str());
2464  if (!ifs.is_open())
2465  throw Poco::Exception(message(message_const::FILE_NOT_OPEN, fileName), ERROR_INDEX_PACK_DOC_DATA);
2466 
2467  std::string line;
2468  while(getline(ifs, line))
2469  {
2470  try
2471  {
2472  std::stoull(line);
2473  delList.insert(line);
2474  }
2475  catch(std::exception& e)
2476  {
2477  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::BAD_DOCUMENT_ID, e.what()) << flush;
2478  }
2479  }
2480  ifs.close();
2481 
2482  if (!moveFile(fileName, backupFile))
2483  throw Poco::Exception(errorMsg, ERROR_INDEX_PACK_DOC_DATA);
2484  }
2485 
2486  std::vector<std::string> vFiles;
2488  throw Poco::Exception(errorMsg, errorCode);
2489 
2490  size_t documentCount = 0;
2491 
2492  if (vFiles.size()==0)
2493  {
2495  }
2496  else if (branches.front()=="*")
2497  {
2498  for (size_t i=0;i<vFiles.size();++i)
2499  {
2500  if (!packData(dataDir+"/"+vFiles[i]+"."+sphinx_admin_command_const::dataFileExtension, delList))
2501  throw Poco::Exception(errorMsg, ERROR_INDEX_PACK_DOC_DATA);
2502 
2503  if (!getDocumentCount(dataDir+"/"+vFiles[i]+"."+sphinx_admin_command_const::dataFileExtension, documentCount))
2504  throw Poco::Exception(errorMsg, ERROR_INDEX_PACK_DOC_DATA);
2505  }
2506  }
2507  else
2508  {
2509  for (size_t k=0;k<branches.size();++k)
2510  for (size_t i=0;i<vFiles.size();++i)
2511  if (vFiles[i]==branches[k])
2512  {
2513  if (!packData(dataDir+"/"+vFiles[i]+"."+sphinx_admin_command_const::dataFileExtension, delList))
2514  throw Poco::Exception(errorMsg, ERROR_INDEX_PACK_DOC_DATA);
2515 
2516  if (!getDocumentCount(dataDir+"/"+vFiles[i]+"."+sphinx_admin_command_const::dataFileExtension, documentCount))
2517  throw Poco::Exception(errorMsg, ERROR_INDEX_PACK_DOC_DATA);
2518  }
2519  }
2520  if (isExistFile(backupFile))
2521  if (!removeFile(backupFile))
2522  throw Poco::Exception(errorMsg, ERROR_INDEX_PACK_DOC_DATA);
2523 
2524  resultData = std::to_string(documentCount);
2525  _isError = false;
2526  }
2527  catch(Poco::Exception& e)
2528  {
2529  errorMsg = e.message();
2530  errorCode = e.code();
2531  }
2532  catch(std::exception& e)
2533  {
2534  errorMsg = e.what();
2536  }
2537  return !_isError;
2538 }
2539 //-----------------------------------------------------------------------------
2540 //-----------------------------------------------------------------------------
2542 :inherited(fObj)
2543 {
2544 }
2545 //-----------------------------------------------------------------------------
2547 {
2548  errorMsg.clear();
2549  errorCode = NO_ERROR;
2550  _isError = true;
2551  try
2552  {
2553  std::string path = fObj.getDataDir()+"/"+indexName;
2554 
2555  if (!isExistDir(path))
2556  throw Poco::Exception(message(message_const::INDEX_NOT_EXIST, path), ERROR_INDEX_REMOVE);
2557 
2558  SphinxFunctionalObject fObject("", 0, fObj.getHomeDir(), indexName);
2559  IndexStop indexStop(fObject);
2560  indexStop.setIndexName(indexName);
2561  if (!indexStop.execute())
2562  throw Poco::Exception(indexStop.getErrorMsg(), ERROR_INDEX_REMOVE);
2563 
2564  std::string cmd("rm");
2565  std::vector<std::string> args = {"-R", path};
2566 
2567  std::stringstream outMsg;
2568  ProcExec procExec(cmd, args);
2569  if (!procExec.exec(outMsg, outMsg))
2570  throw Poco::Exception(message(message_const::REMOVE_DIR_FAIL, path), ERROR_INDEX_REMOVE);
2571 
2572  if (isExistError(outMsg.str()))
2573  throw Poco::Exception(outMsg.str(), ERROR_INDEX_REMOVE);
2574 
2575  path = fObj.getLogDir()+"/"+indexName;
2576  if (isExistDir(path))
2577  {
2578  args.clear();
2579  args.push_back("-R");
2580  args.push_back(path);
2581  ProcExec procExecLog(cmd, args);
2582  procExecLog.exec();
2583  }
2584  _isError = false;
2585  }
2586  catch(Poco::Exception& e)
2587  {
2588  errorMsg = e.message();
2589  errorCode = e.code();
2590  }
2591  return !_isError;
2592 }
2593 //-----------------------------------------------------------------------------
2594 //-----------------------------------------------------------------------------
2596 :inherited(fObj), indexFromName(""), indexToName("")
2597 {
2598 }
2599 //-----------------------------------------------------------------------------
2600 bool IndexCopy::serialize(std::string& json)
2601 {
2602  _isError = true;
2603  errorMsg.clear();
2604  try
2605  {
2606  Poco::JSON::Object::Ptr obj = new Poco::JSON::Object();
2609 
2610  std::stringstream ostr;
2611  Poco::JSON::Stringifier::stringify(obj, ostr);
2612  json = ostr.str();
2613 
2614  _isError = false;
2615  }
2616  catch(std::exception& e)
2617  {
2618  errorMsg = e.what();
2620  }
2621  return !_isError;
2622 }
2623 //-----------------------------------------------------------------------------
2624 bool IndexCopy::unserialize(const std::string& json)
2625 {
2626  indexFromName.clear();
2627  indexToName.clear();
2628  errorMsg.clear();
2629  _isError = true;
2630  try
2631  {
2632  Poco::JSON::Parser parser;
2633  Poco::Dynamic::Var res = parser.parse(json);
2634  Poco::JSON::Object::Ptr obj = res.extract<Poco::JSON::Object::Ptr>();
2635 
2636  Poco::Dynamic::Var tmp = obj->get(sphinx_admin_command_const::indexFromName);
2637  if (tmp.isString())
2638  indexFromName = tmp.convert<std::string>();
2639 
2641  if (tmp.isString())
2642  indexToName = tmp.convert<std::string>();
2643 
2644  _isError = false;
2645  }
2646  catch(Poco::JSON::JSONException& e)
2647  {
2648  errorMsg = e.displayText();
2650  }
2651  return !_isError;
2652 }
2653 //-----------------------------------------------------------------------------
2655 {
2656  errorMsg.clear();
2657  errorCode = NO_ERROR;
2658  _isError = true;
2659  try
2660  {
2661  const std::string srcIndex = fObj.getDataDir()+"/"+indexFromName;
2662  const std::string dstIndex = fObj.getDataDir()+"/"+indexToName;
2663 
2664  if (isExistDir(dstIndex))
2666 
2667  std::string logDir = fObj.getLogDir()+"/"+indexToName;
2668  if (!isExistDir(logDir))
2669  if (!makeDir(logDir))
2670  throw Poco::Exception(message(message_const::DONT_CREATED_DIR, logDir), ERROR_INDEX_COPY);
2671 
2672  const std::string cmd("cp");
2673  std::vector<std::string> args = {"-R", srcIndex, dstIndex};
2674  ProcExec procExec(cmd, args);
2675  if (!procExec.exec())
2676  throw Poco::Exception(message(message_const::INDEX_COPY_FAIL, std::string(srcIndex)+" =>> "+dstIndex), ERROR_INDEX_COPY);
2677 
2678  const std::string propFile = dstIndex+"/"+sphinx_search_const::sphinxPropertyFile;
2679  const std::string sphinxConfigFile = dstIndex+"/"+sphinx_search_const::sphinxConfigName;
2680 
2681  Poco::AutoPtr<SphinxConfigCreator> pConf = new SphinxConfigCreator(propFile);
2682  std::vector<std::string> keys;
2683  pConf->keys(keys);
2684 
2685  for (size_t i=0;i<keys.size();++i)
2686  {
2687  if (keys[i].find(sphinx_search_const::sourceNameField)!=std::string::npos)
2688  {
2689  std::string name = keys[i]+"."+sphinx_search_const::xmlpipeCommandNameField;
2690  std::string value = pConf->getString(name);
2691 
2692  size_t pos = value.find(indexFromName);
2693  if (pos!=std::string::npos)
2694  value = value.replace(pos, indexFromName.length(), indexToName);
2695 
2696  pConf->setString(name, value);
2697  }
2698 
2699  if (keys[i].find(sphinx_search_const::indexNameField)!=std::string::npos)
2700  {
2701  std::string name = keys[i]+"."+sphinx_search_const::pathNameField;
2702  std::string value = pConf->getString(name);
2703 
2704  size_t pos = value.find(indexFromName);
2705  if (pos!=std::string::npos)
2706  value = value.replace(pos, indexFromName.length(), indexToName);
2707 
2708  pConf->setString(name, value);
2709  }
2710  }
2711  std::string value = fObj.getLogDir()+"/"+indexToName+"/"+sphinx_search_const::searchdLogFile;
2712  pConf->setString(sphinx_search_const::searchdLogName, value);
2713 
2714  value = fObj.getRunDir()+"/"+/*indexToName+"/"+*/
2717  pConf->setString(sphinx_search_const::searchdPidName, value);
2718 
2720  pConf->setString(sphinx_search_const::searchdQueryLogName, value);
2721 
2722  unsigned int port = 0;
2723  if (!getFreeAllowedPort(port))
2724  throw Poco::Exception(errorMsg, ERROR_INDEX_COPY);
2725 
2726  value = fObj.getServerHost()+":"+std::to_string(port);
2727  pConf->setString(sphinx_search_const::searchdListen, value);
2728 
2729  pConf->save(propFile);
2730  pConf->setPropertyFileConfiguration(propFile);
2731  pConf->deleteSphinxConfigSection(sphinx_admin_command_const::sectionOptions);
2732 
2733  std::ofstream ofs(sphinxConfigFile.c_str(), std::fstream::trunc);
2734  ofs << *pConf;
2735  ofs.close();
2736 
2737  _isError = false;
2738  }
2739  catch(Poco::Exception& e)
2740  {
2741  errorMsg = e.message();
2742  errorCode = e.code();
2743  }
2744  catch(std::exception& e)
2745  {
2746  errorMsg = e.what();
2748  }
2749  return !_isError;
2750 }
2751 //-----------------------------------------------------------------------------
2752 //-----------------------------------------------------------------------------
2754 :inherited(fObj)
2755 {
2756 }
2757 //-----------------------------------------------------------------------------
2759 {
2760  errorMsg.clear();
2761  errorCode = NO_ERROR;
2762  _isError = true;
2763  try
2764  {
2765  if (!inherited::execute())
2766  throw Poco::Exception(inherited::getErrorMsg(), ERROR_INDEX_RENAME);
2767 
2768  bool isActive = (fObj.getIndexName()==indexFromName);
2769 
2770  IndexRemove indexRemove(fObj);
2771  indexRemove.setIndexName(indexFromName);
2772  if (!indexRemove.execute())
2773  throw Poco::Exception(indexRemove.getErrorMsg(), ERROR_INDEX_RENAME);
2774 
2775  if (isActive)
2777 
2778  _isError = false;
2779  }
2780  catch(Poco::Exception& e)
2781  {
2782  errorMsg = e.message();
2783  errorCode = e.code();
2784  }
2785  return !_isError;
2786 }
2787 //-----------------------------------------------------------------------------
2788 //-----------------------------------------------------------------------------
2790 :inherited(fObj), indexName(""), branchName(""), sectionName(""), parameterName(""), parameterValue("")
2791 {
2792 }
2793 //-----------------------------------------------------------------------------
2794 bool IndexSetConfigVar::serialize(std::string& json)
2795 {
2796  _isError = true;
2797  errorMsg.clear();
2798  try
2799  {
2800  Poco::JSON::Object::Ptr obj = new Poco::JSON::Object();
2806 
2807  std::stringstream ostr;
2808  Poco::JSON::Stringifier::stringify(obj, ostr);
2809  json = ostr.str();
2810 
2811  _isError = false;
2812  }
2813  catch(std::exception& e)
2814  {
2815  errorMsg = e.what();
2817  }
2818  return !_isError;
2819 }
2820 //-----------------------------------------------------------------------------
2821 bool IndexSetConfigVar::unserialize(const std::string& json)
2822 {
2823  indexName.clear();
2824  sectionName.clear();
2825  parameterName.clear();
2826  parameterValue.clear();
2827  errorMsg.clear();
2828  _isError = true;
2829  try
2830  {
2831  Poco::JSON::Parser parser;
2832  Poco::Dynamic::Var res = parser.parse(json);
2833  Poco::JSON::Object::Ptr obj = res.extract<Poco::JSON::Object::Ptr>();
2834 
2835  Poco::Dynamic::Var tmp = obj->get(sphinx_admin_command_const::indexName);
2836  if (tmp.isString())
2837  indexName = tmp.convert<std::string>();
2838 
2840  if (tmp.isString())
2841  branchName = tmp.convert<std::string>();
2842 
2844  if (tmp.isString())
2845  sectionName = tmp.convert<std::string>();
2846 
2848  if (tmp.isString())
2849  parameterName = tmp.convert<std::string>();
2850 
2852  if (tmp.isString())
2853  parameterValue = tmp.convert<std::string>();
2854 
2855  _isError = false;
2856  }
2857  catch(Poco::JSON::JSONException& e)
2858  {
2859  errorMsg = e.displayText();
2861  }
2862  return !_isError;
2863 }
2864 //-----------------------------------------------------------------------------
2866 {
2867  errorMsg.clear();
2868  errorCode = NO_ERROR;
2869  _isError = true;
2870  try
2871  {
2872  std::string path = fObj.getDataDir()+"/"+indexName;
2873  if (!isExistDir(path))
2874  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path));
2875 
2876  const std::string configFile = (branchName.empty())?(path+"/"+sphinx_search_const::sphinxConfigName):(getConfigFileName(path, branchName));
2877  const std::string propFile = (branchName.empty())?(path+"/"+sphinx_search_const::sphinxPropertyFile):(getPropertyFileName(path, branchName));
2878 
2879  Poco::AutoPtr<SphinxConfigCreator> pConf = new SphinxConfigCreator(propFile);
2880 
2881  const std::string name = sectionName+"."+parameterName;
2882  pConf->setString(name, parameterValue);
2883  pConf->save(propFile);
2884  pConf->setPropertyFileConfiguration(propFile);
2885  pConf->deleteSphinxConfigSection(sphinx_admin_command_const::sectionOptions);
2886 
2887  std::ofstream ofs(configFile.c_str(), std::fstream::trunc);
2888  ofs << *pConf;
2889  ofs.close();
2890 
2891  _isError = false;
2892  }
2893  catch(Poco::Exception& e)
2894  {
2895  errorMsg = e.message();
2897  }
2898  return !_isError;
2899 }
2900 //-----------------------------------------------------------------------------
2901 //-----------------------------------------------------------------------------
2903 :inherited(fObj)
2904 {
2905 }
2906 //-----------------------------------------------------------------------------
2907 bool IndexGetConfigVar::serialize(std::string& json)
2908 {
2909  _isError = true;
2910  errorMsg.clear();
2911  try
2912  {
2913  Poco::JSON::Object::Ptr obj = new Poco::JSON::Object();
2917 
2918  std::stringstream ostr;
2919  Poco::JSON::Stringifier::stringify(obj, ostr);
2920  json = ostr.str();
2921 
2922  _isError = false;
2923  }
2924  catch(std::exception& e)
2925  {
2926  errorMsg = e.what();
2928  }
2929  return !_isError;
2930 }
2931 //-----------------------------------------------------------------------------
2932 bool IndexGetConfigVar::unserialize(const std::string& json)
2933 {
2934  indexName.clear();
2935  sectionName.clear();
2936  parameterName.clear();
2937  errorMsg.clear();
2938  _isError = true;
2939  try
2940  {
2941  Poco::JSON::Parser parser;
2942  Poco::Dynamic::Var res = parser.parse(json);
2943  Poco::JSON::Object::Ptr obj = res.extract<Poco::JSON::Object::Ptr>();
2944 
2945  Poco::Dynamic::Var tmp = obj->get(sphinx_admin_command_const::indexName);
2946  if (tmp.isString())
2947  indexName = tmp.convert<std::string>();
2948 
2950  if (tmp.isString())
2951  sectionName = tmp.convert<std::string>();
2952 
2954  if (tmp.isString())
2955  parameterName = tmp.convert<std::string>();
2956 
2957  _isError = false;
2958  }
2959  catch(Poco::JSON::JSONException& e)
2960  {
2961  errorMsg = e.displayText();
2963  }
2964  return !_isError;
2965 }
2966 //-----------------------------------------------------------------------------
2968 {
2969  errorMsg.clear();
2970  errorCode = NO_ERROR;
2971  _isError = true;
2972  try
2973  {
2974  std::string path = fObj.getDataDir()+"/"+indexName;
2975  if (!isExistDir(path))
2976  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path));
2977 
2978  const std::string propFile = (branchName.empty())?(path+"/"+sphinx_search_const::sphinxPropertyFile):(getPropertyFileName(path, branchName));
2979 
2980  Poco::AutoPtr<SphinxConfigCreator> pConf = new SphinxConfigCreator(propFile);
2981 
2982  const std::string name = sectionName+"."+parameterName;
2983  resultData = pConf->getString(name);
2984 
2985  _isError = false;
2986  }
2987  catch(Poco::Exception& e)
2988  {
2989  errorMsg = e.message();
2991  }
2992  return !_isError;
2993 }
2994 //-----------------------------------------------------------------------------
2995 //-----------------------------------------------------------------------------
2997 :inherited(fObj)
2998 {
2999 }
3000 //-----------------------------------------------------------------------------
3002 {
3003  errorMsg.clear();
3004  errorCode = NO_ERROR;
3005  _isError = true;
3006  try
3007  {
3008  std::string path = fObj.getDataDir()+"/"+indexName;
3009  if (!isExistDir(path))
3010  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path), ERROR_INDEX_CHECK_SCHEMA);
3011 
3012  path.append("/").append(sphinx_search_const::sphinxSchemaFile);
3013  std::ifstream ifs(path.c_str(), std::fstream::binary);
3014  if (!ifs.is_open())
3015  throw Poco::Exception(message(message_const::FILE_NOT_OPEN, path) , ERROR_INDEX_CHECK_SCHEMA);
3016 
3017  SphinxSchemaFile oldSchemaFile(ifs);
3018  std::vector<std::pair<std::string, int> > oldSchemaVec;
3019  bool ret = oldSchemaFile.getFields(oldSchemaVec); // need for read all attributes
3020  ifs.close();
3021  if (!ret)
3022  throw Poco::Exception(oldSchemaFile.getErrorMsg(), ERROR_INDEX_CHECK_SCHEMA);
3023 
3024  std::stringstream str;
3026 
3027  std::vector<std::pair<std::string, int> > checkSchemaVec;
3028  SphinxSchemaFile checkSchemaFile(str);
3029  if (!checkSchemaFile.getFields(checkSchemaVec)) // need for read all attributes
3030  throw Poco::Exception(checkSchemaFile.getErrorMsg(), ERROR_INDEX_CHECK_SCHEMA);
3031 
3032  for (size_t i=0;i<checkSchemaVec.size();++i)
3033  {
3034  bool isFound = false;
3035  for (size_t k=0;k<oldSchemaVec.size();++k)
3036  {
3037  if (checkSchemaVec[i].first==oldSchemaVec[k].first)
3038  {
3039  isFound = true;
3040  break;
3041  }
3042  }
3043  if (!isFound)
3045  }
3046 
3047  _isError = false;
3048  }
3049  catch(Poco::Exception& e)
3050  {
3051  errorMsg = e.displayText();
3052  errorCode = e.code();
3053  }
3054  return !_isError;
3055 }
3056 //-----------------------------------------------------------------------------
3057 //-----------------------------------------------------------------------------
3059 :inherited(fObj)
3060 {
3061 }
3062 //-----------------------------------------------------------------------------
3064 {
3065  errorMsg.clear();
3066  errorCode = NO_ERROR;
3067  _isError = true;
3068 
3069  try
3070  {
3071  std::string path = fObj.getDataDir()+"/"+indexName;
3072  if (!isExistDir(path))
3073  throw Poco::Exception(message(message_const::INDEX_NOT_EXIST, path), ERROR_INDEX_SEARCHD_STATUS);
3074 
3075  const std::string configFile = path+"/"+sphinx_search_const::sphinxConfigName;
3076  if (!isExistFile(configFile))
3077  throw Poco::Exception(message(message_const::FILE_NOT_EXIST, configFile), ERROR_INDEX_SEARCHD_STATUS);
3078 
3079  std::stringstream outMsg, errMsg;
3080  const std::string cmd("searchd");
3081  std::vector<std::string> args = {"--status", "--config", configFile};
3082  ProcExec procExec(cmd, args);
3083  if (!procExec.exec(outMsg, errMsg))
3084  throw Poco::Exception((message(message_const::GET_STATUS_SEARCHD_FAIL, configFile)+message(message_const::ERROR, errMsg.str())), ERROR_INDEX_SEARCHD_STATUS);
3085 
3086  if (isExistError(outMsg.str()))
3087  throw Poco::Exception(outMsg.str(), ERROR_INDEX_SEARCHD_STATUS);
3088 
3089  resultData = outMsg.str();
3090 
3091  _isError = false;
3092  }
3093  catch(Poco::Exception& e)
3094  {
3095  errorMsg = e.message();
3096  errorCode = e.code();
3097  }
3098  return !_isError;
3099 }
3100 //-----------------------------------------------------------------------------
3102 {
3103  bool result = false;
3104 
3105  try
3106  {
3107  const std::string propFile = fObj.getDataDir()+"/"+indexName+"/"+sphinx_search_const::sphinxPropertyFile;
3108  Poco::AutoPtr<SphinxConfigCreator> pConf = new SphinxConfigCreator(propFile);
3109  const std::string pidFile = pConf->getString(sphinx_search_const::searchdPidName);
3110  result = isExistFile(pidFile);
3111  }
3112  catch(Poco::Exception& e)
3113  {
3114  errorMsg = e.message();
3116  }
3117  return result;
3118 }
3119 //-----------------------------------------------------------------------------
3120 //-----------------------------------------------------------------------------
3122 :inherited(fObj)
3123 {
3124 }
3125 //-----------------------------------------------------------------------------
3127 {
3128  errorMsg.clear();
3129  errorCode = NO_ERROR;
3130  _isError = true;
3131 
3132  try
3133  {
3134  std::string path = fObj.getDataDir()+"/"+indexName;
3135  if (!isExistDir(path))
3136  throw Poco::Exception(message(message_const::INDEX_NOT_EXIST, path), ERROR_INDEX_STATUS);
3137 
3138  const std::string configFile = path+"/"+sphinx_search_const::sphinxConfigName;
3139  if (!isExistFile(configFile))
3140  throw Poco::Exception(message(message_const::FILE_NOT_EXIST, configFile), ERROR_INDEX_STATUS);
3141 
3142  std::stringstream outMsg;
3143  const std::string cmd("indextool");
3144  std::vector<std::string> args = {"--dumpheader", fObj.getIndexFileName(), "--config", configFile};
3145  ProcExec procExec(cmd, args);
3146  outMsg << procExec;
3147  if (procExec.isError())
3148  throw Poco::Exception(message(message_const::GET_INDEX_STATUS_FAIL, configFile), ERROR_INDEX_STATUS);
3149 
3150  if (isExistError(outMsg.str()))
3151  throw Poco::Exception(outMsg.str(), ERROR_INDEX_STATUS);
3152 
3153  resultData = outMsg.str();
3154 
3155  _isError = false;
3156  }
3157  catch(Poco::Exception& e)
3158  {
3159  errorMsg = e.message();
3160  errorCode = e.code();
3161  }
3162  return !_isError;
3163 }
3164 //-----------------------------------------------------------------------------
3165 //-----------------------------------------------------------------------------
3167 :inherited(fObj)
3168 {
3169 }
3170 //-----------------------------------------------------------------------------
3172 {
3173  errorMsg.clear();
3174  errorCode = NO_ERROR;
3175  _isError = true;
3176 
3177  try
3178  {
3179  unsigned long long maxDocId = 0;
3180  resultData = std::to_string(maxDocId);
3181 
3182  std::string path = fObj.getDataDir()+"/"+indexName;
3183  if (!isExistDir(path))
3184  throw Poco::Exception(message(message_const::INDEX_NOT_EXIST, path), ERROR_INDEX_MAX_DOC_ID);
3185 
3186  std::string dataDir = path+"/"+sphinx_admin_command_const::dataDir;
3187 
3188  if (!isExistDir(dataDir))
3189  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, dataDir), ERROR_INDEX_MAX_DOC_ID);
3190 
3191  std::vector<std::string> vFiles;
3193  throw Poco::Exception(errorMsg, ERROR_INDEX_MAX_DOC_ID);
3194 
3195  std::ifstream ifs;
3196  SphinxDataSourceParameters dataSourceParameters;
3197  for (size_t i=0;i<vFiles.size();++i)
3198  {
3199  const std::string fileName = dataDir+"/"+vFiles[i] +"."+sphinx_admin_command_const::sourceFileExtension;
3200  ifs.open(fileName.c_str());
3201  if (ifs.is_open())
3202  {
3203  if (dataSourceParameters.load(ifs))
3204  {
3205  if (maxDocId < dataSourceParameters.getMaxDocId())
3206  maxDocId = dataSourceParameters.getMaxDocId();
3207  }
3208  else
3209  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::SEARCH_MAX_DOCS_ID_FAIL, fileName) << message(message_const::ERROR, dataSourceParameters.getErrorMsg()) << flush;
3210  ifs.close();
3211  }
3212  else
3213  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::FILE_NOT_OPEN, fileName) << flush;
3214  }
3215 
3216  resultData = std::to_string(maxDocId);
3217  _isError = false;
3218  }
3219  catch(Poco::Exception& e)
3220  {
3221  errorMsg = e.message();
3222  errorCode = e.code();
3223  }
3224  catch(std::exception& e)
3225  {
3226  errorMsg = e.what();
3228  }
3229  return !_isError;
3230 }
3231 //-----------------------------------------------------------------------------
3232 //-----------------------------------------------------------------------------
3234 :inherited(fObj)
3235 {
3236 }
3237 //-----------------------------------------------------------------------------
3239 {
3240  errorMsg.clear();
3241  errorCode = NO_ERROR;
3242  _isError = true;
3243  try
3244  {
3245  if (indexName.empty())
3247 
3248  std::string path = fObj.getDataDir()+"/"+indexName;
3249 
3250  if (!isExistDir(path))
3251  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path), ERROR_INDEX_DATA_LIST);
3252 
3253  std::string dataDir = path+"/"+sphinx_admin_command_const::dataDir;
3254 
3255  if (!isExistDir(path+"/"+sphinx_admin_command_const::dataDir))
3256  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path+"/"+sphinx_admin_command_const::dataDir), ERROR_INDEX_DATA_LIST);
3257 
3258  std::vector<std::string> vFiles;
3260  {
3261  for (size_t i=0;i<vFiles.size();++i)
3262  {
3263  if (!resultData.empty())
3264  resultData.append(",");
3265  resultData.append(vFiles[i]);
3266  }
3267  _isError = false;
3268  }
3269  }
3270  catch(Poco::Exception& e)
3271  {
3272  errorMsg = e.message();
3273  errorCode = e.code();
3274  }
3275  return !_isError;
3276 }
3277 //-----------------------------------------------------------------------------
3278 //-----------------------------------------------------------------------------
3280 :inherited(fObj)
3281 {
3282 }
3283 //-----------------------------------------------------------------------------
3285 {
3286  errorMsg.clear();
3287  errorCode = NO_ERROR;
3288  _isError = true;
3289  try
3290  {
3291  if (indexName.empty())
3293 
3294  std::string path = fObj.getDataDir()+"/"+indexName;
3295 
3296  if (!isExistDir(path))
3297  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path), ERROR_INDEX_BRANCHES_LIST);
3298 
3299  std::string indexDir = path+"/"+sphinx_admin_command_const::indexDir;
3300 
3301  if (!isExistDir(path+"/"+sphinx_admin_command_const::indexDir))
3302  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path+"/"+sphinx_admin_command_const::indexDir), ERROR_INDEX_BRANCHES_LIST);
3303 
3304  std::vector<std::string> vIndexes;
3305  if (getIndexList(indexDir, vIndexes))
3306  {
3307  for (size_t i=0;i<vIndexes.size();++i)
3308  {
3309  if (!resultData.empty())
3310  resultData.append(",");
3311  resultData.append(vIndexes[i]);
3312  }
3313  _isError = false;
3314  }
3315  }
3316  catch(Poco::Exception& e)
3317  {
3318  errorMsg = e.message();
3319  errorCode = e.code();
3320  }
3321  return !_isError;
3322 }
3323 //-----------------------------------------------------------------------------
3324 //-----------------------------------------------------------------------------
3326 :inherited(fObj)
3327 {
3328 }
3329 //-----------------------------------------------------------------------------
3330 bool IndexBranchesInfo::getBranchInfo(const std::string& branchName, const std::string& branchPath, std::string& branchFieldsList)
3331 {
3332  bool result = false;
3333  branchFieldsList.clear();
3334  const std::string branchFileName = branchPath+"/"+branchName+"."+sphinx_admin_command_const::sourceFileExtension;
3335 
3336  try
3337  {
3338  std::ifstream ifs;
3339  SphinxDataSourceParameters dataSourceParameters;
3340  ifs.open(branchFileName.c_str());
3341  if (!ifs.is_open())
3342  throw Poco::Exception(message(message_const::FILE_NOT_OPEN, branchFileName));
3343 
3344  bool loaded = dataSourceParameters.load(ifs);
3345  ifs.close();
3346  if (!loaded)
3347  throw Poco::Exception(message(message_const::LOAD_SOURCE_FILE_FAIL, branchFileName)+message(message_const::ERROR, dataSourceParameters.getErrorMsg()));
3348 
3349  std::string fieldsList;
3350  SphinxDataSourceParameters::PARAM_ATTR__MAP& paramAttr = dataSourceParameters.getParamAttr();
3351  for (SphinxDataSourceParameters::PARAM_ATTR__MAP::iterator iter=paramAttr.begin();iter!=paramAttr.end();++iter)
3352  {
3353  if (!fieldsList.empty())
3354  fieldsList.append(",");
3355  fieldsList.append((*iter).first).append("=").append(std::to_string((*iter).second));
3356  }
3357  Poco::URI::encode(fieldsList, "", branchFieldsList);
3358  result = true;
3359  }
3360  catch(Poco::Exception& e)
3361  {
3362  errorMsg = e.message();
3363  }
3364  return result;
3365 }
3366 //-----------------------------------------------------------------------------
3368 {
3369  errorMsg.clear();
3370  errorCode = NO_ERROR;
3371  _isError = true;
3372  try
3373  {
3374  if (branches.empty())
3376 
3377  std::string path = fObj.getDataDir()+"/"+indexName;
3378 
3379  if (!isExistDir(path))
3380  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, path), ERROR_INDEX_BRANCHES_INFO);
3381 
3382  const std::string indexDir = path+"/"+sphinx_admin_command_const::indexDir;
3383  const std::string dataDir = path+"/"+sphinx_admin_command_const::dataDir;
3384 
3385  if (!isExistDir(indexDir))
3386  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, indexDir), ERROR_INDEX_BRANCHES_INFO);
3387 
3388  if (!isExistDir(dataDir))
3389  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, dataDir), ERROR_INDEX_BRANCHES_INFO);
3390 
3391  std::vector<std::string> vFiles;
3393  {
3394  unsigned int madeFailCount = 0;
3395  if (branches.front()=="*")
3396  {
3397  for (size_t i=0;i<vFiles.size();++i)
3398  {
3399  std::string branchFieldsList;
3400  if (getBranchInfo(vFiles[i], dataDir, branchFieldsList))
3401  {
3402  if (!resultData.empty())
3403  resultData.append("&");
3404  resultData.append(vFiles[i]).append("=").append(branchFieldsList);
3405  }
3406  else
3407  ++madeFailCount;
3408  }
3409  }
3410  else
3411  {
3412  for (size_t k=0;k<branches.size();++k)
3413  for (size_t i=0;i<vFiles.size();++i)
3414  if (vFiles[i]==branches[k])
3415  {
3416  std::string branchFieldsList;
3417  if (getBranchInfo(vFiles[i], dataDir, branchFieldsList))
3418  {
3419  if (!resultData.empty())
3420  resultData.append("&");
3421  resultData.append(vFiles[i]).append("=").append(branchFieldsList);
3422  }
3423  else
3424  ++madeFailCount;
3425  break;
3426  }
3427  }
3428  if (madeFailCount==0)
3429  _isError = false;
3430  }
3431 
3432  if (_isError)
3433  throw Poco::Exception(errorMsg, ERROR_INDEX_BRANCHES_INFO);
3434  }
3435  catch(Poco::Exception& e)
3436  {
3437  errorMsg = e.message();
3438  errorCode = e.code();
3439  }
3440  return !_isError;
3441 }
3442 //-----------------------------------------------------------------------------
3443 //-----------------------------------------------------------------------------
3445 :inherited(fObj)
3446 {
3447 }
3448 //-----------------------------------------------------------------------------
3449 bool IndexBranchesStatus::makeBranchConfig(const std::string& indexName, const std::string& indexFileName, std::string& configFile)
3450 {
3451  bool result = false;
3452  const std::string path = fObj.getDataDir()+"/"+indexName;
3453  const std::string propFile = path+"/"+sphinx_search_const::sphinxPropertyFile;
3454  configFile = path+"/"+sphinx_search_const::branchConfigFile;
3455  try
3456  {
3457  Poco::AutoPtr<SphinxConfigCreator> pConf = new SphinxConfigCreator(propFile);
3458  std::vector<std::string> keys;
3459  pConf->keys(keys);
3460 
3461  std::string trunkSectionName;
3462  for (size_t i=0;i<keys.size();++i)
3463  {
3464  if (keys[i].find(sphinx_search_const::sourceNameField)!=std::string::npos)
3465  {
3466  std::string name = keys[i]+"."+sphinx_search_const::xmlpipeCommandNameField;
3467  std::string value = "cat "+path+"/"+sphinx_admin_command_const::dataDir+"/"+indexFileName+"."+sphinx_admin_command_const::sourceFileExtension;
3468  pConf->setString(name, value);
3469  }
3470  if (keys[i].find(sphinx_search_const::indexNameField)!=std::string::npos)
3471  trunkSectionName = keys[i];
3472  }
3474  std::string value = path+"/"+fObj.getIndexFileName();
3475  pConf->setString(name, value);
3476 
3477  std::string branchSectionName = sphinx_search_const::indexNameField+" "+indexFileName;
3478  pConf->cloneSphinxConfigSection(trunkSectionName, branchSectionName);
3479 
3480  name = branchSectionName+"."+sphinx_search_const::pathNameField;
3482  pConf->setString(name, value);
3483 
3484  value = fObj.getLogDir()+"/"+indexName+"/"+sphinx_search_const::searchdLogFile;
3485  pConf->setString(sphinx_search_const::searchdLogName, value);
3486 
3487  value = fObj.getRunDir()+"/"+/*indexName+"/"+*/
3488  sphinx_search_const::searchdPidFileName+"_"+indexName+"."+
3490  pConf->setString(sphinx_search_const::searchdPidName, value);
3491 
3492  value = fObj.getLogDir()+"/"+indexName+"/"+sphinx_search_const::searchdQueryLogFile;
3493  pConf->setString(sphinx_search_const::searchdQueryLogName, value);
3494 
3495  pConf->save(propFile);
3496  pConf->setPropertyFileConfiguration(propFile);
3497  pConf->deleteSphinxConfigSection(sphinx_admin_command_const::sectionOptions);
3498 
3499  std::ofstream ofs(configFile.c_str(), std::fstream::trunc);
3500  ofs << *pConf;
3501  ofs.close();
3502  result = true;
3503  }
3504  catch(Poco::Exception& e)
3505  {
3506  errorMsg = e.message();
3507  fObj.log(LoggerStream::Priority::PRIO_INFORMATION) << message(message_const::ERROR_MAKE_BRANCH_CONFIG, errorMsg) << flush;
3508  }
3509  return result;
3510 
3511 
3512 }
3513 //-----------------------------------------------------------------------------
3514 bool IndexBranchesStatus::getBranchInfo(const std::string& indexName, const std::string& indexFileName, std::string& information)
3515 {
3516  bool result = false;
3517  information.clear();
3518 
3519  try
3520  {
3521  std::string branchConfigFileName;
3522  if (!makeBranchConfig(indexName, indexFileName, branchConfigFileName))
3523  throw Poco::Exception(errorMsg, ERROR_INDEX_STATUS);
3524 
3525  if (!isExistFile(branchConfigFileName))
3526  throw Poco::Exception(message(message_const::FILE_NOT_EXIST, branchConfigFileName), ERROR_INDEX_STATUS);
3527 
3528  std::stringstream outMsg, errMsg;
3529  const std::string cmd("indextool");
3530  std::vector<std::string> args = {"--dumpheader", indexFileName, "--config", branchConfigFileName};
3531  ProcExec procExec(cmd, args);
3532  if (!procExec.exec(outMsg, errMsg))
3533  throw Poco::Exception(message(message_const::GET_INDEX_STATUS_FAIL, indexFileName)+message(message_const::ERROR, errMsg.str()), ERROR_INDEX_STATUS);
3534 
3535  if (isExistError(outMsg.str()))
3536  throw Poco::Exception(outMsg.str(), ERROR_INDEX_STATUS);
3537 
3538  Poco::URI::encode(outMsg.str(), "", information);
3539 
3540  result = removeFile(branchConfigFileName);
3541  }
3542  catch(Poco::Exception& e)
3543  {
3544  errorMsg.append(e.message());
3545  errorCode = e.code();
3546  }
3547  return result;
3548 }
3549 //-----------------------------------------------------------------------------
3551 {
3552  errorMsg.clear();
3553  errorCode = NO_ERROR;
3554  _isError = true;
3555  try
3556  {
3557  if (branches.empty())
3559 
3560  std::string path = fObj.getDataDir()+"/"+indexName;
3561 
3562  if (!isExistDir(path))
3564 
3565  std::string indexDir = path+"/"+sphinx_admin_command_const::indexDir;
3566  std::string dataDir = path+"/"+sphinx_admin_command_const::dataDir;
3567 
3568  if (!isExistDir(indexDir))
3569  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, indexDir), ERROR_INDEX_BRANCHES_STATUS);
3570 
3571  if (!isExistDir(dataDir))
3572  throw Poco::Exception(message(message_const::FOLDER_NOT_EXIST, dataDir), ERROR_INDEX_BRANCHES_STATUS);
3573 
3574  std::vector<std::string> vIndexes;
3575  if (getIndexList(indexDir, vIndexes))
3576  {
3577  unsigned int madeFailCount = 0;
3578  if (branches.front()=="*")
3579  {
3580  for (size_t i=0;i<vIndexes.size();++i)
3581  {
3582  std::string information;
3583  if (getBranchInfo(indexName, vIndexes[i], information))
3584  {
3585  if (!resultData.empty())
3586  resultData.append("&");
3587  resultData.append(vIndexes[i]).append("=").append(information);
3588  }
3589  else
3590  ++madeFailCount;
3591  }
3592  }
3593  else
3594  {
3595  for (size_t k=0;k<branches.size();++k)
3596  for (size_t i=0;i<vIndexes.size();++i)
3597  if (vIndexes[i]==branches[k])
3598  {
3599  std::string information;
3600  if (getBranchInfo(indexName, vIndexes[i], information))
3601  {
3602  if (!resultData.empty())
3603  resultData.append("&");
3604  resultData.append(vIndexes[i]).append("=").append(information);
3605  }
3606  else
3607  ++madeFailCount;
3608  break;
3609  }
3610  }
3611  if (madeFailCount==0)
3612  _isError = false;
3613  }
3614 
3615  if (_isError)
3616  throw Poco::Exception(errorMsg, ERROR_INDEX_BRANCHES_STATUS);
3617  }
3618  catch(Poco::Exception& e)
3619  {
3620  errorMsg = e.message();
3621  errorCode = e.code();
3622  }
3623  return !_isError;
3624 }
3625 //-----------------------------------------------------------------------------
3627 :inherited(fObj)
3628 {
3629 }
3630 //-----------------------------------------------------------------------------
3632 {
3633  errorMsg.clear();
3634  errorCode = NO_ERROR;
3635  _isError = true;
3636 
3637  try
3638  {
3639  if (indexName.empty() && fObj.getIndexName().empty())
3641 
3642  std::string path = (indexName.empty())?(fObj.getDataDir()+"/"+fObj.getIndexName()):(fObj.getDataDir()+"/"+indexName);
3643 
3644  if (!isExistDir(path))
3645  throw Poco::Exception(message(message_const::INDEX_NOT_EXIST, path), ERROR_INDEX_CONNECT);
3646 
3647  path.append("/").append(sphinx_search_const::sphinxConfigName);
3648  if (!isExistFile(path))
3649  throw Poco::Exception(message(message_const::FILE_NOT_EXIST, path), ERROR_INDEX_CONNECT);
3650 
3651  if (!indexName.empty())
3653 
3655  throw Poco::Exception(fObj.getErrorMsg(), ERROR_INDEX_CONNECT);
3656 
3657  if (fObj.isConnected())
3658  if (!fObj.close())
3659  throw Poco::Exception(fObj.getErrorMsg(), ERROR_INDEX_CONNECT);
3660 
3661  if (!fObj.easyStart())
3662  throw Poco::Exception(fObj.getErrorMsg(), ERROR_INDEX_CONNECT);
3663 
3664  _isError = false;
3665  }
3666  catch(Poco::Exception& e)
3667  {
3668  errorMsg = e.message();
3669  errorCode = e.code();
3670  }
3671  return !_isError;
3672 }
3673 //-----------------------------------------------------------------------------
3674 //-----------------------------------------------------------------------------
3676 :inherited(fObj)
3677 {
3678 }
3679 //-----------------------------------------------------------------------------
3680 bool IndexDisconnect::serialize(std::string& json)
3681 {
3682  _isError = true;
3683  errorMsg.clear();
3684  try
3685  {
3686  Poco::JSON::Object::Ptr obj = new Poco::JSON::Object();
3687 
3688  std::stringstream ostr;
3689  Poco::JSON::Stringifier::stringify(obj, ostr);
3690  json = ostr.str();
3691 
3692  _isError = false;
3693  }
3694  catch(std::exception& e)
3695  {
3696  errorMsg = e.what();
3698  }
3699  return !_isError;
3700 }
3701 //-----------------------------------------------------------------------------
3702 bool IndexDisconnect::unserialize(const std::string& json)
3703 {
3704  errorMsg.clear();
3705  _isError = true;
3706  try
3707  {
3708  Poco::JSON::Parser parser;
3709  Poco::Dynamic::Var res = parser.parse(json);
3710  Poco::JSON::Object::Ptr obj = res.extract<Poco::JSON::Object::Ptr>();
3711 
3712  _isError = false;
3713  }
3714  catch(Poco::JSON::JSONException& e)
3715  {
3716  errorMsg = e.displayText();
3718  }
3719  return !_isError;
3720 }
3721 //-----------------------------------------------------------------------------
3723 {
3724  errorMsg.clear();
3725  errorCode = NO_ERROR;
3726  _isError = true;
3727 
3728  try
3729  {
3730  if (fObj.isConnected())
3731  if (!fObj.close())
3732  throw Poco::Exception(fObj.getErrorMsg(), ERROR_INDEX_DISCONNECT);
3733 
3734  _isError = false;
3735  }
3736  catch(Poco::Exception& e)
3737  {
3738  errorMsg = e.message();
3739  errorCode = e.code();
3740  }
3741  return !_isError;
3742 }
3743 //-----------------------------------------------------------------------------
3744 //-----------------------------------------------------------------------------
3745 } // end namespace sphinx
3746 } // end namespace HCE