FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
OjosDatabaseHandler.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2019, Siemens AG
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * version 2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16  */
22 #include "OjosDatabaseHandler.hpp"
23 
24 using namespace fo;
25 using namespace std;
26 
32  fo::AgentDatabaseHandler(dbManager)
33 {
34 }
35 
42 vector<unsigned long> OjosDatabaseHandler::queryFileIdsForUpload(int uploadId, bool ignoreFilesWithMimeType)
43 {
44  return queryFileIdsVectorForUpload(uploadId, ignoreFilesWithMimeType);
45 }
46 
54 {
55  DbManager spawnedDbMan(dbManager.spawn());
56  return OjosDatabaseHandler(spawnedDbMan);
57 }
58 
65  OjoDatabaseEntry &entry) const
66 {
67  QueryResult queryResult = dbManager.execPrepared(
68  fo_dbManager_PrepareStamement(dbManager.getStruct_dbManager(),
69  "ojoInsertLicense",
70  "INSERT INTO license_file"
71  "(rf_fk, agent_fk, pfile_fk)"
72  " VALUES($1,$2,$3) RETURNING fl_pk",
73  long, long, long),
74  entry.license_fk, entry.agent_fk, entry.pfile_fk);
75  vector<unsigned long> res = queryResult.getSimpleResults<unsigned long>(0,
77  if (res.size() > 0)
78  {
79  return res.at(0);
80  }
81  else
82  {
83  return -1;
84  }
85 }
86 
94  const unsigned long fl_fk) const
95 {
96  if (fl_fk < 1)
97  {
98  return false;
99  }
100  return dbManager.execPrepared(
101  fo_dbManager_PrepareStamement(dbManager.getStruct_dbManager(),
102  "ojoInsertHighlight",
103  "INSERT INTO highlight"
104  "(fl_fk, start, len, type)"
105  " VALUES($1,$2,$3,'L')",
106  long, long, long
107  ),
108  fl_fk, match.start,
109  match.len);
110 }
111 
118  OjoDatabaseEntry &entry) const
119 {
120  return dbManager.execPrepared(
121  fo_dbManager_PrepareStamement(dbManager.getStruct_dbManager(),
122  "ojoInsertNoLicense",
123  "INSERT INTO license_file"
124  "(agent_fk, pfile_fk)"
125  " VALUES($1,$2)",
126  long, long
127  ),
128  entry.agent_fk, entry.pfile_fk);
129 }
130 
137 bool hasEnding(string const &firstString, string const &ending)
138 {
139  if (firstString.length() >= ending.length())
140  {
141  return (0
142  == firstString.compare(firstString.length() - ending.length(),
143  ending.length(), ending));
144  }
145  else
146  {
147  return false;
148  }
149 }
150 
164  string rfShortName)
165 {
166  bool success = false;
167  unsigned long result = 0;
168 
169  icu::UnicodeString unicodeCleanShortname = fo::recodeToUnicode(rfShortName);
170 
171  // Clean shortname to get utf8 string
172  rfShortName = "";
173  unicodeCleanShortname.toUTF8String(rfShortName);
174 
175  fo_dbManager_PreparedStatement *searchWithOr = fo_dbManager_PrepareStamement(
177  "selectLicenseIdWithOrOJO",
178  "SELECT rf_pk FROM ONLY license_ref"
179  " WHERE LOWER(rf_shortname) = LOWER($1)"
180  " OR LOWER(rf_shortname) = LOWER($2)"
181  " ORDER BY rf_pk ASC;",
182  char*, char*);
183 
184  /* First check similar matches */
185  /* Check if the name ends with +, -or-later, -only */
186  if (hasEnding(rfShortName, "+") || hasEnding(rfShortName, "-or-later"))
187  {
188  string tempShortName(rfShortName);
189  /* Convert shortname to lower-case */
190  std::transform(tempShortName.begin(), tempShortName.end(), tempShortName.begin(),
191  ::tolower);
192  string plus("+");
193  string orLater("-or-later");
194 
195  unsigned long int plusLast = tempShortName.rfind(plus);
196  unsigned long int orLaterLast = tempShortName.rfind(orLater);
197 
198  /* Remove last occurrence of + and -or-later (if found) */
199  if (plusLast != string::npos)
200  {
201  tempShortName.erase(plusLast, string::npos);
202  }
203  if (orLaterLast != string::npos)
204  {
205  tempShortName.erase(orLaterLast, string::npos);
206  }
207 
208  QueryResult queryResult = dbManager.execPrepared(searchWithOr,
209  (tempShortName + plus).c_str(), (tempShortName + orLater).c_str());
210 
211  success = queryResult && queryResult.getRowCount() > 0;
212  if (success)
213  {
214  result = queryResult.getSimpleResults<unsigned long>(0, fo::stringToUnsignedLong)[0];
215  }
216  }
217  else
218  {
219  string tempShortName(rfShortName);
220  /* Convert shortname to lower-case */
221  std::transform(tempShortName.begin(), tempShortName.end(), tempShortName.begin(),
222  ::tolower);
223  string only("-only");
224 
225  unsigned long int onlyLast = tempShortName.rfind(only);
226 
227  /* Remove last occurrence of -only (if found) */
228  if (onlyLast != string::npos)
229  {
230  tempShortName.erase(onlyLast, string::npos);
231  }
232 
233  QueryResult queryResult = dbManager.execPrepared(searchWithOr,
234  tempShortName.c_str(), (tempShortName + only).c_str());
235 
236  success = queryResult && queryResult.getRowCount() > 0;
237  if (success)
238  {
239  result = queryResult.getSimpleResults<unsigned long>(0, fo::stringToUnsignedLong)[0];
240  }
241  }
242 
243  if (result > 0)
244  {
245  return result;
246  }
247 
248  unsigned count = 0;
249  while ((!success) && count++ < 3)
250  {
251  if (!dbManager.begin())
252  continue;
253 
254  dbManager.queryPrintf("LOCK TABLE license_ref");
255 
256  QueryResult queryResult =
258  fo_dbManager_PrepareStamement(dbManager.getStruct_dbManager(),
259  "selectOrInsertLicenseIdForNameOjo",
260  "WITH "
261  "selectExisting AS ("
262  "SELECT rf_pk FROM ONLY license_ref"
263  " WHERE LOWER(rf_shortname) = LOWER($1)"
264  "),"
265  "insertNew AS ("
266  "INSERT INTO license_ref(rf_shortname, rf_text, rf_detector_type)"
267  " SELECT $1, $2, $3"
268  " WHERE NOT EXISTS(SELECT * FROM selectExisting)"
269  " RETURNING rf_pk"
270  ") "
271 
272  "SELECT rf_pk FROM insertNew "
273  "UNION "
274  "SELECT rf_pk FROM selectExisting",
275  char*, char*, int
276  ),
277  rfShortName.c_str(), "License by OJO.", 3);
278 
279  success = queryResult && queryResult.getRowCount() > 0;
280 
281  if (success)
282  {
283  success &= dbManager.commit();
284 
285  if (success)
286  {
287  result = queryResult.getSimpleResults(0, fo::stringToUnsignedLong)[0];
288  }
289  }
290  else
291  {
293  }
294  }
295 
296  return result;
297 }
298 
309  string const &rfShortName)
310 {
311  unsigned long licenseId = getCachedLicenseIdForName(rfShortName);
312  if (licenseId == 0)
313  {
314  licenseId = selectOrInsertLicenseIdForName(rfShortName);
315  licenseRefCache.insert(std::make_pair(rfShortName, licenseId));
316  }
317  return licenseId;
318 }
319 
326  string const &rfShortName) const
327 {
328  std::unordered_map<string, long>::const_iterator findIterator =
329  licenseRefCache.find(rfShortName);
330  if (findIterator != licenseRefCache.end())
331  {
332  return findIterator->second;
333  }
334  else
335  {
336  return 0;
337  }
338 }
unsigned long getLicenseIdForName(std::string const &rfShortName)
Get the license id for a given short name.
std::vector< unsigned long > queryFileIdsVectorForUpload(int uploadId, bool ignoreFilesWithMimeType) const
Get pfile ids for a given upload id.
unsigned long saveLicenseToDatabase(OjoDatabaseEntry &entry) const
Save findings to the database if agent was called by scheduler.
DB wrapper for agents.
Store the results of a regex match.
Definition: scanners.hpp:39
QueryResult execPrepared(fo_dbManager_PreparedStatement *stmt,...) const
Execute a prepared statement with new parameters.
bool hasEnding(string const &firstString, string const &ending)
OjosDatabaseHandler(fo::DbManager dbManager)
fo_dbManager * getStruct_dbManager() const
unsigned long stringToUnsignedLong(const char *string)
Definition: libfossUtils.cc:31
Database handler for OJO.
unsigned long selectOrInsertLicenseIdForName(std::string rfShortname)
Database handler for agents.
bool saveHighlightToDatabase(const ojomatch &match, const unsigned long fl_fk) const
Wrapper for DB result.
bool rollback() const
OjosDatabaseHandler spawn() const
std::unordered_map< std::string, long > licenseRefCache
QueryResult queryPrintf(const char *queryFormat,...) const
Execute a query in printf format.
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:28
int getRowCount() const
fo namespace holds the FOSSology library functions.
unsigned long getCachedLicenseIdForName(std::string const &rfShortName) const
const unsigned long int agent_fk
bool insertNoResultInDatabase(OjoDatabaseEntry &entry) const
Save no result to the database.
icu::UnicodeString recodeToUnicode(const std::string &input)
Definition: libfossUtils.cc:43
std::vector< T > getSimpleResults(int columnN, T(functionP)(const char *)) const
Get vector of a single column from query result.
DbManager dbManager
DbManager to use.
const unsigned long int license_fk
DbManager spawn() const
long int len
Definition: ojomatch.hpp:39
long int start
Definition: ojomatch.hpp:39
const unsigned long int pfile_fk
std::vector< unsigned long > queryFileIdsForUpload(int uploadId, bool ignoreFilesWithMimeType)
Store the results of a regex match.
Definition: ojomatch.hpp:27