Compare commits
2 Commits
44b651292f
...
be93c2bdad
Author | SHA1 | Date | |
---|---|---|---|
be93c2bdad | |||
6797d4a9ae |
@ -100,13 +100,13 @@ json DistroqueryAPI::getRepositoryPackages(string repository, int per_page, int
|
|||||||
"%' OR description LIKE '%" + query + "%'";
|
"%' OR description LIKE '%" + query + "%'";
|
||||||
|
|
||||||
sql = "SELECT u.*,COUNT(*) OVER() AS total_count FROM ("
|
sql = "SELECT u.*,COUNT(*) OVER() AS total_count FROM ("
|
||||||
"SELECT name,arch,version,release,summary,buildtime,0 AS sort FROM sources " + query_append;
|
"SELECT name,arch,version,release,summary,buildtime,'src' AS reparch, 0 AS sort FROM sources " + query_append;
|
||||||
|
|
||||||
int archorder = 1;
|
int archorder = 1;
|
||||||
for (auto arch: ct->arch) {
|
for (auto arch: ct->arch) {
|
||||||
if (arch == NULL) break;
|
if (arch == NULL) break;
|
||||||
sql += " UNION SELECT name,arch,version,release,summary,buildtime," + to_string(archorder) +
|
sql += " UNION SELECT name,arch,version,release,summary,buildtime,'" + string(arch) + "' AS reparch," +
|
||||||
" AS sort FROM '" + repository + "_" + arch + "'.packages " + query_append;
|
to_string(archorder) + " AS sort FROM '" + repository + "_" + arch + "'.packages " + query_append;
|
||||||
archorder++;
|
archorder++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ json DistroqueryAPI::getRepositoryPackages(string repository, int per_page, int
|
|||||||
}
|
}
|
||||||
json package;
|
json package;
|
||||||
package["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "name")));
|
package["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "name")));
|
||||||
package["arch"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "arch")));
|
package["arch"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "reparch")));
|
||||||
package["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "version")));
|
package["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "version")));
|
||||||
package["release"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "release")));
|
package["release"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "release")));
|
||||||
package["summary"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "summary")));
|
package["summary"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "summary")));
|
||||||
@ -145,6 +145,7 @@ json DistroqueryAPI::getRepositoryPackages(string repository, int per_page, int
|
|||||||
j["error"] = "error preparing query '" + sql + "': " + sqlite3_errmsg(db);
|
j["error"] = "error preparing query '" + sql + "': " + sqlite3_errmsg(db);
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
sqlite3_close(db);
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,6 +194,7 @@ json DistroqueryAPI::getPackageSourceDetailsById(configTag* ct, long id) {
|
|||||||
j["error"] = "no results from query '" + sql + "'";
|
j["error"] = "no results from query '" + sql + "'";
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
sqlite3_close(db);
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,27 +229,18 @@ json DistroqueryAPI::getBuiltPackagesFromSourceID(configTag* ct, long id) {
|
|||||||
j["error"] = "error preparing query '" + sql + "': " + sqlite3_errmsg(db);
|
j["error"] = "error preparing query '" + sql + "': " + sqlite3_errmsg(db);
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
sqlite3_close(db);
|
||||||
}
|
}
|
||||||
j["archs"] = archs;
|
j["archs"] = archs;
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
json DistroqueryAPI::getProvidersForRequirement(string repository, string requirement, string flags, string version, string onlyarch) {
|
json DistroqueryAPI::getProvidersForRequirementFromDb(sqlite3 *db , configTag* ct, string requirement,
|
||||||
|
string flags, string version, string onlyarch) {
|
||||||
|
|
||||||
json j;
|
json j;
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
struct configTag* ct = findRepositoryByTag(repository.c_str());
|
|
||||||
if (ct == NULL) {
|
|
||||||
j["error"] = "repository with tag '" + repository + "' does not exist";
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto db = openRepositoryDatabase(ct);
|
|
||||||
if (!db) {
|
|
||||||
j["error"] = "error opening sources database for repository " + string(ct->tag);
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
|
|
||||||
string sql = "SELECT u.* FROM (";
|
string sql = "SELECT u.* FROM (";
|
||||||
|
|
||||||
int intflags = rpmSenseStringToFlags(flags);
|
int intflags = rpmSenseStringToFlags(flags);
|
||||||
@ -256,7 +249,6 @@ json DistroqueryAPI::getProvidersForRequirement(string repository, string requir
|
|||||||
for (auto arch: ct->arch) {
|
for (auto arch: ct->arch) {
|
||||||
if (arch == NULL) break;
|
if (arch == NULL) break;
|
||||||
if (onlyarch != "" && onlyarch != arch) continue;
|
if (onlyarch != "" && onlyarch != arch) continue;
|
||||||
attachCtDatabases(ct, db, arch);
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (ct->repository[i]) {
|
while (ct->repository[i]) {
|
||||||
if (a + i > 0) sql += " UNION ";
|
if (a + i > 0) sql += " UNION ";
|
||||||
@ -288,7 +280,7 @@ json DistroqueryAPI::getProvidersForRequirement(string repository, string requir
|
|||||||
string provideVersion = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "provideversion")));
|
string provideVersion = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "provideversion")));
|
||||||
provider["version"] = provideVersion;
|
provider["version"] = provideVersion;
|
||||||
|
|
||||||
if (flags != "") {
|
if (flags != "" && provideVersion != "") {
|
||||||
// Check that provide version matches with required flags and version
|
// Check that provide version matches with required flags and version
|
||||||
if (checkVersionWithFlags(version.c_str(), intflags, provideVersion.c_str()) != 1)
|
if (checkVersionWithFlags(version.c_str(), intflags, provideVersion.c_str()) != 1)
|
||||||
continue;
|
continue;
|
||||||
@ -308,6 +300,33 @@ json DistroqueryAPI::getProvidersForRequirement(string repository, string requir
|
|||||||
j["providers"]["archs"] = archs;
|
j["providers"]["archs"] = archs;
|
||||||
else
|
else
|
||||||
j["providers"] = archs[onlyarch];
|
j["providers"] = archs[onlyarch];
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
json DistroqueryAPI::getProvidersForRequirement(string repository, string requirement, string flags, string version, string onlyarch) {
|
||||||
|
json j;
|
||||||
|
|
||||||
|
struct configTag* ct = findRepositoryByTag(repository.c_str());
|
||||||
|
if (ct == NULL) {
|
||||||
|
j["error"] = "repository with tag '" + repository + "' does not exist";
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto db = openRepositoryDatabase(ct);
|
||||||
|
if (!db) {
|
||||||
|
j["error"] = "error opening sources database for repository " + string(ct->tag);
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onlyarch != "") {
|
||||||
|
attachCtDatabases(ct, db, onlyarch);
|
||||||
|
} else {
|
||||||
|
attachCtDatabasesAllArchs(ct, db);
|
||||||
|
}
|
||||||
|
|
||||||
|
j = getProvidersForRequirementFromDb(db, ct, requirement, flags, version, onlyarch);
|
||||||
|
sqlite3_close(db);
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,6 +403,7 @@ json DistroqueryAPI::getPackageSourceDetails(string repository, string package)
|
|||||||
j["error"] = "error preparing query '" + sql + "'";
|
j["error"] = "error preparing query '" + sql + "'";
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
sqlite3_close(db);
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,8 +518,46 @@ json DistroqueryAPI::getPackageDetails(string repository, string package, string
|
|||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sqlite3_close(db);
|
||||||
return j;
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
json DistroqueryAPI::getRepositoryProblems(string repository) {
|
||||||
|
json j;
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
|
struct configTag* ct = findRepositoryByTag(repository.c_str());
|
||||||
|
if (ct == NULL) {
|
||||||
|
j["error"] = "repository with tag '" + repository + "' does not exist";
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto db = openRepositoryDatabase(ct);
|
||||||
|
if (!db) {
|
||||||
|
j["error"] = "error opening sources database for repository " + string(ct->tag);
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
attachCtDatabases(ct, db);
|
||||||
|
|
||||||
|
j["problems"] = json::array();
|
||||||
|
|
||||||
|
// Check build requires
|
||||||
|
string sql = "SELECT * FROM warnings ORDER BY repository,arch,name";
|
||||||
|
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt, NULL) == SQLITE_OK) {
|
||||||
|
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||||
|
json problem = {};
|
||||||
|
problem["repository"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "repository")));
|
||||||
|
problem["arch"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "arch")));
|
||||||
|
problem["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "name")));
|
||||||
|
problem["text"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "text")));
|
||||||
|
j["problems"].push_back(problem);
|
||||||
|
}
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_close(db);
|
||||||
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DistroqueryAPI::getApiResponse(string path_info) {
|
void DistroqueryAPI::getApiResponse(string path_info) {
|
||||||
@ -578,7 +636,7 @@ void DistroqueryAPI::getApiResponse(string path_info) {
|
|||||||
}
|
}
|
||||||
cout << details.dump();
|
cout << details.dump();
|
||||||
} else if (path_split[0] == "providers") {
|
} else if (path_split[0] == "providers") {
|
||||||
// API service: package
|
// API service: providers
|
||||||
if (path_split.size() != 3 && path_split.size() != 5)
|
if (path_split.size() != 3 && path_split.size() != 5)
|
||||||
sendErrorResponse("expected 3 or 5 arguments for " + path_split[0]);
|
sendErrorResponse("expected 3 or 5 arguments for " + path_split[0]);
|
||||||
json providers;
|
json providers;
|
||||||
@ -589,6 +647,12 @@ void DistroqueryAPI::getApiResponse(string path_info) {
|
|||||||
providers = getProvidersForRequirement(path_split[1], urlDecode(path_split[2]),
|
providers = getProvidersForRequirement(path_split[1], urlDecode(path_split[2]),
|
||||||
urlDecode(path_split[3]), urlDecode(path_split[4]));
|
urlDecode(path_split[3]), urlDecode(path_split[4]));
|
||||||
cout << providers.dump();
|
cout << providers.dump();
|
||||||
|
} else if (path_split[0] == "problems") {
|
||||||
|
// API service: check problems
|
||||||
|
if (path_split.size() != 2)
|
||||||
|
sendErrorResponse("expected 2 arguments for " + path_split[0]);
|
||||||
|
json problems = getRepositoryProblems(path_split[1]);
|
||||||
|
cout << problems.dump();
|
||||||
} else {
|
} else {
|
||||||
sendErrorResponse("invalid request for service '" + path_split[0]);
|
sendErrorResponse("invalid request for service '" + path_split[0]);
|
||||||
}
|
}
|
||||||
|
@ -43,11 +43,14 @@ class DistroqueryAPI {
|
|||||||
void sendErrorResponse(string message);
|
void sendErrorResponse(string message);
|
||||||
json getRepositoryPackages(string repository, int per_page, int page, string query);
|
json getRepositoryPackages(string repository, int per_page, int page, string query);
|
||||||
json getPackageSourceDetailsById(configTag* ct, long id);
|
json getPackageSourceDetailsById(configTag* ct, long id);
|
||||||
|
json getProvidersForRequirementFromDb(sqlite3 *db , configTag* ct, string requirement,
|
||||||
|
string flags, string version, string onlyarch);
|
||||||
json getProvidersForRequirement(string repository, string requirement, string flags,
|
json getProvidersForRequirement(string repository, string requirement, string flags,
|
||||||
string version, string onlyarch="");
|
string version, string onlyarch="");
|
||||||
json getPackageSourceDetails(string repository, string package);
|
json getPackageSourceDetails(string repository, string package);
|
||||||
json getBuiltPackagesFromSourceID(configTag* ct, long id);
|
json getBuiltPackagesFromSourceID(configTag* ct, long id);
|
||||||
json getPackageDetails(string repository, string package, string arch);
|
json getPackageDetails(string repository, string package, string arch);
|
||||||
|
json getRepositoryProblems(string repository);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __DISTROQUERY_API_H
|
#endif // __DISTROQUERY_API_H
|
||||||
|
@ -315,6 +315,56 @@ long generateSQLite_add_changelog(sqlite3 *db, struct changeLog* firstchangelog,
|
|||||||
return lastchangelogid;
|
return lastchangelogid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long generateSQLite_add_warnings(sqlite3 *db, struct warningList* firstWarning, char* repository) {
|
||||||
|
|
||||||
|
struct warningList* warning = firstWarning;
|
||||||
|
long lastwarningid = 0;
|
||||||
|
|
||||||
|
while (warning) {
|
||||||
|
snprintf(sqlite3_query, PATH_MAX, "INSERT INTO warnings VALUES(NULL,?,?,?,?);");
|
||||||
|
|
||||||
|
if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
|
||||||
|
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_bind_text(stmt, 1, repository, -1, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_text(stmt, 2, warning->arch, -1, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_text(stmt, 3, warning->name, -1, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_text(stmt, 4, warning->text, -1, SQLITE_STATIC);
|
||||||
|
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||||
|
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
warning->id = sqlite3_last_insert_rowid(db);
|
||||||
|
lastwarningid = warning->id;
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
warning = warning->next;
|
||||||
|
}
|
||||||
|
return lastwarningid;
|
||||||
|
}
|
||||||
|
|
||||||
|
long generateSQLite_add_needrebuild(sqlite3 *db, struct rebuildList* firstRebuild, long id_source) {
|
||||||
|
|
||||||
|
struct rebuildList* rebuild = firstRebuild;
|
||||||
|
long lastrebuildid = 0;
|
||||||
|
|
||||||
|
while (rebuild) {
|
||||||
|
snprintf(sqlite3_query, PATH_MAX, "INSERT INTO needrebuild VALUES(NULL,%ld,%ld,%ld);",
|
||||||
|
id_source,
|
||||||
|
rebuild->sourceheader->id,
|
||||||
|
rebuild->provider->id);
|
||||||
|
|
||||||
|
if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
|
||||||
|
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
||||||
|
}
|
||||||
|
rebuild->id = sqlite3_last_insert_rowid(db);
|
||||||
|
lastrebuildid = rebuild->id;
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
rebuild = rebuild->next;
|
||||||
|
}
|
||||||
|
return lastrebuildid;
|
||||||
|
}
|
||||||
|
|
||||||
#define SQLITE_TABLE_packages "id INTEGER PRIMARY KEY, "\
|
#define SQLITE_TABLE_packages "id INTEGER PRIMARY KEY, "\
|
||||||
"name STRING, arch STRING, altrepository INTEGER, epoch INTEGER, version STRING, release STRING, summary STRING, "\
|
"name STRING, arch STRING, altrepository INTEGER, epoch INTEGER, version STRING, release STRING, summary STRING, "\
|
||||||
"groupdescr STRING, description STRING, buildtime INTEGER, size INTEGER, id_source INTEGER"
|
"groupdescr STRING, description STRING, buildtime INTEGER, size INTEGER, id_source INTEGER"
|
||||||
@ -425,7 +475,7 @@ generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
|||||||
}
|
}
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
} else if (strstr(currpackage->require[i]->name,"rpmlib(") != currpackage->require[i]->name) {
|
} else if (strstr(currpackage->require[i]->name,"rpmlib(") != currpackage->require[i]->name) {
|
||||||
fprintf(stderr, "WARNING: package %s require %s not in provided list\n", currpackage->name, currpackage->require[i]->name);
|
fprintf(stderr, "WARNING: package %s requires %s not in provided list\n", currpackage->name, currpackage->require[i]->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -440,20 +490,23 @@ generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
|
|||||||
#define SQLITE_TABLE_sources "id INTEGER PRIMARY KEY, "\
|
#define SQLITE_TABLE_sources "id INTEGER PRIMARY KEY, "\
|
||||||
"name STRING, altrepository INTEGER, epoch INTEGER, version STRING, release STRING, summary STRING, id_packager INTEGER, "\
|
"name STRING, altrepository INTEGER, epoch INTEGER, version STRING, release STRING, summary STRING, id_packager INTEGER, "\
|
||||||
"groupdescr STRING, description STRING, url STRING, license STRING, arch STRING, buildarchs STRING, " \
|
"groupdescr STRING, description STRING, url STRING, license STRING, arch STRING, buildarchs STRING, " \
|
||||||
"excludearch STRING, buildtime INTEGER, size INTEGER, id_changelog INTEGER"
|
"excludearch STRING, buildtime INTEGER, size INTEGER"
|
||||||
//#define SQLITE_TABLE_sources_files_rel "id INTEGER PRIMARY KEY, id_source INTEGER, id_files INTEGER"
|
//#define SQLITE_TABLE_sources_files_rel "id INTEGER PRIMARY KEY, id_source INTEGER, id_files INTEGER"
|
||||||
//#define SQLITE_TABLE_sources_provided_rel "id INTEGER PRIMARY KEY, id_source INTEGER, id_provided INTEGER"
|
//#define SQLITE_TABLE_sources_provided_rel "id INTEGER PRIMARY KEY, id_source INTEGER, id_provided INTEGER"
|
||||||
#define SQLITE_TABLE_changelog "id INTEGER PRIMARY KEY, "\
|
#define SQLITE_TABLE_changelog "id INTEGER PRIMARY KEY, "\
|
||||||
"id_source INTEGER, time INTEGER, id_packager INTEGER, release STRING, text STRING"
|
"id_source INTEGER, time INTEGER, id_packager INTEGER, release STRING, text STRING"
|
||||||
#define SQLITE_TABLE_buildrequires "id INTEGER PRIMARY KEY, "\
|
#define SQLITE_TABLE_buildrequires "id INTEGER PRIMARY KEY, "\
|
||||||
"id_source INTEGER, buildrequirename STRING, buildrequireflags INTEGER, buildrequireversion STRING"
|
"id_source INTEGER, buildrequirename STRING, buildrequireflags INTEGER, buildrequireversion STRING"
|
||||||
|
#define SQLITE_TABLE_warnings "id INTEGER PRIMARY KEY, "\
|
||||||
|
"repository STRING, arch STRING, name STRING, text STRING"
|
||||||
|
#define SQLITE_TABLE_needrebuild "id INTEGER PRIMARY KEY, "\
|
||||||
|
"id_source INTEGER, id_source_rebuild INTEGER, id_provider INTEGER"
|
||||||
|
|
||||||
int
|
int
|
||||||
generateSQLite_sources(struct configTag *ct, sqlite3 *db) {
|
generateSQLite_sources(struct configTag *ct, sqlite3 *db) {
|
||||||
|
|
||||||
struct headerSourceList* currsource;
|
struct headerSourceList* currsource;
|
||||||
int i;
|
int i;
|
||||||
long nextchangelogid = 1;
|
|
||||||
|
|
||||||
SQLite_init_table(db, "sources", SQLITE_TABLE_sources);
|
SQLite_init_table(db, "sources", SQLITE_TABLE_sources);
|
||||||
SQLite_init_table(db, "sources_source", SQLITE_TABLE_sources_source);
|
SQLite_init_table(db, "sources_source", SQLITE_TABLE_sources_source);
|
||||||
@ -462,19 +515,20 @@ generateSQLite_sources(struct configTag *ct, sqlite3 *db) {
|
|||||||
// SQLite_init_table(db, "sources_provided_rel", SQLITE_TABLE_sources_provided_rel);
|
// SQLite_init_table(db, "sources_provided_rel", SQLITE_TABLE_sources_provided_rel);
|
||||||
SQLite_init_table(db, "changelog", SQLITE_TABLE_changelog);
|
SQLite_init_table(db, "changelog", SQLITE_TABLE_changelog);
|
||||||
SQLite_init_table(db, "buildrequires", SQLITE_TABLE_buildrequires);
|
SQLite_init_table(db, "buildrequires", SQLITE_TABLE_buildrequires);
|
||||||
|
SQLite_init_table(db, "warnings", SQLITE_TABLE_warnings);
|
||||||
|
SQLite_init_table(db, "needrebuild", SQLITE_TABLE_needrebuild);
|
||||||
SQLite_begin_transaction(db);
|
SQLite_begin_transaction(db);
|
||||||
|
|
||||||
currsource = ct->headersourcelist;
|
currsource = ct->headersourcelist;
|
||||||
while (currsource != NULL) {
|
while (currsource != NULL) {
|
||||||
if (currsource->altrepository == ct->repository_level) {
|
if (currsource->altrepository == ct->repository_level) {
|
||||||
snprintf(sqlite3_query, PATH_MAX, "INSERT INTO sources VALUES(%ld,?,%d,%ld,?,?,?,%ld,?,?,?,?,?,?,?,%ld,%ld,%ld);",
|
snprintf(sqlite3_query, PATH_MAX, "INSERT INTO sources VALUES(%ld,?,%d,%ld,?,?,?,%ld,?,?,?,?,?,?,?,%ld,%ld);",
|
||||||
currsource->id,
|
currsource->id,
|
||||||
currsource->altrepository,
|
currsource->altrepository,
|
||||||
currsource->epoch,
|
currsource->epoch,
|
||||||
currsource->packager->id,
|
currsource->packager->id,
|
||||||
currsource->buildtime,
|
currsource->buildtime,
|
||||||
currsource->size,
|
currsource->size);
|
||||||
(currsource->changelog?nextchangelogid:0));
|
|
||||||
if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
|
if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
|
||||||
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
|
||||||
}
|
}
|
||||||
@ -573,8 +627,16 @@ generateSQLite_sources(struct configTag *ct, sqlite3 *db) {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (currsource->changelog) {
|
if (currsource->changelog) {
|
||||||
nextchangelogid = generateSQLite_add_changelog(db, currsource->changelog, currsource->id) + 1;
|
generateSQLite_add_changelog(db, currsource->changelog, currsource->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currsource->firstrebuild) {
|
||||||
|
generateSQLite_add_needrebuild(db, currsource->firstrebuild, currsource->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (currsource->firstwarning) {
|
||||||
|
generateSQLite_add_warnings(db, currsource->firstwarning, ct->repository[currsource->altrepository]->tag);
|
||||||
}
|
}
|
||||||
currsource = currsource->next;
|
currsource = currsource->next;
|
||||||
}
|
}
|
||||||
@ -635,6 +697,7 @@ generateSQLite(struct configTag *ct)
|
|||||||
}
|
}
|
||||||
|
|
||||||
generateSQLite_sources(ct, db);
|
generateSQLite_sources(ct, db);
|
||||||
|
|
||||||
generateSQLite_packagers(db);
|
generateSQLite_packagers(db);
|
||||||
|
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
|
@ -252,7 +252,7 @@ handleObsoletedPackages(struct configTag *ct, int archidx)
|
|||||||
prov->provider[i]->name,
|
prov->provider[i]->name,
|
||||||
prov->provider[i]->arch,
|
prov->provider[i]->arch,
|
||||||
ct->repository[prov->provider[i]->altrepository]->tag);
|
ct->repository[prov->provider[i]->altrepository]->tag);
|
||||||
addWarning(prov->provider[k]->sourceheader, buf);
|
addWarning(prov->provider[k]->sourceheader, currheader, buf);
|
||||||
logmsg(LOG_WARNING,"%s", buf);
|
logmsg(LOG_WARNING,"%s", buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -269,7 +269,7 @@ handleObsoletedPackages(struct configTag *ct, int archidx)
|
|||||||
prov->provider[k]->name,
|
prov->provider[k]->name,
|
||||||
prov->provider[k]->arch,
|
prov->provider[k]->arch,
|
||||||
ct->repository[prov->provider[k]->altrepository]->tag);
|
ct->repository[prov->provider[k]->altrepository]->tag);
|
||||||
addWarning(prov->provider[i]->sourceheader, buf);
|
addWarning(prov->provider[i]->sourceheader, prov->provider[i], buf);
|
||||||
logmsg(LOG_WARNING,"%s", buf);
|
logmsg(LOG_WARNING,"%s", buf);
|
||||||
obs[k]=i;
|
obs[k]=i;
|
||||||
}
|
}
|
||||||
@ -350,7 +350,7 @@ handleObsoletedPackages(struct configTag *ct, int archidx)
|
|||||||
ct->repository[prov->provider[i]->altrepository]->tag);
|
ct->repository[prov->provider[i]->altrepository]->tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addWarning(currheader->sourceheader, buf);
|
addWarning(currheader->sourceheader, currheader, buf);
|
||||||
logmsg(LOG_WARNING,"%s", buf);
|
logmsg(LOG_WARNING,"%s", buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -399,7 +399,7 @@ resolveFirstLevelDependencies(struct configTag *ct, int archidx)
|
|||||||
currheader->version,
|
currheader->version,
|
||||||
currheader->next->version);
|
currheader->next->version);
|
||||||
fprintf(stderr,"Warning: %s\n",warning);
|
fprintf(stderr,"Warning: %s\n",warning);
|
||||||
addWarning(currheader->sourceheader,warning);
|
addWarning(currheader->sourceheader, currheader, warning);
|
||||||
}
|
}
|
||||||
} else if (currheader->altrepository >= currheader->sourceheader->updatingparent->altrepository) {
|
} else if (currheader->altrepository >= currheader->sourceheader->updatingparent->altrepository) {
|
||||||
currheader->next->obsoleted = 1;
|
currheader->next->obsoleted = 1;
|
||||||
@ -415,7 +415,7 @@ resolveFirstLevelDependencies(struct configTag *ct, int archidx)
|
|||||||
currheader->next->version,
|
currheader->next->version,
|
||||||
currheader->version);
|
currheader->version);
|
||||||
fprintf(stderr,"Warning: %s\n",warning);
|
fprintf(stderr,"Warning: %s\n",warning);
|
||||||
addWarning(currheader->sourceheader,warning);
|
addWarning(currheader->sourceheader, currheader->next, warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -472,7 +472,7 @@ resolveFirstLevelDependencies(struct configTag *ct, int archidx)
|
|||||||
ct->repository[currheader->altrepository]->tag,
|
ct->repository[currheader->altrepository]->tag,
|
||||||
currheader->require[i]->name);
|
currheader->require[i]->name);
|
||||||
fprintf(stderr,"Warning: %s\n",warning);
|
fprintf(stderr,"Warning: %s\n",warning);
|
||||||
addWarning(currheader->sourceheader,warning);
|
addWarning(currheader->sourceheader, currheader, warning);
|
||||||
}
|
}
|
||||||
} else { /* provided->numproviders > 0 */
|
} else { /* provided->numproviders > 0 */
|
||||||
/* warn about provides only provided by older packages */
|
/* warn about provides only provided by older packages */
|
||||||
@ -495,7 +495,7 @@ resolveFirstLevelDependencies(struct configTag *ct, int archidx)
|
|||||||
ct->repository[provided->provider[j]->altrepository]->tag);
|
ct->repository[provided->provider[j]->altrepository]->tag);
|
||||||
addRebuild(provided->provider[j]->sourceheader,
|
addRebuild(provided->provider[j]->sourceheader,
|
||||||
currheader->sourceheader, provided->provider[j]);
|
currheader->sourceheader, provided->provider[j]);
|
||||||
addWarning(provided->provider[j]->sourceheader,warning);
|
addWarning(provided->provider[j]->sourceheader, currheader, warning);
|
||||||
}
|
}
|
||||||
fprintf(stderr,"Warning: %s\n",warning);
|
fprintf(stderr,"Warning: %s\n",warning);
|
||||||
} else {
|
} else {
|
||||||
@ -519,9 +519,9 @@ resolveFirstLevelDependencies(struct configTag *ct, int archidx)
|
|||||||
ct->repository[provided->provider[j]->altrepository]->tag);
|
ct->repository[provided->provider[j]->altrepository]->tag);
|
||||||
}
|
}
|
||||||
fprintf(stderr,"Warning: %s\n",warning);
|
fprintf(stderr,"Warning: %s\n",warning);
|
||||||
addWarning(currheader->sourceheader,warning);
|
addWarning(currheader->sourceheader, currheader, warning);
|
||||||
for (j = 0; j < provided->numproviders; j++) {
|
for (j = 0; j < provided->numproviders; j++) {
|
||||||
addWarning(provided->provider[j]->sourceheader,warning);
|
addWarning(provided->provider[j]->sourceheader, currheader, warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -602,7 +602,7 @@ resolveFirstLevelDependencies(struct configTag *ct, int archidx)
|
|||||||
provided->name,
|
provided->name,
|
||||||
provided->version[foundprovider]);
|
provided->version[foundprovider]);
|
||||||
logmsg(LOG_WARNING,"%s", warning);
|
logmsg(LOG_WARNING,"%s", warning);
|
||||||
addWarning(currheader->sourceheader, warning);
|
addWarning(currheader->sourceheader, currheader, warning);
|
||||||
} else if (!found) {
|
} else if (!found) {
|
||||||
for (j = 0; j < provided->numproviders; j++) {
|
for (j = 0; j < provided->numproviders; j++) {
|
||||||
if (!checkVersionWithFlags(
|
if (!checkVersionWithFlags(
|
||||||
@ -631,12 +631,12 @@ resolveFirstLevelDependencies(struct configTag *ct, int archidx)
|
|||||||
for (k = 0; k < provided->numproviders; k++) {
|
for (k = 0; k < provided->numproviders; k++) {
|
||||||
if (provided->provider[k]->sourceheader &&
|
if (provided->provider[k]->sourceheader &&
|
||||||
(provided->provider[k]->altrepository == ct->repository_level)) {
|
(provided->provider[k]->altrepository == ct->repository_level)) {
|
||||||
addWarning(provided->provider[k]->sourceheader, warning);
|
addWarning(provided->provider[k]->sourceheader, currheader, warning);
|
||||||
addRebuild(provided->provider[k]->sourceheader,
|
addRebuild(provided->provider[k]->sourceheader,
|
||||||
currheader->sourceheader, provided->provider[k]);
|
currheader->sourceheader, provided->provider[k]);
|
||||||
}
|
}
|
||||||
if ((currheader->altrepository == ct->repository_level)) {
|
if ((currheader->altrepository == ct->repository_level)) {
|
||||||
addWarning(currheader->sourceheader, warning);
|
addWarning(currheader->sourceheader, currheader, warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -725,7 +725,7 @@ resolveFirstLevelSourceDependencies(struct configTag *ct, int archidx)
|
|||||||
currsourceheader->name,
|
currsourceheader->name,
|
||||||
ct->repository[currsourceheader->altrepository]->tag,
|
ct->repository[currsourceheader->altrepository]->tag,
|
||||||
warning);
|
warning);
|
||||||
addWarning(currsourceheader,warning);
|
addWarning(currsourceheader, NULL, warning);
|
||||||
}
|
}
|
||||||
//} else if (provided->numbuildproviders > 1) {
|
//} else if (provided->numbuildproviders > 1) {
|
||||||
/*printf("Multiple providers for %s in package %s\n",currsourceheader->require[i]->name,currsourceheader->name);*/
|
/*printf("Multiple providers for %s in package %s\n",currsourceheader->require[i]->name,currsourceheader->name);*/
|
||||||
@ -1187,7 +1187,7 @@ main(int argc, char *argv[])
|
|||||||
logmsg(LOG_WARNING, "%s: %s",
|
logmsg(LOG_WARNING, "%s: %s",
|
||||||
currheadersourcelist->name,
|
currheadersourcelist->name,
|
||||||
warning);
|
warning);
|
||||||
addWarning(currheadersourcelist, warning);
|
addWarning(currheadersourcelist, NULL, warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
warning[0] = '\0';
|
warning[0] = '\0';
|
||||||
@ -1204,7 +1204,7 @@ main(int argc, char *argv[])
|
|||||||
logmsg(LOG_WARNING, "%s: %s",
|
logmsg(LOG_WARNING, "%s: %s",
|
||||||
currheadersourcelist->name,
|
currheadersourcelist->name,
|
||||||
warning);
|
warning);
|
||||||
addWarning(currheadersourcelist, warning);
|
addWarning(currheadersourcelist, NULL, warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
warning[0] = '\0';
|
warning[0] = '\0';
|
||||||
@ -1232,7 +1232,7 @@ main(int argc, char *argv[])
|
|||||||
logmsg(LOG_WARNING, "%s: %s",
|
logmsg(LOG_WARNING, "%s: %s",
|
||||||
currheadersourcelist->name,
|
currheadersourcelist->name,
|
||||||
warning);
|
warning);
|
||||||
addWarning(currheadersourcelist, warning);
|
addWarning(currheadersourcelist, NULL, warning);
|
||||||
}
|
}
|
||||||
currheadersourcelist = currheadersourcelist->next;
|
currheadersourcelist = currheadersourcelist->next;
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,13 @@ void attachCtDatabases(struct configTag* ct, sqlite3 *db, string arch) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void attachCtDatabasesAllArchs(struct configTag* ct, sqlite3 *db) {
|
||||||
|
for (auto arch: ct->arch) {
|
||||||
|
if (arch == NULL) break;
|
||||||
|
attachCtDatabases(ct, db, arch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void attachRepositoryDatabases(struct configTag* ct, sqlite3 *db, string arch, int source) {
|
void attachRepositoryDatabases(struct configTag* ct, sqlite3 *db, string arch, int source) {
|
||||||
string dbname;
|
string dbname;
|
||||||
string sql;
|
string sql;
|
||||||
|
@ -52,13 +52,13 @@ int sourcerpmselector(const struct dirent *entry);
|
|||||||
|
|
||||||
const int bufsize = PATH_MAX;
|
const int bufsize = PATH_MAX;
|
||||||
|
|
||||||
struct warningList* addWarning(struct headerSourceList *pkg, char* text)
|
struct warningList* addWarning(struct headerSourceList *srcpkg, struct headerList *package, char* text)
|
||||||
{
|
{
|
||||||
struct warningList *currwarning, *prevwarning = NULL;
|
struct warningList *currwarning, *prevwarning = NULL;
|
||||||
|
|
||||||
if (!pkg) return NULL;
|
if (!srcpkg) return NULL;
|
||||||
|
|
||||||
currwarning = pkg->firstwarning;
|
currwarning = srcpkg->firstwarning;
|
||||||
|
|
||||||
while (currwarning) {
|
while (currwarning) {
|
||||||
if (!strcmp(currwarning->text,text)) return currwarning;
|
if (!strcmp(currwarning->text,text)) return currwarning;
|
||||||
@ -68,14 +68,22 @@ struct warningList* addWarning(struct headerSourceList *pkg, char* text)
|
|||||||
|
|
||||||
currwarning=malloc(sizeof(struct warningList));
|
currwarning=malloc(sizeof(struct warningList));
|
||||||
if (!currwarning) return NULL;
|
if (!currwarning) return NULL;
|
||||||
if (!pkg->firstwarning) pkg->firstwarning=currwarning;
|
if (!srcpkg->firstwarning) srcpkg->firstwarning=currwarning;
|
||||||
|
|
||||||
|
if (package) {
|
||||||
|
currwarning->arch = strdup(package->arch);
|
||||||
|
currwarning->name = strdup(package->name);
|
||||||
|
} else {
|
||||||
|
currwarning->arch = "src";
|
||||||
|
currwarning->name = strdup(srcpkg->name);
|
||||||
|
}
|
||||||
|
|
||||||
currwarning->text=strdup(text);
|
currwarning->text=strdup(text);
|
||||||
if (!currwarning->text) return NULL;
|
if (!currwarning->text) return NULL;
|
||||||
|
|
||||||
currwarning->next=NULL;
|
currwarning->next=NULL;
|
||||||
if (prevwarning) prevwarning->next=currwarning;
|
if (prevwarning) prevwarning->next=currwarning;
|
||||||
return pkg->firstwarning;
|
return srcpkg->firstwarning;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rebuildList* addRebuild(struct headerSourceList *pkg, struct headerSourceList* sourceheader, struct headerList* provider)
|
struct rebuildList* addRebuild(struct headerSourceList *pkg, struct headerSourceList* sourceheader, struct headerList* provider)
|
||||||
@ -998,7 +1006,7 @@ void addNewToSourceHeaderList(struct headerSourceList *newheadersourcelist,
|
|||||||
newheadersourcelist->name,
|
newheadersourcelist->name,
|
||||||
ct->repository[newheadersourcelist->altrepository]->tag,
|
ct->repository[newheadersourcelist->altrepository]->tag,
|
||||||
warning);
|
warning);
|
||||||
addWarning(newheadersourcelist, warning);
|
addWarning(newheadersourcelist, NULL, warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newheadersourcelist->next = currheadersourcelist->next;
|
newheadersourcelist->next = currheadersourcelist->next;
|
||||||
@ -1212,7 +1220,7 @@ int addToSourceHeaderList(struct configTag *ct, int mode, int altrepository) {
|
|||||||
logmsg(LOG_WARNING,
|
logmsg(LOG_WARNING,
|
||||||
"%s: missing changelog name and/or text",
|
"%s: missing changelog name and/or text",
|
||||||
newheadersourcelist->name);
|
newheadersourcelist->name);
|
||||||
addWarning(newheadersourcelist, warning);
|
addWarning(newheadersourcelist, NULL, warning);
|
||||||
}
|
}
|
||||||
changelog = changelog->next;
|
changelog = changelog->next;
|
||||||
}
|
}
|
||||||
@ -1314,7 +1322,7 @@ int addToSourceHeaderList(struct configTag *ct, int mode, int altrepository) {
|
|||||||
logmsg(LOG_WARNING,
|
logmsg(LOG_WARNING,
|
||||||
"%s: missing changelog name and/or text",
|
"%s: missing changelog name and/or text",
|
||||||
newheadersourcelist->name);
|
newheadersourcelist->name);
|
||||||
addWarning(newheadersourcelist, warning);
|
addWarning(newheadersourcelist, NULL, warning);
|
||||||
}
|
}
|
||||||
changelog = changelog->next;
|
changelog = changelog->next;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,10 @@ string rpmSenseFlagsToString(int flags);
|
|||||||
int rpmSenseStringToFlags(string flags);
|
int rpmSenseStringToFlags(string flags);
|
||||||
vector<string> split(string str, string token);
|
vector<string> split(string str, string token);
|
||||||
sqlite3* openRepositoryDatabase(struct configTag* ct, string arch = "", string append = "");
|
sqlite3* openRepositoryDatabase(struct configTag* ct, string arch = "", string append = "");
|
||||||
|
// Attach all upstream dbs for given ct repository and given arch (default = source)
|
||||||
void attachCtDatabases(struct configTag* ct, sqlite3 *db, string arch = "");
|
void attachCtDatabases(struct configTag* ct, sqlite3 *db, string arch = "");
|
||||||
|
// Attach all upstream dbs for given ct repository and all archs
|
||||||
|
void attachCtDatabasesAllArchs(struct configTag* ct, sqlite3 *db);
|
||||||
void attachRepositoryDatabases(struct configTag* ct, sqlite3 *db, string arch, int source);
|
void attachRepositoryDatabases(struct configTag* ct, sqlite3 *db, string arch, int source);
|
||||||
int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* name);
|
int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* name);
|
||||||
string urlDecode(string str);
|
string urlDecode(string str);
|
||||||
|
@ -52,13 +52,17 @@ struct fileGroupList {
|
|||||||
|
|
||||||
struct warningList {
|
struct warningList {
|
||||||
char* text;
|
char* text;
|
||||||
|
char *arch;
|
||||||
|
char *name;
|
||||||
struct warningList *next;
|
struct warningList *next;
|
||||||
|
long id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rebuildList {
|
struct rebuildList {
|
||||||
struct headerSourceList *sourceheader;
|
struct headerSourceList *sourceheader;
|
||||||
struct headerList *provider;
|
struct headerList *provider;
|
||||||
struct rebuildList *next;
|
struct rebuildList *next;
|
||||||
|
long id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Require {
|
struct Require {
|
||||||
@ -219,7 +223,7 @@ addToHeaderList(struct configTag *ct,
|
|||||||
const char* altscantag[ALT_REPS_MAX],
|
const char* altscantag[ALT_REPS_MAX],
|
||||||
int arch);
|
int arch);
|
||||||
|
|
||||||
struct warningList* addWarning(struct headerSourceList *pkg,char* text);
|
struct warningList* addWarning(struct headerSourceList *srcpkg, struct headerList *package, char* text);
|
||||||
|
|
||||||
struct rebuildList* addRebuild(struct headerSourceList *pkg, struct headerSourceList* sourceheader, struct headerList* provider);
|
struct rebuildList* addRebuild(struct headerSourceList *pkg, struct headerSourceList* sourceheader, struct headerList* provider);
|
||||||
|
|
||||||
|
@ -1074,7 +1074,7 @@ generateHTML_SRPMSFiles(struct configTag *configtag)
|
|||||||
{
|
{
|
||||||
snprintf(buffer, PATH_MAX, "has build requirement %s which is only provided in this repository",
|
snprintf(buffer, PATH_MAX, "has build requirement %s which is only provided in this repository",
|
||||||
currheadersourcelist->require[i]->resolved->name);
|
currheadersourcelist->require[i]->resolved->name);
|
||||||
addWarning(currheadersourcelist, buffer);
|
addWarning(currheadersourcelist, NULL, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1483,7 +1483,7 @@ generateHTMLFiles(struct configTag *ct, int arch)
|
|||||||
currheaderlist->require[i]->resolved->provider[0]->name,
|
currheaderlist->require[i]->resolved->provider[0]->name,
|
||||||
ct->arch[arch],
|
ct->arch[arch],
|
||||||
ct->repository[currheaderlist->require[i]->resolved->provider[0]->altrepository]->tag);
|
ct->repository[currheaderlist->require[i]->resolved->provider[0]->altrepository]->tag);
|
||||||
addWarning(currheaderlist->sourceheader, buffer);
|
addWarning(currheaderlist->sourceheader, currheaderlist, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user