Scid  4.7.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
sc_base.cpp
Go to the documentation of this file.
1 /*
2 # Copyright (C) 2015 Fulvio Benini
3 
4 * This file is part of Scid (Shane's Chess Information Database).
5 *
6 * Scid is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation.
9 *
10 * Scid is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Scid. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include "common.h"
20 #include "dbasepool.h"
21 #include "misc.h"
22 #include "scidbase.h"
23 #include "searchtournaments.h"
24 #include "ui.h"
25 #include <cstring>
26 #include <string>
27 
28 namespace {
29 /*
30 * This "sc_base" functions are used by the UI to access the databases.
31 * To encapsulate database internal complexity this functions should only
32 * parse arguments and call other functions/objects.
33 *
34 * Command names are case sensitive
35 * Optional parameter are indicated using [value_opt]
36 * Alternative values are indicated using <value_a|value_b|value_c>
37 * BaseId is the handle used to select the database to work on
38 * "dbfilter" is the name of the default filter of database
39 * Games are numbered starting from "1"
40 * Example:
41 * sc_base open "filename" -> on success returns a baseId handle to the opened database
42 * sc_base gameslist baseId "1" "10" "dbfilter" "N+"
43 * -> returns the list of the first 10 games of the database
44 */
45 
46 
47 /**
48  * doOpenBase() - open/create a database
49  * @filename: the filename of the database to open/create
50  * @fMode: open the database read-only|read-write|create|in_memory
51  * @codec: the type of the database
52  *
53  * If @fMode == FMODE_Both, and the file cannot be opened for writing, this
54  * function will try to open the database read-only.
55  */
56 static UI_res_t doOpenBase(UI_handle_t ti, const char* filename,
57  fileModeT fMode, ICodecDatabase::Codec codec) {
58  if (DBasePool::find(filename) != 0) return UI_Result(ti, ERROR_FileInUse);
59 
61  if (dbase == 0) return UI_Result(ti, ERROR_Full);
62 
63  Progress progress = UI_CreateProgress(ti);
64  errorT err = dbase->Open(codec, fMode, filename, progress);
65 
66  if ((err == ERROR_FileOpen || err == ERROR_FileMode) &&
67  fMode == FMODE_Both) {
68  err = dbase->Open(codec, FMODE_ReadOnly, filename, progress);
69  }
70  progress.report(1,1);
71 
72  if (err != OK && err != ERROR_NameDataLoss) return UI_Result(ti, err);
73 
74  int res = DBasePool::switchCurrent(dbase);
75  return UI_Result(ti, err, res);
76 }
77 
78 
79 /**
80  * sc_base_close() - close a database
81  */
82 UI_res_t sc_base_close(scidBaseT* dbase, UI_handle_t ti, int, const char**) {
83  if (dbase->getFileName() == "<clipbase>") {
84  return UI_Result(ti, ERROR_BadArg, "Cannot close clipbase.");
85  }
86  return UI_Result(ti, dbase->Close());
87 }
88 
89 
90 /**
91  * sc_base_compact() - compact a database
92  * @stats: if used do not compact the database but calculate stats
93  *
94  * Compacting a database:
95  * - remove all the games marked as "deleted"
96  * - remove unused names
97  * - makes search operations faster
98  * - replace bad names with "???"
99  */
100 UI_res_t sc_base_compact(scidBaseT* dbase, UI_handle_t ti, int argc,
101  const char** argv) {
102  const char* usage = "Usage: sc_base compact baseId [stats]";
103 
104  if (argc == 3) {
105  errorT res = dbase->compact(UI_CreateProgress(ti));
106  return UI_Result(ti, res);
107  } else if (argc == 4 && std::strcmp("stats", argv[3]) == 0) {
108  unsigned long long n_deleted, n_unused, n_sparse, n_badNameId;
109  errorT res = dbase->getCompactStat(&n_deleted, &n_unused, &n_sparse,
110  &n_badNameId);
111  UI_List val(4);
112  val.push_back(n_deleted);
113  val.push_back(n_unused);
114  val.push_back(n_sparse);
115  val.push_back(n_badNameId);
116  return UI_Result(ti, res, val);
117  }
118 
119  return UI_Result(ti, ERROR_BadArg, usage);
120 }
121 
122 
123 /**
124  * sc_base_copygames() - copy games from a database to another
125  */
126 UI_res_t sc_base_copygames(scidBaseT* dbase, UI_handle_t ti, int argc, const char** argv)
127 {
128  const char* usage = "Usage: sc_base copygames baseId <gameNum|filterName> targetBaseId";
129  if (argc != 5) return UI_Result(ti, ERROR_BadArg, usage);
130 
131  scidBaseT* targetBase = DBasePool::getBase(strGetUnsigned(argv[4]));
132  if (targetBase == 0)
133  return UI_Result(ti, ERROR_BadArg, "sc_base copygames error: wrong targetBaseId");
134  if (targetBase->isReadOnly())
135  return UI_Result(ti, ERROR_FileReadOnly);
136 
137  errorT err = OK;
138  const HFilter filter = dbase->getFilter(argv[3]);
139  if (filter != 0) {
140  err = targetBase->importGames(dbase, filter, UI_CreateProgress(ti));
141  } else {
142  uint gNum = strGetUnsigned (argv[3]);
143  if (gNum == 0)
144  return UI_Result(ti, ERROR_BadArg, "sc_base copygames error: wrong <gameNum|filterName>");
145  err = targetBase->importGame(dbase, gNum -1);
146  }
147  return UI_Result(ti, err);
148 }
149 
150 
151 /**
152  * sc_base_create() - crate a database
153  * @codec : the type of the database
154  * @filename: the filename of the wanted database.
155  * Database in native Scid format do not use extension ("example").
156  * Other databases require file extension ("example.pgn").
157  *
158  * Return:
159  * - on success the handle assigned to the database
160  */
161 UI_res_t sc_base_create(UI_handle_t ti, int argc, const char** argv) {
162  const char* usage = "Usage: sc_base create <MEMORY|SCID4|PGN> filename";
163  if (argc != 4 && argc != 3) return UI_Result(ti, ERROR_BadArg, usage);
164 
165  // Old interface defaults to SCID4
167  if (argc == 4) {
168  if (std::strcmp("MEMORY", argv[2]) == 0)
169  codec = ICodecDatabase::MEMORY;
170  else if (std::strcmp("SCID4", argv[2]) == 0)
171  codec = ICodecDatabase::SCID4;
172  else if (std::strcmp("PGN", argv[2]) == 0)
173  codec = ICodecDatabase::PGN;
174  else
175  return UI_Result(ti, ERROR_BadArg, usage);
176  }
177 
178  return doOpenBase(
179  ti, argc == 4 ? argv[3] : argv[2],
180  codec == ICodecDatabase::MEMORY ? FMODE_Memory : FMODE_Create, codec);
181 }
182 
183 
184 /**
185  * sc_base_extra() - get/set a database extra tag (i.e. "description" or "type")
186  */
187 UI_res_t sc_base_extra(scidBaseT* dbase, UI_handle_t ti, int argc, const char** argv)
188 {
189  const char* usage = "Usage: sc_base extra baseId [tagname new_value]";
190 
191  if (argc == 3) {
192  auto list = dbase->getExtraInfo();
193  UI_List res(list.size() * 2);
194  for (const auto& e : list) {
195  res.push_back(e.first);
196  res.push_back(e.second.c_str());
197  }
198  return UI_Result(ti, OK, res);
199  }
200  if (argc == 5) {
201  return UI_Result(ti, dbase->setExtraInfo(argv[3], argv[4]));
202  }
203 
204  return UI_Result(ti, ERROR_BadArg, usage);
205 }
206 
207 
208 /**
209  * sc_base_filename() - get the filename of a database
210  *
211  * Return:
212  * the full path filename for non native databases (like pgn)
213  * the full path filename without the .si4 extension for native Scid databases
214  * <clipbase> for the clipbase
215  */
216 UI_res_t sc_base_filename(scidBaseT* dbase, UI_handle_t ti, int argc,
217  const char**) {
218  const char* usage = "Usage: sc_base filename baseId";
219  if (argc != 3) return UI_Result(ti, ERROR_BadArg, usage);
220 
221  return UI_Result(ti, OK, dbase->getFileName());
222 }
223 
224 
225 /**
226  * sc_base_gameflag() - get/set a game flag (i.e. "D" for deleted)
227  *
228  * Return: a boolean value if the requested operation is "get"
229  */
230 UI_res_t sc_base_gameflag(scidBaseT* dbase, UI_handle_t ti, int argc, const char** argv)
231 {
232  const char* usage = "Usage: sc_base gameflag baseId <gameNum|filterName|all> <get|set|unset|invert> flagType";
233  if (argc != 6) return UI_Result(ti, ERROR_BadArg, usage);
234 
235  int cmd = 0;
236  if (std::strcmp("get", argv[4]) == 0)
237  cmd = 1;
238  else if (std::strcmp("set", argv[4]) == 0)
239  cmd = 2;
240  else if (std::strcmp("unset", argv[4]) == 0)
241  cmd = 3;
242  else if (std::strcmp("invert", argv[4]) == 0)
243  cmd = 4;
244  uint flagType = IndexEntry::CharToFlagMask(argv[5][0]);
245  if (flagType != 0 && cmd != 0) {
246  bool value = (cmd == 2);
247 
248  const HFilter filter = dbase->getFilter(argv[3]);
249  if (filter != 0 || (std::strcmp("all", argv[3]) == 0)) {
250  switch (cmd) {
251  case 2:
252  case 3: return UI_Result(ti, dbase->setFlag(value, flagType, filter));
253  case 4: return UI_Result(ti, dbase->invertFlag(flagType, filter));
254  }
255  } else {
256  gamenumT gNum = strGetUnsigned(argv[3]);
257  if (gNum > 0 && gNum <= dbase->numGames()) {
258  gNum--;
259  switch (cmd) {
260  case 1: return UI_Result(ti, OK, dbase->getFlag(flagType, gNum));
261  case 2:
262  case 3: return UI_Result(ti, dbase->setFlag(value, flagType, gNum));
263  case 4: return UI_Result(ti, dbase->invertFlag(flagType, gNum));
264  }
265  }
266  }
267  }
268 
269  return UI_Result(ti, ERROR_BadArg, usage);
270 }
271 
272 
273 /**
274  * sc_base_gamelocation() - find the position of a game
275  * @sortCrit: the order for the list of games to search
276  * @gnumber: the number of the game to search for
277  * @text: if (@gnumber == 0) search the first game that contains @text in
278  * white name or black name or event name or site name
279  * @start_pos: used only with @text, start searching from a zero-based position.
280  * @forward_dir: <true|false>, used only with @start_pos.
281  * if @e true search in the range [start_pos, numGames)
282  * if @e false search in the range [0, start_pos)
283  *
284  * Return: the position (0 == first) of the first match or "none" if not found
285  */
286 UI_res_t sc_base_gamelocation(scidBaseT* dbase, UI_handle_t ti, int argc, const char** argv)
287 {
288  const char* usage = "Usage: sc_base gamelocation baseId filterName sortCrit <gnumber | 0 text start_pos forward_dir>";
289  if (argc < 6) return UI_Result(ti, ERROR_BadArg, usage);
290 
291  const HFilter filter = dbase->getFilter(argv[3]);
292  if (filter == 0) return UI_Result(ti, ERROR_BadArg, usage);
293 
294  const char* sort = argv[4];
295  gamenumT gnumber = strGetUnsigned(argv[5]);
296  size_t location = INVALID_GAMEID;
297  if (gnumber == 0) {
298  if (argc != 9)
299  return UI_Result(ti, ERROR_BadArg, usage);
300  const char* text = argv[6];
301  size_t start = strGetUnsigned(argv[7]);
302  const NameBase* nb = dbase->getNameBase();
303  auto contains = [dbase, nb, text](gamenumT g) {
304  const IndexEntry* ie = dbase->getIndexEntry(g);
305  return strAlphaContains(ie->GetWhiteName(nb), text) ||
306  strAlphaContains(ie->GetBlackName(nb), text) ||
307  strAlphaContains(ie->GetEventName(nb), text) ||
308  strAlphaContains(ie->GetSiteName(nb), text);
309  };
310  if (strGetBoolean(argv[8])) {
311  std::vector<gamenumT> buf(filter->size() - start);
312  buf.resize(
313  dbase->listGames(sort, start, buf.size(), filter, buf.data()));
314  auto it = std::find_if(buf.begin(), buf.end(), contains);
315  if (it != buf.end())
316  location = start + std::distance(buf.begin(), it);
317  } else {
318  std::vector<gamenumT> buf(start);
319  buf.resize(dbase->listGames(sort, 0, start, filter, buf.data()));
320  auto it = std::find_if(buf.rbegin(), buf.rend(), contains);
321  if (it != buf.rend())
322  location = std::distance(it, buf.rend()) - 1;
323  }
324  } else {
325  location = dbase->sortedPosition(sort, filter, gnumber - 1);
326  }
327  if (location == INVALID_GAMEID)
328  return UI_Result(ti, OK, "none"); // Not found
329  return UI_Result(ti, OK, location);
330 }
331 
332 
333 /**
334  * sc_base_gameslist() - returns the sorted list of games of a database
335  * @start: 0 for the first game
336  */
337 UI_res_t sc_base_gameslist(scidBaseT* dbase, UI_handle_t ti, int argc, const char** argv)
338 {
339  const char* usage = "Usage: sc_base gameslist baseId start count filterName sortCrit";
340  if (argc != 7) return UI_Result(ti, ERROR_BadArg, usage);
341 
342  size_t start = strGetUnsigned(argv[3]);
343  size_t count = strGetUnsigned(argv[4]);
344  const HFilter filter = dbase->getFilter(argv[5]);
345  if (filter == NULL)
346  return UI_Result(ti, ERROR_BadArg, usage);
347  gamenumT* idxList = new gamenumT[count];
348  count = dbase->listGames(argv[6], start, count, filter, idxList);
349 
350  UI_List res (count * 3);
351  UI_List ginfo(24);
352  const NameBase* nb = dbase->getNameBase();
353  for (uint i = 0; i < count; ++i) {
354  uint idx = idxList[i];
355 
356  ASSERT(filter->get(idx) != 0);
357  uint ply = filter->get(idx) -1;
358 
359  const IndexEntry* ie = dbase->getIndexEntry(idx);
360 
361  ginfo.clear();
362  ginfo.push_back(idx +1);
363  ginfo.push_back(RESULT_STR[ie->GetResult()]);
364  ginfo.push_back((ie->GetNumHalfMoves() + 1) / 2);
365  ginfo.push_back(ie->GetWhiteName(nb));
366  std::string eloStr;
367  eloT welo = ie->GetWhiteElo();
368  if (welo != 0) {
369  eloStr = std::to_string(welo);
370  } else {
371  welo = ie->GetWhiteElo(nb);
372  eloStr = std::to_string(welo);
373  if (welo != 0) {
374  eloStr.insert(eloStr.begin(), '(');
375  eloStr.insert(eloStr.end(), ')');
376  }
377  }
378  ginfo.push_back(eloStr);
379  ginfo.push_back(ie->GetBlackName(nb));
380  eloT belo = ie->GetBlackElo();
381  if (belo != 0) {
382  eloStr = std::to_string(belo);
383  } else {
384  belo = ie->GetBlackElo(nb);
385  eloStr = std::to_string(belo);
386  if (belo != 0) {
387  eloStr.insert(eloStr.begin(), '(');
388  eloStr.insert(eloStr.end(), ')');
389  }
390  }
391  ginfo.push_back(eloStr);
392  char buf_date[16];
393  date_DecodeToString (ie->GetDate(), buf_date);
394  ginfo.push_back(buf_date);
395  ginfo.push_back(ie->GetEventName(nb));
396  ginfo.push_back(ie->GetRoundName(nb));
397  ginfo.push_back(ie->GetSiteName(nb));
398  ginfo.push_back(ie->GetNagCount());
399  ginfo.push_back(ie->GetCommentCount());
400  ginfo.push_back(ie->GetVariationCount());
401  char deleted[2] = {0};
402  deleted[0] = (ie->GetDeleteFlag()) ? 'D' : ' ';
403  ginfo.push_back(deleted);
404  char flags[16];
405  ie->GetFlagStr (flags, "WBMENPTKQ!?U123456");
406  ginfo.push_back(flags);
407  ecoStringT ecoStr;
408  eco_ToExtendedString (ie->GetEcoCode(), ecoStr);
409  ginfo.push_back(ecoStr);
410  std::string endMaterial = matsig_makeString(ie->GetFinalMatSig());
411  ginfo.push_back(endMaterial);
412  char startpos[2] = {0};
413  startpos[0] = (ie->GetStartFlag()) ? 'S' : ' ';
414  ginfo.push_back(startpos);
415  char buf_eventdate[16];
416  date_DecodeToString (ie->GetEventDate(), buf_eventdate);
417  ginfo.push_back(buf_eventdate);
418  ginfo.push_back(ie->GetYear());
419  ginfo.push_back((welo + belo)/2);
420  ginfo.push_back(ie->GetRating(nb));
421  FastGame game = dbase->getGame(ie);
422  ginfo.push_back(game.getMoveSAN(ply, 10));
423 
424  res.push_back(std::to_string(idx+1) + "_" + std::to_string(ply));
425  res.push_back(ginfo);
426  res.push_back(deleted);
427  }
428 
429  delete [] idxList;
430  return UI_Result(ti, OK, res);
431 }
432 
433 static UI_res_t sc_base_getGameHelper(UI_handle_t ti, Game& game) {
434  auto positions = gamepos::collectPositions(game);
435  UI_List res(positions.size());
436  UI_List posInfo(6);
437  for (const auto& pos : positions) {
438  posInfo.clear();
439  posInfo.push_back(pos.RAVdepth);
440  posInfo.push_back(pos.RAVnum);
441  posInfo.push_back(pos.FEN);
442  std::string nags;
443  for (const auto& nag : pos.NAGs) {
444  char temp[16];
445  game_printNag(nag, temp, true, PGN_FORMAT_Plain);
446  if (!nags.empty())
447  nags += ' ';
448  nags += temp;
449  }
450  posInfo.push_back(nags);
451  posInfo.push_back(pos.comment);
452  posInfo.push_back(pos.lastMoveSAN);
453  res.push_back(posInfo);
454  }
455  return UI_Result(ti, OK, res);
456 }
457 
458 /**
459  * sc_base_getGame() - return all the positions of a game
460  * @param gameNum: the number of the requested game
461  * @param live: optional parameter which specify the behavior when the requested
462  * game have unsaved changes. If present the latest unsaved version is returned,
463  * otherwise the saved copy in the database is used.
464  *
465  * Return a list containing all the positions of a game, including variations.
466  * The positions are sorted according to pgn standard:
467  * "The alternate move sequence given by an RAV is one that may be legally
468  * played by first unplaying the move that appears immediately prior to the
469  * RAV". For each position the following informations are provided: RAVdepth:
470  * current variation depth. RAVnum: current variation num. FEN: "Forsyth-Edwards
471  * Notation" describing the current position. NAGS: "Numeric Annotation Glyph"
472  * is a non-negative integer from 0 to 255 used to indicate a simple annotation
473  * in a language independent manner. comment: text annotation of the
474  * current position. lastMoveSAN: the last move that was played to reach the
475  * current position. The move is indicated using English "Standard Algebraic
476  * Notation".
477  */
478 UI_res_t sc_base_getGame(scidBaseT* dbase, UI_handle_t ti, int argc,
479  const char** argv) {
480  const char* usage = "Usage: sc_base getGame baseId gameNum [live]";
481  bool live = (argc == 5 && std::strcmp("live", argv[4]) == 0);
482  if (!live && argc != 4)
483  return UI_Result(ti, ERROR_BadArg, usage);
484 
485  gamenumT gNum = strGetUnsigned(argv[3]);
486  if (live && dbase->gameNumber == (static_cast<long long>(gNum) - 1)) {
487  auto location = dbase->game->currentLocation();
488  auto res = sc_base_getGameHelper(ti, *(dbase->game));
489  dbase->game->restoreLocation(location);
490  return res;
491  }
492 
493  auto ie = (gNum > 0) ? dbase->getIndexEntry_bounds(gNum - 1) : nullptr;
494  if (!ie)
495  return UI_Result(ti, ERROR_BadArg, usage);
496 
497  Game game;
498  errorT err = dbase->getGame(*ie, game);
499  if (err != OK)
500  return UI_Result(ti, err);
501  return sc_base_getGameHelper(ti, game);
502 }
503 
504 /**
505  * sc_base_import() - import games from non-native database
506  *
507  * Return:
508  * On success, returns a list of two elements: the number of
509  * games imported and a string containing import errors
510  * or warnings.
511  */
512 UI_res_t sc_base_import(scidBaseT* dbase, UI_handle_t ti, int argc, const char** argv)
513 {
514  const char* usage = "Usage: sc_base import baseId filename";
515  if (argc != 4) return UI_Result(ti, ERROR_BadArg, usage);
516 
517  // if (pgn)
518  auto codec = ICodecDatabase::PGN;
519 
520  auto nImported = dbase->numGames();
521  std::string errorMsg;
522  auto res_imp =
523  dbase->importGames(codec, argv[3], UI_CreateProgress(ti), errorMsg);
524  if (res_imp != OK)
525  return UI_Result(ti, res_imp);
526 
527  UI_List res(2);
528  res.push_back(dbase->numGames() - nImported);
529  res.push_back(errorMsg);
530  return UI_Result(ti, OK, res);
531 }
532 
533 
534 /**
535  * sc_base_list() - return a baseId list of opened databases
536  */
537 UI_res_t sc_base_list(UI_handle_t ti, int argc, const char**) {
538  const char* usage = "Usage: sc_base list";
539  if (argc != 2) return UI_Result(ti, ERROR_BadArg, usage);
540 
541  std::vector<int> l = DBasePool::getHandles();
542  UI_List res(l.size());
543  for (size_t i=0, n=l.size(); i < n; i++) res.push_back(l[i]);
544  return UI_Result(ti, OK, res);
545 }
546 
547 
548 /**
549  * sc_base_numGames() - return the number of games in the database
550  */
551 UI_res_t sc_base_numGames(scidBaseT* dbase, UI_handle_t ti, int argc,
552  const char**) {
553  const char* usage = "Usage: sc_base numGames baseId";
554  if (argc != 3) return UI_Result(ti, ERROR_BadArg, usage);
555 
556  return UI_Result(ti, OK, dbase->numGames());
557 }
558 
559 
560 /**
561  * sc_base_open() - open a database
562  * @codec : the type of the database
563  * @filename: the filename of the wanted database.
564  * Database in native Scid format do not use extension ("example").
565  * Other databases require file extension ("example.pgn").
566  *
567  * Return:
568  * - on success or with ERROR_NameDataLoss: the handle assigned to the database
569  */
570 UI_res_t sc_base_open(UI_handle_t ti, int argc, const char** argv) {
571  const char* usage = "Usage: sc_base open <SCID4|PGN> filename";
572  if (argc != 4 && argc != 3) return UI_Result(ti, ERROR_BadArg, usage);
573 
574  // Old interface defaults to SCID4
576  if (argc == 4) {
577  if (std::strcmp("SCID4", argv[2]) == 0)
578  codec = ICodecDatabase::SCID4;
579  else if (std::strcmp("PGN", argv[2]) == 0)
580  codec = ICodecDatabase::PGN;
581  else
582  return UI_Result(ti, ERROR_BadArg, usage);
583  }
584 
585  return doOpenBase(ti, argc == 4 ? argv[3] : argv[2], FMODE_Both, codec);
586 }
587 
588 
589 /**
590  * sc_base_slot() - get the handle of an opened database
591  * @filename: the filename of the wanted database.
592  * Database in native Scid format do not use extension ("example").
593  * Other databases require file extension ("example.pgn").
594  *
595  * Return:
596  * - the handle of the database corresponding to @filename.
597  * - 0 if not found.
598  */
599 UI_res_t sc_base_slot(UI_handle_t ti, int argc, const char** argv)
600 {
601  const char* usage = "Usage: sc_base slot filename";
602  if (argc != 3) return UI_Result(ti, ERROR_BadArg, usage);
603 
604  int res = DBasePool::find(argv[2]);
605  return UI_Result(ti, OK, res);
606 }
607 
608 
609 /**
610  * sc_base_sortcache() - create/release a sortcache
611  *
612  * A sortchace is used to speed up the other sc_base functions with the same "sortCrit"
613  */
614 UI_res_t sc_base_sortcache(scidBaseT* dbase, UI_handle_t ti, int argc, const char** argv)
615 {
616  const char* usage = "Usage: sc_base sortcache baseId <create|release> sortCrit";
617  if (argc != 5) return UI_Result(ti, ERROR_BadArg, usage);
618 
619  if (std::strcmp("create", argv[3]) == 0) {
620  if (dbase->createSortCache(argv[4]) == NULL)
621  return UI_Result(ti, ERROR);
622  } else {
623  dbase->releaseSortCache(argv[4]);
624  }
625  return UI_Result(ti, OK);
626 }
627 
628 
629 /**
630  * sc_base_stats() - return statistics about a database.
631  *
632  * The returned values are specific for every subcomand:
633  * dates -> {minimum year} {maximum year} {mean year}
634  * eco ? -> {number of games with for the ? eco} {white wins} {draws}
635  * {black wins} {n_games with empty result} {score in %}
636  * ? must be a valid ECO code or an abbreviation, for example:
637  * A returns the sum of all the A00,A00a...A99z4
638  * A1 returns the sum of all the A10,A10a,A10a1...A19z4
639  * A10 returns the sum of all the A10,A10a,A10a1...A10z4
640  * An empty string returns the sum of all valid ECO codes
641  * flag ? -> {number of games with the ? flag set}
642  * ? must be a valid flag char (see IndexEntry::CharToFlag())
643  * flags -> {n_games with D flag set} {n_games with W flag set} {n_games with B flag set}
644  * ratings -> {minimum elo} {maximum elo {mean elo}
645  * results -> {number of games won by white} {number of draws} {number of
646  * games won by black} {number of games with no result}
647  */
648 UI_res_t sc_base_stats(const scidBaseT* dbase, UI_handle_t ti, int argc, const char ** argv)
649 {
650  const char* usage = "Usage: sc_base stats baseId <dates|eco ?|flag ?|flags|ratings|results>";
651  if (argc < 4) return UI_Result(ti, ERROR_BadArg, usage);
652 
653  const char* subcmd = argv[3];
654  const scidBaseT::Stats& stats = dbase->getStats();
655  UI_List res(6);
656 
657  enum { OPT_DATE, OPT_ECO, OPT_FLAG, OPT_FLAGS, OPT_RATINGS, OPT_RESULTS };
658  const char * options[] = { "dates", "eco", "flag", "flags", "ratings", "results", NULL };
659  switch (strExactMatch(subcmd, options)) {
660  case OPT_DATE:
661  res.push_back(date_GetYear(stats.minDate));
662  res.push_back(date_GetYear(stats.maxDate));
663  res.push_back(stats.nYears == 0 ? 0 : size_t(stats.sumYears / stats.nYears));
664  break;
665  case OPT_ECO: {
666  const scidBaseT::Stats::Eco* eco = (argc != 5) ? 0 : stats.getEcoStats(argv[4]);
667  if (eco == 0) return UI_Result(ti, ERROR_BadArg, usage);
668  res.push_back(eco->count);
669  res.push_back(eco->results[RESULT_White]);
670  res.push_back(eco->results[RESULT_Draw]);
671  res.push_back(eco->results[RESULT_Black]);
672  res.push_back(eco->results[RESULT_None]);
673  ASSERT(eco->count >= eco->results[RESULT_None]);
674  uint count = eco->count - eco->results[RESULT_None];
675  uint score = eco->results[RESULT_White] * 2;
676  score += eco->results[RESULT_Draw];
677  score *= 500;
678  res.push_back(count == 0 ? 0.0 : score / count / 10.0);
679  break; }
680  case OPT_FLAG: {
681  uint flag = (argc != 5) ? 0 : IndexEntry::CharToFlag(*(argv[4]));
682  if (flag == 0) return UI_Result(ti, ERROR_BadArg, usage);
683  res.push_back(stats.flagCount[flag]);
684  break; }
685  case OPT_FLAGS:
686  res.push_back(stats.flagCount[IndexEntry::CharToFlag('D')]);
687  res.push_back(stats.flagCount[IndexEntry::CharToFlag('W')]);
688  res.push_back(stats.flagCount[IndexEntry::CharToFlag('B')]);
689  break;
690  case OPT_RATINGS:
691  res.push_back(stats.minRating);
692  res.push_back(stats.maxRating);
693  res.push_back(stats.nRatings == 0 ? 0 : size_t(stats.sumRatings / stats.nRatings));
694  break;
695  case OPT_RESULTS:
696  res.push_back(stats.nResults[RESULT_White]);
697  res.push_back(stats.nResults[RESULT_Draw]);
698  res.push_back(stats.nResults[RESULT_Black]);
699  res.push_back(stats.nResults[RESULT_None]);
700  break;
701  default:
702  return UI_Result(ti, ERROR_BadArg, usage);
703  }
704 
705  return UI_Result(ti, OK, res);
706 }
707 
708 
709 /**
710  * sc_base_switch() - change the current database and the current game
711  *
712  * DEPRECATED
713  * Unfortunately Scid used to have only one database, one game, one filter, etc...
714  * This function changes the current database and consequently the current game
715  * (sc_game functions works on the current game)
716  *
717  * Return: the current database ID after the switch
718  */
719 UI_res_t sc_base_switch(scidBaseT* dbase, UI_handle_t ti)
720 {
721  int res = DBasePool::switchCurrent(dbase);
722  return UI_Result(ti, OK, res);
723 }
724 
725 
726 /**
727  * sc_base_tournaments() - return a list of tournaments
728  *
729  * Games with the same [Event], [Site] and [EventDate] tags are considered
730  * a tournament (also games with empty [EventDate] tag are included).
731  * The list returned can be restricted based on the average elo of the
732  * participants, the number of games, the number of players and the name
733  * of a participant.
734  * Ranges can be specified with one or two numbers separated by spaces (min max).
735  * The returned list can be sorted according to the following criteria:
736  * - "Date" : date of the first games in the tournament
737  * - "Players" : number of participants to the tournament
738  * - "Games" : number of games
739  * - "Elo" : average elo of the participants
740  * - "Site" : site name
741  * - "Event" : event name
742  *
743  * Return:
744  * On success, return a list of tournaments.
745  * For each tournament the following info are provided:
746  * date of the first games, site name, event name, number of players,
747  * number of games, average elo of the participants, lowest game number,
748  * winner name, winner elo, winner score, 2nd place name, 2nd elo, 2nd score.
749  */
750 UI_res_t sc_base_tournaments(const scidBaseT* dbase, UI_handle_t ti, int argc, const char ** argv)
751 {
752  const char* usage = "Usage: sc_base tournaments baseId filterName n_maxResults [-avgelo range] [-n_games range] [-n_players range] [-sort criteria] ";
753  if (argc < 5) return UI_Result(ti, ERROR_BadArg, usage);
754 
755  const HFilter filter = dbase->getFilter(argv[3]);
756  if (filter == 0) return UI_Result(ti, ERROR_BadArg, usage);
757 
758  SearchTournaments search(dbase, filter);
759 
760  const char* sortCriteria = 0;
761  long nResults = strGetUnsigned(argv[4]);
762 
763  static const char* options[] = {
764  "-avgelo", "-n_games", "-n_players", "-player", "-sort", NULL
765  };
766  enum { AVGELO, N_GAMES, N_PLAYERS, PLAYER, SORT };
767 
768  for (int i = 5; (i + 1) < argc; i += 2) {
769  int index = strUniqueMatch(argv[i], options);
770  const char* value = argv[i + 1];
771  if (*value == 0) continue;
772  switch (index) {
773  case AVGELO:
774  search.filterByAvgElo(StrRange(value));
775  break;
776  case N_GAMES:
777  search.filterByNGames(StrRange(value));
778  break;
779  case N_PLAYERS:
780  search.filterByNPlayers(StrRange(value));
781  break;
782  case PLAYER:
783  search.filterByPlayer(value);
784  break;
785  case SORT:
786  sortCriteria = value;
787  break;
788  default:
789  return UI_Result(ti, ERROR_BadArg, usage);
790  }
791  }
792 
793  if (sortCriteria != 0) {
794  if (!search.sort(sortCriteria, nResults))
795  return UI_Result(ti, ERROR_BadArg, usage);
796  }
797 
798  SearchTournaments::Iter it = search.begin();
799  SearchTournaments::Iter it_end = search.end();
800  if (std::distance(it, it_end) > nResults) {
801  it_end = it + nResults;
802  }
803 
804  char buf_date[16];
805  const NameBase* nb = dbase->getNameBase();
806  UI_List res(std::distance(it, it_end));
807  UI_List tourney(14);
808  for (; it != it_end; it++) {
809  tourney.clear();
810  date_DecodeToString(it->getStartDate(), buf_date);
811  strTrimDate(buf_date);
812  tourney.push_back(buf_date);
813  tourney.push_back(nb->GetName(NAME_SITE, it->getSiteId()));
814  tourney.push_back(nb->GetName(NAME_EVENT, it->getEventId()));
815  tourney.push_back(it->nPlayers());
816  tourney.push_back(it->nGames());
817  tourney.push_back(it->getAvgElo());
818  tourney.push_back(it->getStartGameNum() + 1);
819  const char* name1st = "";
820  eloT elo1st = 0;
821  double score1st = 0.0;
822  const char* name2nd = "";
823  eloT elo2nd = 0;
824  double score2nd = 0.0;
825  if (it->nPlayers() > 0) {
826  const Tourney::Player& p = it->getPlayer(0);
827  name1st = nb->GetName(NAME_PLAYER, p.nameId);
828  elo1st = p.elo;
829  score1st = p.score / 2.0;
830  }
831  if (it->nPlayers() > 1) {
832  const Tourney::Player& p = it->getPlayer(1);
833  name2nd = nb->GetName(NAME_PLAYER, p.nameId);
834  elo2nd = p.elo;
835  score2nd = p.score / 2.0;
836  }
837  tourney.push_back(name1st);
838  tourney.push_back(elo1st);
839  tourney.push_back(score1st);
840  tourney.push_back(name2nd);
841  tourney.push_back(elo2nd);
842  tourney.push_back(score2nd);
843 
844  res.push_back(tourney);
845  }
846 
847  return UI_Result(ti, OK, res);
848 }
849 
850 /**
851  * sc_base_player_elo() - return a list of elo values of a player
852  * Return:
853  * On success, return a list of years (the month is added in the fractional
854  * part: 2018.00 ==> gen 2018, 2018.75 ==> oct 2018, etc..) and elos.
855  */
856 UI_res_t sc_base_player_elo(const scidBaseT& dbase, UI_handle_t ti, int argc,
857  const char** argv) {
858  const char* usage = "Usage: sc_base player_elo baseId filterName playerName";
859  if (argc != 5)
860  return UI_Result(ti, ERROR_BadArg, usage);
861 
862  const HFilter filter = dbase.getFilter(argv[3]);
863  if (filter == nullptr)
864  return UI_Result(ti, ERROR_BadArg, usage);
865 
866  idNumberT id = 0;
867  if (dbase.getNameBase()->FindExactName(NAME_PLAYER, argv[4], &id) != OK)
868  return UI_Result(ti, OK);
869 
870  std::map<unsigned, eloT> eloByMonth;
871  auto getPlayerElo = [](auto idx_entry, auto player_id) -> eloT {
872  ASSERT(idx_entry);
873  if (idx_entry->GetWhite() == player_id)
874  return idx_entry->GetWhiteElo();
875  if (idx_entry->GetBlack() == player_id)
876  return idx_entry->GetBlackElo();
877  return 0;
878  };
879  for (auto gnum : filter) {
880  const IndexEntry* ie = dbase.getIndexEntry(gnum);
881  if (auto elo = getPlayerElo(ie, id)) {
882  auto date = ie->GetDate();
883  auto year = date_GetYear(date);
884  auto month = date_GetMonth(date);
885  if (month > 0) {
886  month--;
887  }
888  if (month > 11) {
889  month = 0;
890  }
891  eloByMonth[year * 12 + month] = elo;
892  }
893  }
894 
895  UI_List res(eloByMonth.size() * 2);
896  for (auto& e : eloByMonth) {
897  res.push_back(e.first / 12.0); // year
898  res.push_back(e.second); // elo
899  }
900  return UI_Result(ti, OK, res);
901 }
902 
903 } // End of anonymous namespace
904 
905 //TODO: move this function here from tkscid.cpp
906 UI_res_t sc_base_inUse (UI_extra_t, UI_handle_t, int argc, const char ** argv);
907 UI_res_t sc_base_export (UI_extra_t, UI_handle_t, int argc, const char ** argv);
908 UI_res_t sc_base_piecetrack (UI_extra_t, UI_handle_t, int argc, const char ** argv);
909 UI_res_t sc_base_tag (UI_extra_t, UI_handle_t, int argc, const char ** argv);
910 uint sc_base_duplicates (scidBaseT* dbase, UI_handle_t, int argc, const char ** argv);
911 
912 
913 UI_res_t sc_base (UI_extra_t cd, UI_handle_t ti, int argc, const char ** argv)
914 {
915  static const char * options [] = {
916  "close", "compact", "copygames",
917  "create", "current", "duplicates",
918  "export", "extra", "filename", "gameflag",
919  "gamelocation", "gameslist", "getGame", "import",
920  "inUse", "isReadOnly", "list", "numGames", "open",
921  "piecetrack", "player_elo", "slot", "sortcache", "stats",
922  "switch", "tag", "tournaments", "type",
923  NULL
924  };
925  enum {
926  BASE_CLOSE, BASE_COMPACT, BASE_COPYGAMES,
927  BASE_CREATE, BASE_CURRENT, BASE_DUPLICATES,
928  BASE_EXPORT, BASE_EXTRA, BASE_FILENAME, BASE_GAMEFLAG,
929  BASE_GAMELOCATION, BASE_GAMESLIST, BASE_GETGAME, BASE_IMPORT,
930  BASE_INUSE, BASE_ISREADONLY, BASE_LIST, BASE_NUMGAMES, BASE_OPEN,
931  BASE_PTRACK, BASE_PLAYER_ELO, BASE_SLOT, BASE_SORTCACHE, BASE_STATS,
932  BASE_SWITCH, BASE_TAG, BASE_TOURNAMENTS, BASE_TYPE
933  };
934 
935  if (argc <= 1) return UI_Result(ti, ERROR_BadArg, "Usage: sc_base <cmd>");
936 
937  int index = strUniqueMatch (argv[1], options);
938  switch (index) {
939  case BASE_CREATE:
940  return sc_base_create(ti, argc, argv);
941 
942  case BASE_CURRENT:
943  return sc_base_switch(0, ti);
944 
945  case BASE_EXPORT:
946  return sc_base_export (cd, ti, argc, argv);
947 
948  case BASE_INUSE:
949  return sc_base_inUse (cd, ti, argc, argv);
950 
951  case BASE_LIST:
952  return sc_base_list(ti, argc, argv);
953 
954  case BASE_OPEN:
955  return sc_base_open(ti, argc, argv);
956 
957  case BASE_PTRACK:
958  return sc_base_piecetrack (cd, ti, argc, argv);
959 
960  case BASE_SLOT:
961  return sc_base_slot (ti, argc, argv);
962 
963  case BASE_TAG:
964  return sc_base_tag (cd, ti, argc, argv);
965  }
966 
967  //New multi-base functions
968  if (argc < 3) return UI_Result(ti, ERROR_BadArg, "Usage: sc_base <cmd> baseId [args]");
969  scidBaseT* dbase = DBasePool::getBase(strGetUnsigned(argv[2]));
970  if (dbase == 0) return UI_Result(ti, ERROR_FileNotOpen);
971 
972  switch (index) {
973  case BASE_CLOSE:
974  return sc_base_close(dbase, ti, argc, argv);
975 
976  case BASE_COMPACT:
977  return sc_base_compact(dbase, ti, argc, argv);
978 
979  case BASE_COPYGAMES:
980  return sc_base_copygames(dbase, ti, argc, argv);
981 
982  case BASE_DUPLICATES:
983  if (dbase->isReadOnly()) return UI_Result(ti, ERROR_FileReadOnly);
984  return UI_Result(ti, OK, sc_base_duplicates (dbase, ti, argc, argv));
985 
986  case BASE_EXTRA:
987  return sc_base_extra(dbase, ti, argc, argv);
988 
989  case BASE_FILENAME:
990  return sc_base_filename(dbase, ti, argc, argv);
991 
992  case BASE_GAMEFLAG:
993  return sc_base_gameflag(dbase, ti, argc, argv);
994 
995  case BASE_GAMELOCATION:
996  return sc_base_gamelocation(dbase, ti, argc, argv);
997 
998  case BASE_GAMESLIST:
999  return sc_base_gameslist(dbase, ti, argc, argv);
1000 
1001  case BASE_GETGAME:
1002  return sc_base_getGame(dbase, ti, argc, argv);
1003 
1004  case BASE_IMPORT:
1005  return sc_base_import (dbase, ti, argc, argv);
1006 
1007  case BASE_ISREADONLY:
1008  return UI_Result(ti, OK, dbase->isReadOnly());
1009 
1010  case BASE_NUMGAMES:
1011  return sc_base_numGames (dbase, ti, argc, argv);
1012 
1013  case BASE_PLAYER_ELO:
1014  return sc_base_player_elo(*dbase, ti, argc, argv);
1015 
1016  case BASE_SORTCACHE:
1017  return sc_base_sortcache(dbase, ti, argc, argv);
1018 
1019  case BASE_STATS:
1020  return sc_base_stats(dbase, ti, argc, argv);
1021 
1022  case BASE_SWITCH:
1023  return sc_base_switch (dbase, ti);
1024 
1025  case BASE_TOURNAMENTS:
1026  return sc_base_tournaments (dbase, ti, argc, argv);
1027  }
1028 
1029  std::string res = "sc_base\nInvalid minor command: ";
1030  res.append(argv[1]);
1031  return UI_Result(ti, ERROR_BadArg, res);
1032 }
const IndexEntry * getIndexEntry(gamenumT g) const
Definition: scidbase.h:131
uint date_GetYear(dateT date)
Definition: date.h:52
const errorT ERROR_Full
Definition: error.h:49
errorT setExtraInfo(const char *tagname, const char *new_value)
Store an extra information about the database (type, description, etc..)
Definition: scidbase.h:108
bool GetStartFlag() const
Definition: indexentry.h:252
dateT GetDate() const
Definition: indexentry.h:107
int strExactMatch(const char *keyStr, const char **strTable)
Definition: misc.h:258
const char * GetBlackName(const NameBase *nb) const
Definition: indexentry.h:228
errorT FindExactName(nameT nt, const char *str, idNumberT *idPtr) const
Finds an exact full, case-sensitive name.
Definition: namebase.h:190
std::string matsig_makeString(matSigT m)
Definition: matsig.cpp:27
const errorT OK
Definition: error.h:23
int switchCurrent(scidBaseT *dbase=0)
switchCurrent() - DEPRECATED.
Definition: dbasepool.cpp:84
FastGame getGame(const IndexEntry *ie) const
Definition: scidbase.h:141
std::vector< Tourney >::const_iterator Iter
const errorT ERROR_FileInUse
Definition: error.h:37
void restoreLocation(const GameSavedPos &savedPos)
Definition: game.h:282
resultT GetResult() const
Definition: indexentry.h:109
SortCache * createSortCache(const char *criteria)
Increment the reference count of a SortCache object matching criteria.
Definition: scidbase.cpp:699
const Stats & getStats() const
Statistics.
Definition: scidbase.cpp:336
class SearchTournamens - Search tournaments in a database
#define ASSERT(f)
Definition: common.h:59
const char * GetWhiteName(const NameBase *nb) const
Definition: indexentry.h:225
const errorT ERROR_BadArg
Definition: error.h:28
const char * GetEventName(const NameBase *nb) const
Definition: indexentry.h:231
UI_res_t sc_base_piecetrack(UI_extra_t, UI_handle_t, int argc, const char **argv)
const resultT RESULT_Black
Definition: common.h:191
Definition: misc.h:63
errorT Close()
Definition: scidbase.cpp:114
int strUniqueMatch(const char *keyStr, const char **strTable)
Definition: misc.h:255
class StrRange - parse a string interpreting its content as 1 or 2 integers separated by whitespace...
Definition: misc.h:36
byte get(gamenumT gnum) const
Definition: hfilter.h:260
uint64_t sumYears
Definition: scidbase.h:45
void collectPositions(Game &game, TCont &dest)
Iterate all the positions of a game and store the corresponding GamePos objects into a container...
Definition: game.h:550
const gamenumT INVALID_GAMEID
Definition: scidbase.h:37
static uint CharToFlag(char ch)
Definition: indexentry.h:467
scidBaseT * getBase(int baseHandle)
getBase() - get a database from the pool.
Definition: dbasepool.cpp:59
matSigT GetFinalMatSig() const
Definition: indexentry.h:114
char ecoStringT[6]
Definition: common.h:166
bool isReadOnly() const
Definition: scidbase.h:98
int UI_res_t
Definition: ui_tcltk.h:30
uint16_t GetNumHalfMoves() const
Definition: indexentry.h:113
const char * GetName(nameT nt, idNumberT id) const
Retrieve a name.
Definition: namebase.h:162
uint results[NUM_RESULT_TYPES]
Definition: scidbase.h:56
void date_DecodeToString(dateT date, char *str)
Definition: date.h:87
const resultT RESULT_Draw
Definition: common.h:192
uint32_t idNumberT
Definition: common.h:152
errorT importGame(const scidBaseT *srcBase, uint gNum)
Definition: scidbase.cpp:194
eloT GetWhiteElo() const
Definition: indexentry.h:99
int find(const char *filename)
find() - search for a database.
Definition: dbasepool.cpp:51
static uint32_t CharToFlagMask(char flag)
Definition: indexentry.h:497
const char RESULT_STR[4][4]
Definition: common.h:196
uint GetNagCount() const
Definition: indexentry.h:112
This class stores the database&#39;s names (players, events, sites and rounds).
Definition: namebase.h:33
uint64_t sumRatings
Definition: scidbase.h:48
UI_res_t sc_base(UI_extra_t cd, UI_handle_t ti, int argc, const char **argv)
Definition: sc_base.cpp:913
uint GetFlagStr(char *dest, const char *flags) const
Definition: indexentry.h:548
errorT invertFlag(uint flag, uint gNum)
Definition: scidbase.h:433
const std::string & getFileName() const
Definition: scidbase.h:97
Game * game
Definition: scidbase.h:356
sort?type?
Definition: analysis.tcl:320
size_t sortedPosition(const char *criteria, const HFilter &filter, gamenumT gameId)
Get the sorted position of a game.
Definition: scidbase.cpp:716
const resultT RESULT_White
Definition: common.h:190
uint32_t uint
Definition: common.h:91
uint sc_base_duplicates(scidBaseT *dbase, UI_handle_t, int argc, const char **argv)
Definition: tkscid.cpp:826
bool GetDeleteFlag() const
Definition: indexentry.h:258
const Eco * getEcoStats(const char *ecoStr) const
Definition: scidbase.cpp:420
std::string getMoveSAN(int ply_to_skip, int count)
Definition: fastgame.h:439
eloT GetBlackElo() const
Definition: indexentry.h:102
bool strAlphaContains(const char *longStr, const char *keyStr)
Definition: misc.h:401
statsfmt
Definition: optable.tcl:704
ushort eloT
Definition: common.h:164
uint GetCommentCount() const
Definition: indexentry.h:111
errorT getCompactStat(unsigned long long *n_deleted, unsigned long long *n_unused, unsigned long long *n_sparse, unsigned long long *n_badNameId)
Definition: scidbase.cpp:491
byte GetRating(const NameBase *nb) const
Definition: indexentry.h:431
void releaseSortCache(const char *criteria)
Decrement the reference count of the SortCache object matching criteria.
Definition: scidbase.cpp:685
Definition: board.tcl:17
UI_res_t sc_base_tag(UI_extra_t, UI_handle_t, int argc, const char **argv)
ecoT GetEcoCode() const
Definition: indexentry.h:116
void eco_ToExtendedString(ecoT ecoCode, char *ecoStr)
Definition: misc.h:113
uint32_t strGetUnsigned(const char *str)
Definition: misc.h:195
unsigned short errorT
Definition: error.h:20
uint nResults[NUM_RESULT_TYPES]
Definition: scidbase.h:46
Definition: errors.tcl:17
scidBaseT * getFreeSlot()
getFreeSlot() - search for a free database slot.
Definition: dbasepool.cpp:69
uint flagCount[IndexEntry::IDX_NUM_FLAGS]
Definition: scidbase.h:41
errorT importGames(const scidBaseT *srcBase, const HFilter &filter, const Progress &progress)
Definition: scidbase.cpp:205
const errorT ERROR_FileReadOnly
Definition: error.h:41
UI_res_t UI_Result(UI_handle_t ti, errorT res)
UI_Result() - pass the result of an operation from c++ to UI.
Definition: ui.h:140
GameSavedPos currentLocation() const
Definition: game.h:279
std::vector< int > getHandles()
getHandles() - get the handles of opened databases.
Definition: dbasepool.cpp:76
errorT compact(const Progress &progress)
Definition: scidbase.cpp:527
size_t size() const
Definition: hfilter.h:240
void push_back(Tcl_Obj *value)
Definition: ui_tcltk.h:154
bool report(size_t done, size_t total) const
Definition: misc.h:75
Definition: game.h:167
int gameNumber
Definition: scidbase.h:357
const errorT ERROR_FileNotOpen
Definition: error.h:36
gamenumT numGames() const
Definition: scidbase.h:99
An heterogeneous container used to pass a list of values from c++ to UI.
Definition: ui.h:162
Tcl_Interp * UI_handle_t
Definition: ui_tcltk.h:32
const char * GetSiteName(const NameBase *nb) const
Definition: indexentry.h:234
HFilter getFilter(const std::string &filterId) const
Definition: scidbase.h:200
uint GetYear() const
Definition: indexentry.h:217
cmd
Definition: fics.tcl:439
Progress UI_CreateProgress(UI_handle_t ti)
UI_CreateProgress() - create a Progress object.
Definition: ui.h:122
const IndexEntry * getIndexEntry_bounds(gamenumT g) const
Definition: scidbase.h:134
errorT Open(ICodecDatabase::Codec dbtype, fileModeT mode, const char *filename=0, const Progress &progress=Progress())
Definition: scidbase.cpp:84
bool strGetBoolean(const char *str)
Definition: misc.cpp:500
uint gamenumT
Definition: common.h:163
void game_printNag(byte nag, char *str, bool asSymbol, gameFormatT format)
Definition: game.cpp:98
UI_res_t sc_base_inUse(UI_extra_t, UI_handle_t, int argc, const char **argv)
fileModeT
Definition: common.h:136
const errorT ERROR_FileMode
Definition: error.h:38
const resultT RESULT_None
Definition: common.h:189
const NameBase * getNameBase() const
Definition: scidbase.h:138
const errorT ERROR_NameDataLoss
Definition: error.h:54
uint64_t nYears
Definition: scidbase.h:44
std::vector< std::pair< const char *, std::string > > getExtraInfo() const
Returns a vector of tag pairs containing extra information about the database (type, description, autoload, etc..)
Definition: scidbase.h:103
const char * GetRoundName(const NameBase *nb) const
Definition: indexentry.h:237
uint date_GetMonth(dateT date)
Definition: date.h:61
const errorT ERROR_FileOpen
Definition: error.h:31
void strTrimDate(char *str)
Definition: misc.cpp:356
UI_res_t sc_base_export(UI_extra_t, UI_handle_t, int argc, const char **argv)
Definition: indexentry.h:54
size_t listGames(const char *criteria, size_t start, size_t count, const HFilter &filter, gamenumT *destCont)
Retrieve a list of ordered game indexes sorted by criteria.
Definition: scidbase.cpp:707
bool getFlag(uint flag, uint gNum) const
Definition: scidbase.h:180
uint GetVariationCount() const
Definition: indexentry.h:110
dateT GetEventDate() const
Definition: indexentry.h:108
ClientData UI_extra_t
Definition: ui_tcltk.h:31
errorT setFlag(bool value, uint flag, uint gNum)
Definition: scidbase.h:447