FOSSology  4.7.1
Open Source License Compliance by Open Source Software
scancode_dbhandler.cc
1 /*
2  SPDX-FileCopyrightText: © 2021 Sarita Singh <saritasingh.0425@gmail.com>
3 
4  SPDX-License-Identifier: GPL-2.0-only
5 */
6 
7 #include "scancode_dbhandler.hpp"
8 
13  agent_fk(0),
14  pfile_fk(0),
15  content(""),
16  hash(""),
17  type(""),
18  copy_startbyte(0),
19  copy_endbyte(0)
20 {
21 };
22 
29 DatabaseEntry::DatabaseEntry(Match match, unsigned long agentId,
30  unsigned long pfileId) :
31  agent_fk(agentId), pfile_fk(pfileId), hash("")
32 {
33  content = match.getMatchName();
34  type = match.getType();
35  copy_startbyte = match.getStartPosition();
36  copy_endbyte = match.getStartPosition() + match.getLength();
37 };
38 
46 {
47  std::string result;
48  for (size_t i = 0; i < size; ++i)
49  {
50  if (i != 0)
51  result += ", ";
52  result += in[i].name;
53  result += " ";
54  result += in[i].type;
55  result += " ";
56  result += in[i].creationFlags;
57  }
58  return result;
59 }
60 
67 {
68 }
69 
77 {
78  DbManager spawnedDbMan(dbManager.spawn());
79  return ScancodeDatabaseHandler(spawnedDbMan);
80 }
81 
87 vector<unsigned long> ScancodeDatabaseHandler::queryFileIdsForUpload(int uploadId, bool ignoreFilesWithMimeType)
88 {
89  return queryFileIdsVectorForUpload(uploadId,ignoreFilesWithMimeType);
90 }
91 
98 bool ScancodeDatabaseHandler::insertNoResultInDatabase(int agentId, long pFileId ,long licenseId)
99 {
100  return dbManager.execPrepared(
101  fo_dbManager_PrepareStamement(dbManager.getStruct_dbManager(),
102  "scancodeInsertNoLicense",
103  "INSERT INTO license_file"
104  "(agent_fk, pfile_fk, rf_fk)"
105  " VALUES($1,$2,$3)",
106  int, long, long
107  ),
108  agentId, pFileId, licenseId);
109 }
110 
121  int agentId,
122  long pFileId,
123  long licenseId,
124  int percentMatch)
125 {
127  fo_dbManager_PrepareStamement(
129  "saveLicenseMatch",
130  "WITH "
131  "selectExisting AS ("
132  "SELECT fl_pk FROM ONLY license_file"
133  " WHERE (agent_fk = $1 AND pfile_fk = $2 AND rf_fk = $3)"
134  "),"
135  "insertNew AS ("
136  "INSERT INTO license_file"
137  "(agent_fk, pfile_fk, rf_fk, rf_match_pct)"
138  " SELECT $1, $2, $3, $4"
139  " WHERE NOT EXISTS(SELECT * FROM license_file WHERE (agent_fk = $1 AND pfile_fk = $2 AND rf_fk = $3))"
140  " RETURNING fl_pk"
141  ") "
142  "SELECT fl_pk FROM insertNew "
143  "UNION "
144  "SELECT fl_pk FROM selectExisting",
145  int, long, long, unsigned
146  ),
147  agentId,
148  pFileId,
149  licenseId,
150  percentMatch
151  );
152 
153  long licenseFilePK= -1;
154  if(!result.isFailed()){
155 
156  vector<unsigned long> res = result.getSimpleResults<unsigned long>(0,
158 
159  licenseFilePK = res.at(0);
160  }
161  return licenseFilePK;
162 }
163 
172  long licenseFileId,
173  unsigned start,
174  unsigned length)
175 {
176  return dbManager.execPrepared(
177  fo_dbManager_PrepareStamement(
179  "saveHighlightInfo",
180  "INSERT INTO highlight"
181  "(fl_fk, type, start, len)"
182  " SELECT $1, 'L', $2, $3 "
183  " WHERE NOT EXISTS(SELECT * FROM highlight WHERE (fl_fk = $1 AND start = $2 AND len = $3))",
184  long, unsigned, unsigned
185  ),
186  licenseFileId,
187  start,
188  length
189  );}
190 
197 void ScancodeDatabaseHandler::insertOrCacheLicenseIdForName(string const& rfShortName, string const& rfFullName, string const& rfTextUrl)
198 {
199  if (getCachedLicenseIdForName(rfShortName)==0)
200  {
201  unsigned long licenseId = selectOrInsertLicenseIdForName(rfShortName, rfFullName, rfTextUrl);
202 
203  if (licenseId > 0)
204  {
205  licenseRefCache.insert(std::make_pair(rfShortName, licenseId));
206  }
207  }
208 }
209 
215 unsigned long ScancodeDatabaseHandler::getCachedLicenseIdForName(string const& rfShortName) const
216 {
217  auto findIterator = licenseRefCache.find(rfShortName);
218  if (findIterator != licenseRefCache.end())
219  {
220  return findIterator->second;
221  }
222  else
223  {
224  return 0;
225  }
226 }
227 
234 bool hasEnding(string const &firstString, string const &ending)
235 {
236  if (firstString.length() >= ending.length())
237  {
238  return (0
239  == firstString.compare(firstString.length() - ending.length(),
240  ending.length(), ending));
241  }
242  else
243  {
244  return false;
245  }
246 }
247 
255 unsigned long ScancodeDatabaseHandler::selectOrInsertLicenseIdForName(string rfShortName, string rfFullname, string rfTexturl)
256 {
257  bool success = false;
258  unsigned long result = 0;
259 
260  icu::UnicodeString unicodeCleanShortname = fo::recodeToUnicode(rfShortName);
261 
262  // Clean shortname to get utf8 string
263  rfShortName = "";
264  unicodeCleanShortname.toUTF8String(rfShortName);
265 
266  fo_dbManager_PreparedStatement *searchWithOr = fo_dbManager_PrepareStamement(
268  "selectLicenseIdWithOrScancode",
269  " SELECT rf_pk FROM ONLY license_ref"
270  " WHERE LOWER(rf_shortname) = LOWER($1)"
271  " OR LOWER(rf_shortname) = LOWER($2);",
272  char*, char*);
273 
274  if (hasEnding(rfShortName, "+") || hasEnding(rfShortName, "-or-later"))
275  {
276  string tempShortName(rfShortName);
277  /* Convert shortname to lower-case to make it case-insensitive*/
278  std::transform(tempShortName.begin(), tempShortName.end(), tempShortName.begin(),
279  ::tolower);
280  string plus("+");
281  string orLater("-or-later");
282 
283  unsigned long int plusLast = tempShortName.rfind(plus);
284  unsigned long int orLaterLast = tempShortName.rfind(orLater);
285 
286  /* Remove last occurrence of + and -or-later (if found) */
287  if (plusLast != string::npos)
288  {
289  tempShortName.erase(plusLast, string::npos);
290  }
291  if (orLaterLast != string::npos)
292  {
293  tempShortName.erase(orLaterLast, string::npos);
294  }
295 
296  QueryResult queryResult = dbManager.execPrepared(searchWithOr,
297  (tempShortName + plus).c_str(), (tempShortName + orLater).c_str());
298 
299  success = queryResult && queryResult.getRowCount() > 0;
300  if (success)
301  {
302  result = queryResult.getSimpleResults<unsigned long>(0, fo::stringToUnsignedLong)[0];
303  }
304  }
305  else
306  {
307  string tempShortName(rfShortName);
308  /* Convert shortname to lower-case */
309  std::transform(tempShortName.begin(), tempShortName.end(), tempShortName.begin(),
310  ::tolower);
311  string only("-only");
312 
313  unsigned long int onlyLast = tempShortName.rfind(only);
314 
315  /* Remove last occurrence of -only (if found) */
316  if (onlyLast != string::npos)
317  {
318  tempShortName.erase(onlyLast, string::npos);
319  }
320 
321  QueryResult queryResult = dbManager.execPrepared(searchWithOr,
322  tempShortName.c_str(), (tempShortName + only).c_str());
323 
324  success = queryResult && queryResult.getRowCount() > 0;
325  if (success)
326  {
327  result = queryResult.getSimpleResults<unsigned long>(0, fo::stringToUnsignedLong)[0];
328  }
329  }
330 
331  if (result > 0)
332  {
333  return result;
334  }
335 
336 
337  unsigned count = 0;
338  while ((!success) && count++<3)
339  {
340  if (!dbManager.begin())
341  continue;
342 
343  dbManager.queryPrintf("LOCK TABLE license_ref");
344  QueryResult queryResult = dbManager.execPrepared(
345  fo_dbManager_PrepareStamement(
347  "selectOrInsertLicenseIdForName",
348  "WITH "
349  "selectExisting AS ("
350  "SELECT rf_pk FROM ONLY license_ref"
351  " WHERE rf_shortname = $1"
352  "),"
353  "insertNew AS ("
354  "INSERT INTO license_ref(rf_shortname, rf_text, rf_detector_type, rf_fullname, rf_url)"
355  " SELECT $1, $2, $3, $4, $5"
356  " WHERE NOT EXISTS(SELECT * FROM selectExisting)"
357  " RETURNING rf_pk"
358  ") "
359 
360  "SELECT rf_pk FROM insertNew "
361  "UNION "
362  "SELECT rf_pk FROM selectExisting",
363  char*, char*, int, char* , char*
364  ),
365  rfShortName.c_str(),
366  "License by Scancode.",
367  4,
368  rfFullname.c_str(),
369  rfTexturl.c_str()
370 
371  );
372 
373  success = queryResult && queryResult.getRowCount() > 0;
374 
375  if (success) {
376  success &= dbManager.commit();
377 
378  if (success) {
379  result = queryResult.getSimpleResults(0, fo::stringToUnsignedLong)[0];
380  }
381  } else {
383  }
384  }
385 
386  return result;
387 }
388 
395 {
396  std::string tableName = "scancode_author";
397 
398  if("scancode_statement" == entry.type ){
399  tableName = "scancode_copyright";
400  }
401 
402  return dbManager.execPrepared(
403  fo_dbManager_PrepareStamement(
405  ("insertInDatabaseFor " + tableName).c_str(),
406  ("INSERT INTO "+ tableName +
407  "(agent_fk, pfile_fk, content, hash, type, copy_startbyte, copy_endbyte)" +
408  " SELECT $1, $2, $3, md5($3), $4, $5, $6 "
409  " WHERE NOT EXISTS(SELECT * FROM " + tableName +
410  " WHERE (agent_fk= $1 AND pfile_fk = $2 AND hash = md5($3)))").c_str(),
411  long, long, char*, char*, int, int
412  ),
413  entry.agent_fk, entry.pfile_fk,
414  entry.content.c_str(),
415  entry.type.c_str(),
416  entry.copy_startbyte, entry.copy_endbyte
417  );
418 }
419 
425 {
427  bool result = createTableAgentFindings("scancode_copyright") &&
428  createTableAgentFindings("scancode_author") &&
429  createTableAgentEvents("scancode_copyright_event") &&
430  createTableAgentEvents("scancode_author_event");
431  dbManager.ignoreWarnings(false);
432  return result;
433 }
434 
440 #define CSEQUENCE_NAME "scancode_copyright_pk_seq"
441 #define CCOLUMN_NAME_PK "scancode_copyright_pk"
442  {CCOLUMN_NAME_PK, "bigint",
443  "PRIMARY KEY DEFAULT nextval('" CSEQUENCE_NAME "'::regclass)"},
444  {"agent_fk", "bigint", "NOT NULL"},
445  {"pfile_fk", "bigint", "NOT NULL"},
446  {"content", "text", ""},
447  {"hash", "text", ""},
448  {"type", "text", ""},
449  {"copy_startbyte", "integer", ""},
450  {"copy_endbyte", "integer", ""},
451  {"is_enabled", "boolean", "NOT NULL DEFAULT TRUE"},
452 };
453 
459 #define ASEQUENCE_NAME "scancode_author_pk_seq"
460 #define ACOLUMN_NAME_PK "scancode_author_pk"
461  {ACOLUMN_NAME_PK, "bigint",
462  "PRIMARY KEY DEFAULT nextval('" ASEQUENCE_NAME "'::regclass)"},
463  {"agent_fk", "bigint", "NOT NULL"},
464  {"pfile_fk", "bigint", "NOT NULL"},
465  {"content", "text", ""},
466  {"hash", "text", ""},
467  {"type", "text", ""},
468  {"copy_startbyte", "integer", ""},
469  {"copy_endbyte", "integer", ""},
470  {"is_enabled", "boolean", "NOT NULL DEFAULT TRUE"},
471 };
472 
479 {
480  if (tableName != "scancode_copyright" && tableName != "scancode_author") {
481  LOG_FATAL("createTableAgentFindings: unexpected table name '%s'", tableName.c_str());
482  return false;
483  }
484 
485  const char *tablename = "";
486  const char *sequencename = "";
487  if (tableName == "scancode_copyright") {
488  tablename = "scancode_copyright";
489  sequencename = "scancode_copyright_pk_seq";
490  } else if (tableName == "scancode_author") {
491  tablename = "scancode_author";
492  sequencename = "scancode_author_pk_seq";
493  }
494 
495  RETURN_IF_FALSE(dbManager.queryPrintf("CREATE SEQUENCE IF NOT EXISTS %s"
496  " START WITH 1"
497  " INCREMENT BY 1"
498  " NO MAXVALUE"
499  " NO MINVALUE"
500  " CACHE 1", sequencename));
501 
502  if (tableName == "scancode_copyright") {
504  RETURN_IF_FALSE(dbManager.queryPrintf("CREATE TABLE IF NOT EXISTS %s(%s)", tablename,
506  ));
507  } else if (tableName == "scancode_author") {
509  RETURN_IF_FALSE(dbManager.queryPrintf("CREATE TABLE IF NOT EXISTS %s(%s)", tablename,
511  ));
512  }
513 
514  RETURN_IF_FALSE(dbManager.queryPrintf(
515  "CREATE INDEX IF NOT EXISTS %s_agent_fk_index"
516  " ON %s"
517  " USING BTREE (agent_fk)",
518  tablename, tablename
519  ));
520 
521  RETURN_IF_FALSE(dbManager.queryPrintf(
522  "CREATE INDEX IF NOT EXISTS %s_hash_index"
523  " ON %s"
524  " USING BTREE (hash)",
525  tablename, tablename
526  ));
527 
528  RETURN_IF_FALSE(dbManager.queryPrintf(
529  "CREATE INDEX IF NOT EXISTS %s_pfile_fk_index"
530  " ON %s"
531  " USING BTREE (pfile_fk)",
532  tablename, tablename
533  ));
534 
535  {
537  "SELECT 1 FROM pg_constraint"
538  " WHERE conname = 'agent_fk' AND conrelid = '%s'::regclass",
539  tablename);
540  RETURN_IF_FALSE(fkCheck);
541  if (fkCheck.getRowCount() == 0) {
542  RETURN_IF_FALSE(dbManager.queryPrintf(
543  "DO $$ BEGIN"
544  " ALTER TABLE ONLY %s"
545  " ADD CONSTRAINT agent_fk"
546  " FOREIGN KEY (agent_fk)"
547  " REFERENCES agent(agent_pk) ON DELETE CASCADE;"
548  " EXCEPTION WHEN duplicate_object THEN NULL;"
549  " END $$",
550  tablename
551  ));
552  }
553  }
554 
555  {
557  "SELECT 1 FROM pg_constraint"
558  " WHERE conname = 'pfile_fk' AND conrelid = '%s'::regclass",
559  tablename);
560  RETURN_IF_FALSE(fkCheck);
561  if (fkCheck.getRowCount() == 0) {
562  RETURN_IF_FALSE(dbManager.queryPrintf(
563  "DO $$ BEGIN"
564  " ALTER TABLE ONLY %s"
565  " ADD CONSTRAINT pfile_fk"
566  " FOREIGN KEY (pfile_fk)"
567  " REFERENCES pfile(pfile_pk) ON DELETE CASCADE;"
568  " EXCEPTION WHEN duplicate_object THEN NULL;"
569  " END $$",
570  tablename
571  ));
572  }
573  }
574 
575  return true;
576 }
577 
583 #define CESEQUENCE_NAME "scancode_copyright_event_pk_seq"
584 #define CECOLUMN_NAME_PK "scancode_copyright_event_pk"
585  {CECOLUMN_NAME_PK, "bigint",
586  "PRIMARY KEY DEFAULT nextval('" CESEQUENCE_NAME "'::regclass)"},
587  {"upload_fk", "bigint", "NOT NULL"},
588  {"uploadtree_fk", "bigint", "NOT NULL"},
589  {"scancode_copyright_fk", "bigint", "NOT NULL"},
590  {"content", "text", ""},
591  {"hash", "text", ""},
592  {"is_enabled", "boolean", "NOT NULL DEFAULT FALSE"},
593  {"scope", "int4", "NOT NULL"},
594 };
595 
601 #define AESEQUENCE_NAME "scancode_author_event_pk_seq"
602 #define AECOLUMN_NAME_PK "scancode_author_event_pk"
603  {AECOLUMN_NAME_PK, "bigint",
604  "PRIMARY KEY DEFAULT nextval('" AESEQUENCE_NAME "'::regclass)"},
605  {"upload_fk", "bigint", "NOT NULL"},
606  {"uploadtree_fk", "bigint", "NOT NULL"},
607  {"scancode_author_fk", "bigint", "NOT NULL"},
608  {"content", "text", ""},
609  {"hash", "text", ""},
610  {"is_enabled", "boolean", "NOT NULL DEFAULT FALSE"},
611  {"scope", "int4", "NOT NULL"},
612 };
613 
620 {
621  if (tableName != "scancode_copyright_event" && tableName != "scancode_author_event") {
622  LOG_FATAL("createTableAgentEvents: unexpected table name '%s'", tableName.c_str());
623  return false;
624  }
625 
626  const char *tablename = "";
627  const char *etablename = "";
628  const char *esequencename = "";
629  if (tableName == "scancode_copyright_event") {
630  etablename = "scancode_copyright_event";
631  esequencename = "scancode_copyright_event_pk_seq";
632  tablename = "scancode_copyright";
633  } else if (tableName == "scancode_author_event") {
634  etablename = "scancode_author_event";
635  esequencename = "scancode_author_event_pk_seq";
636  tablename = "scancode_author";
637  }
638 
639  RETURN_IF_FALSE(dbManager.queryPrintf("CREATE SEQUENCE IF NOT EXISTS %s"
640  " START WITH 1"
641  " INCREMENT BY 1"
642  " NO MAXVALUE"
643  " NO MINVALUE"
644  " CACHE 1", esequencename));
645 
646  if (tableName == "scancode_copyright_event") {
648  RETURN_IF_FALSE(dbManager.queryPrintf("CREATE TABLE IF NOT EXISTS %s(%s)", etablename,
650  ));
651  } else if (tableName == "scancode_author_event") {
653  RETURN_IF_FALSE(dbManager.queryPrintf("CREATE TABLE IF NOT EXISTS %s(%s)", etablename,
655  ));
656  }
657 
658  RETURN_IF_FALSE(dbManager.queryPrintf(
659  "CREATE INDEX IF NOT EXISTS %s_upload_fk_index"
660  " ON %s"
661  " USING BTREE (upload_fk)",
662  etablename, etablename
663  ));
664 
665  RETURN_IF_FALSE(dbManager.queryPrintf(
666  "CREATE INDEX IF NOT EXISTS %s_uploadtree_fk_index"
667  " ON %s"
668  " USING BTREE (uploadtree_fk)",
669  etablename, etablename
670  ));
671 
672  RETURN_IF_FALSE(dbManager.queryPrintf(
673  "CREATE INDEX IF NOT EXISTS %s_scancode_fk_index"
674  " ON %s"
675  " USING BTREE (%s_fk)",
676  etablename, etablename, tablename
677  ));
678 
679  {
681  "SELECT 1 FROM pg_constraint"
682  " WHERE conname = 'upload_fk' AND conrelid = '%s'::regclass",
683  etablename);
684  RETURN_IF_FALSE(fkCheck);
685  if (fkCheck.getRowCount() == 0) {
686  RETURN_IF_FALSE(dbManager.queryPrintf(
687  "DO $$ BEGIN"
688  " ALTER TABLE ONLY %s"
689  " ADD CONSTRAINT upload_fk"
690  " FOREIGN KEY (upload_fk)"
691  " REFERENCES upload(upload_pk) ON DELETE CASCADE;"
692  " EXCEPTION WHEN duplicate_object THEN NULL;"
693  " END $$",
694  etablename
695  ));
696  }
697  }
698 
699  {
700  string contentFkName = string(tablename) + "_fk";
702  "SELECT 1 FROM pg_constraint"
703  " WHERE conname = '%s' AND conrelid = '%s'::regclass",
704  contentFkName.c_str(), etablename);
705  RETURN_IF_FALSE(fkCheck);
706  if (fkCheck.getRowCount() == 0) {
707  RETURN_IF_FALSE(dbManager.queryPrintf(
708  "DO $$ BEGIN"
709  " ALTER TABLE ONLY %s"
710  " ADD CONSTRAINT %s_fk"
711  " FOREIGN KEY (%s_fk)"
712  " REFERENCES %s(%s_pk) ON DELETE CASCADE;"
713  " EXCEPTION WHEN duplicate_object THEN NULL;"
714  " END $$",
715  etablename, tablename, tablename, tablename, tablename
716  ));
717  }
718  }
719 
720  {
721  QueryResult defaultCheck = dbManager.queryPrintf(
722  "SELECT 1 FROM pg_attrdef ad"
723  " JOIN pg_attribute a ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum"
724  " WHERE ad.adrelid = '%s'::regclass"
725  " AND a.attname = 'scope'"
726  " AND pg_get_expr(ad.adbin, ad.adrelid) = '1'",
727  etablename);
728  RETURN_IF_FALSE(defaultCheck);
729  if (defaultCheck.getRowCount() == 0) {
730  RETURN_IF_FALSE(dbManager.queryPrintf(
731  "ALTER TABLE %s ALTER COLUMN scope SET DEFAULT 1",
732  etablename
733  ));
734  }
735  }
736 
737  return true;
738 }
bool hasEnding(string const &firstString, string const &ending)
Maps agent data to database schema.
Definition: database.hpp:25
int copy_startbyte
Definition: database.hpp:44
std::string content
Definition: database.hpp:31
std::string type
Type of statement found.
Definition: database.hpp:43
int copy_endbyte
Definition: database.hpp:45
DatabaseEntry()
Default constructor for DatabaseEntry.
Definition: database.cc:26
bool saveHighlightInfo(long licenseFileId, unsigned start, unsigned length)
save highlight information in the highlight table
static const ColumnDef columns_copyright_event[]
Columns required to store copyright deactivated statement.
unsigned long selectOrInsertLicenseIdForName(std::string rfShortname, std::string rfFullname, std::string rfTexturl)
insert license if not present in license_ref table and return rf_pk
bool createTables() const
create tables to save copyright and author informations
unsigned long getCachedLicenseIdForName(std::string const &rfShortName) const
for given short name search license
static const ColumnDef columns_copyright[]
Columns required to store copyright information by scancode agent.
long saveLicenseMatch(int agentId, long pFileId, long licenseId, int percentMatch)
save license match with license_ref table in license_file table Insert license if already not present...
static const ColumnDef columns_author_event[]
Columns required to store author deactivated statement.
bool insertInDatabase(DatabaseEntry &entry) const
insert copyright/author in scancode_copyright/scancode_author table
void insertOrCacheLicenseIdForName(std::string const &rfShortName, std::string const &rfFullname, std::string const &rfTexturl)
calling function for selectOrInsertLicenseIdForName
bool insertNoResultInDatabase(int agentId, long pFileId, long licenseId)
Insert null value of license for uploads having no licenses.
std::string getColumnCreationString(const ColumnDef in[], size_t size) const
get string of parameters for a column for table creation
std::vector< unsigned long > queryFileIdsForUpload(int uploadId, bool ignoreFilesWithMimeType)
Function to get pfile ID for uploads.
ScancodeDatabaseHandler(fo::DbManager dbManager)
Default constructor for ScanCode Database Handler class.
bool createTableAgentFindings(string tablename) const
create table to store agent findings
static const ColumnDef columns_author[]
Columns required to store author information by scancode agent.
bool createTableAgentEvents(string tablename) const
create table to store agent events
ScancodeDatabaseHandler spawn() const
Instantiate a new object spawn for ScanCode Database handler Used to create new objects for threads.
Database handler for agents.
std::vector< unsigned long > queryFileIdsVectorForUpload(int uploadId, bool ignoreFilesWithMimeType) const
Get pfile ids for a given upload id.
DbManager dbManager
DbManager to use.
DB wrapper for agents.
QueryResult execPrepared(fo_dbManager_PreparedStatement *stmt,...) const
Execute a prepared statement with new parameters.
void ignoreWarnings(bool) const
QueryResult queryPrintf(const char *queryFormat,...) const
Execute a query in printf format.
fo_dbManager * getStruct_dbManager() const
DbManager spawn() const
Wrapper for DB result.
std::vector< T > getSimpleResults(int columnN, T(functionP)(const char *)) const
Get vector of a single column from query result.
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16
fo namespace holds the FOSSology library functions.
unsigned long stringToUnsignedLong(const char *string)
Definition: libfossUtils.cc:20
icu::UnicodeString recodeToUnicode(const std::string &input)
Definition: libfossUtils.cc:46
start($application)
start the application Assumes application is restartable via /etc/init.d/<script>....
Definition: pkgConfig.php:1214
Definition: match.h:20
Holds the column related data for table creation.
Store the results of a regex match.
Definition: scanners.hpp:28