[aur-dev] [PATCH 1/6] Store conflicts, provides and replaces in the DB
Package conflicts, provides and replaces are now stored in the new PackageRelations table. The gendummydata script generates test entries for these relations. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- UPGRADING | 28 ++++++++++++++++++++++++++++ schema/aur-schema.sql | 26 ++++++++++++++++++++++++++ schema/gendummydata.py | 27 ++++++++++++++++----------- web/html/pkgsubmit.php | 18 ++++++++++++++++-- web/lib/pkgfuncs.inc.php | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 122 insertions(+), 13 deletions(-) diff --git a/UPGRADING b/UPGRADING index 0a801cc..f523140 100644 --- a/UPGRADING +++ b/UPGRADING @@ -171,6 +171,34 @@ ALTER TABLE PackageDepends ALTER TABLE PackageDepends MODIFY DepName VARCHAR(255) NOT NULL; ---- +15. Create a new table to store package relation types: + +---- +CREATE TABLE RelationTypes ( + ID TINYINT UNSIGNED NOT NULL AUTO_INCREMENT, + Name VARCHAR(32) NOT NULL DEFAULT '', + PRIMARY KEY (ID) +) ENGINE = InnoDB; +INSERT INTO RelationTypes VALUES (1, 'conflicts'); +INSERT INTO RelationTypes VALUES (2, 'provides'); +INSERT INTO RelationTypes VALUES (3, 'replaces'); +---- + +16. Create a new table to store package relations: + +---- +CREATE TABLE PackageRelations ( + PackageID INTEGER UNSIGNED NOT NULL, + RelTypeID TINYINT UNSIGNED NOT NULL, + RelName VARCHAR(255) NOT NULL, + RelCondition VARCHAR(20), + INDEX (PackageID), + INDEX (RelName), + FOREIGN KEY (PackageID) REFERENCES Packages(ID) ON DELETE CASCADE, + FOREIGN KEY (RelTypeID) REFERENCES RelationTypes(ID) ON DELETE NO ACTION +) ENGINE = InnoDB; +---- + From 2.2.0 to 2.3.0 ------------------- diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql index af03b69..c98ba77 100644 --- a/schema/aur-schema.sql +++ b/schema/aur-schema.sql @@ -160,6 +160,32 @@ CREATE TABLE PackageDepends ( ) ENGINE = InnoDB; +-- Define the package relation types +-- +CREATE TABLE RelationTypes ( + ID TINYINT UNSIGNED NOT NULL AUTO_INCREMENT, + Name VARCHAR(32) NOT NULL DEFAULT '', + PRIMARY KEY (ID) +) ENGINE = InnoDB; +INSERT INTO RelationTypes VALUES (1, 'conflicts'); +INSERT INTO RelationTypes VALUES (2, 'provides'); +INSERT INTO RelationTypes VALUES (3, 'replaces'); + + +-- Track which conflicts, provides and replaces a package has +-- +CREATE TABLE PackageRelations ( + PackageID INTEGER UNSIGNED NOT NULL, + RelTypeID TINYINT UNSIGNED NOT NULL, + RelName VARCHAR(255) NOT NULL, + RelCondition VARCHAR(20), + INDEX (PackageID), + INDEX (RelName), + FOREIGN KEY (PackageID) REFERENCES Packages(ID) ON DELETE CASCADE, + FOREIGN KEY (RelTypeID) REFERENCES RelationTypes(ID) ON DELETE NO ACTION +) ENGINE = InnoDB; + + -- Track which sources a package has -- CREATE TABLE PackageSources ( diff --git a/schema/gendummydata.py b/schema/gendummydata.py index 18852a2..bb622d1 100755 --- a/schema/gendummydata.py +++ b/schema/gendummydata.py @@ -29,6 +29,7 @@ MAX_DEVS = .1 # what percentage of MAX_USERS are Developers MAX_TUS = .2 # what percentage of MAX_USERS are Trusted Users MAX_PKGS = 900 # how many packages to load PKG_DEPS = (1, 15) # min/max depends a package has +PKG_RELS = (1, 5) # min/max relations a package has PKG_SRC = (1, 3) # min/max sources a package has PKG_CMNTS = (1, 5) # min/max number of comments a package has CATEGORIES_COUNT = 17 # the number of categories from aur-schema @@ -253,18 +254,22 @@ for p in list(track_votes.keys()): log.debug("Creating statements for package depends/sources.") for p in list(seen_pkgs.keys()): num_deps = random.randrange(PKG_DEPS[0], PKG_DEPS[1]) - this_deps = {} - i = 0 - while i != num_deps: + for i in range(0, num_deps): dep = random.choice([k for k in seen_pkgs]) - if dep not in this_deps: - deptype = random.randrange(1, 5) - if deptype == 4: - dep += ": for " + random.choice([k for k in seen_pkgs]) - s = "INSERT INTO PackageDepends VALUES (%d, %d, '%s', NULL);\n" - s = s % (seen_pkgs[p], deptype, dep) - out.write(s) - i += 1 + deptype = random.randrange(1, 5) + if deptype == 4: + dep += ": for " + random.choice([k for k in seen_pkgs]) + s = "INSERT INTO PackageDepends VALUES (%d, %d, '%s', NULL);\n" + s = s % (seen_pkgs[p], deptype, dep) + out.write(s) + + num_rels = random.randrange(PKG_RELS[0], PKG_RELS[1]) + for i in range(0, num_deps): + rel = random.choice([k for k in seen_pkgs]) + reltype = random.randrange(1, 4) + s = "INSERT INTO PackageRelations VALUES (%d, %d, '%s', NULL);\n" + s = s % (seen_pkgs[p], reltype, rel) + out.write(s) num_sources = random.randrange(PKG_SRC[0], PKG_SRC[1]) for i in range(num_sources): diff --git a/web/html/pkgsubmit.php b/web/html/pkgsubmit.php index 11206e1..3df38d8 100644 --- a/web/html/pkgsubmit.php +++ b/web/html/pkgsubmit.php @@ -155,7 +155,10 @@ if ($uid): 'makedepends' => array(), 'checkdepends' => array(), 'optdepends' => array(), - 'source' => array() + 'source' => array(), + 'conflicts' => array(), + 'provides' => array(), + 'replaces' => array() ); /* Fall-through case. */ case 'epoch': @@ -171,6 +174,9 @@ if ($uid): case 'makedepends': case 'checkdepends': case 'optdepends': + case 'conflicts': + case 'provides': + case 'replaces': $section_info[$key][] = $value; break; } @@ -190,7 +196,7 @@ if ($uid): if (!isset($pkgbase_info['pkgbase'])) { $pkgbase_info['pkgbase'] = $pkgbase_info['pkgname']; } - foreach (array('source', 'depends', 'makedepends', 'checkdepends', 'optdepends') as $array_opt) { + foreach (array('source', 'depends', 'makedepends', 'checkdepends', 'optdepends', 'conflicts', 'provides', 'replaces') as $array_opt) { if (empty($pkgbase_info[$array_opt])) { $pkgbase_info[$array_opt] = array(); } else { @@ -359,6 +365,14 @@ if ($uid): } } + foreach (array('conflicts', 'provides', 'replaces') as $reltype) { + foreach ($pi[$reltype] as $rel) { + $relpkgname = preg_replace("/(<|=|>).*/", "", $rel); + $relcondition = str_replace($relpkgname, "", $rel); + pkg_add_rel($pkgid, $reltype, $relpkgname, $relcondition); + } + } + foreach ($pi['source'] as $src) { pkg_add_src($pkgid, $src); } diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index 5c30a95..2eb0be4 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -148,6 +148,21 @@ function pkg_dependency_type_id_from_name($name) { } /** + * Get the ID of a relation type given its name + * + * @param string $name The name of the relation type + * + * @return int The ID of the relation type + */ +function pkg_relation_type_id_from_name($name) { + $dbh = DB::connect(); + $q = "SELECT ID FROM RelationTypes WHERE Name = "; + $q.= $dbh->quote($name); + $result = $dbh->query($q); + return $result->fetch(PDO::FETCH_COLUMN, 0); +} + +/** * Get the HTML code to display a package dependency link * * @param string $name The name of the dependency @@ -727,6 +742,27 @@ function pkg_add_dep($pkgid, $type, $depname, $depcondition) { } /** + * Add a relation for a specific package to the database + * + * @param int $pkgid The package ID to add the relation for + * @param string $type The type of relation to add + * @param string $relname The name of the relation to add + * @param string $relcondition The version requirement of the relation + * + * @return void + */ +function pkg_add_rel($pkgid, $type, $relname, $relcondition) { + $dbh = DB::connect(); + $q = sprintf("INSERT INTO PackageRelations (PackageID, RelTypeID, RelName, RelCondition) VALUES (%d, %d, %s, %s)", + $pkgid, + pkg_relation_type_id_from_name($type), + $dbh->quote($relname), + $dbh->quote($relcondition) + ); + $dbh->exec($q); +} + +/** * Add a source for a specific package to the database * * @param int $pkgid The package ID to add the source for -- 1.9.2
This adds information from the following three fields to the package details page: * conflicts * provides * replaces If either of these fields is empty, it is not displayed. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/lib/pkgfuncs.inc.php | 28 +++++++++++++++++++ web/template/pkg_details.php | 64 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index 2eb0be4..a04f525 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -133,6 +133,34 @@ function pkg_dependencies($pkgid) { } /** + * Get package relations for a specific package + * + * @param int $pkgid The package to get relations for + * + * @return array All package relations for the package + */ +function pkg_relations($pkgid) { + $rels = array(); + $pkgid = intval($pkgid); + if ($pkgid > 0) { + $dbh = DB::connect(); + $q = "SELECT pr.RelName, rt.Name, pr.RelCondition, p.ID FROM PackageRelations pr "; + $q.= "LEFT JOIN Packages p ON pr.RelName = p.Name "; + $q.= "LEFT JOIN RelationTypes rt ON rt.ID = pr.RelTypeID "; + $q.= "WHERE pr.PackageID = ". $pkgid . " "; + $q.= "ORDER BY pr.RelName"; + $result = $dbh->query($q); + if (!$result) { + return array(); + } + while ($row = $result->fetch(PDO::FETCH_NUM)) { + $rels[] = $row; + } + } + return $rels; +} + +/** * Get the ID of a dependency type given its name * * @param string $name The name of the dependency type diff --git a/web/template/pkg_details.php b/web/template/pkg_details.php index f0bfa0b..da90c9d 100644 --- a/web/template/pkg_details.php +++ b/web/template/pkg_details.php @@ -25,6 +25,22 @@ $urlpath = URL_DIR . substr($row['BaseName'], 0, 2) . "/" . $row['BaseName']; $deps = pkg_dependencies($row["ID"]); $requiredby = pkg_required($row["Name"]); +$rels = pkg_relations($row["ID"]); +$rels_c = $rels_p = $rels_r = array(); +foreach ($rels as $rel) { + switch ($rel[1]) { + case "conflicts": + $rels_c[] = $rel; + break; + case "provides": + $rels_p[] = $rel; + break; + case "replaces": + $rels_r[] = $rel; + break; + } +} + # $sources[0] = 'src'; $sources = pkg_sources($row["ID"]); ?> @@ -156,6 +172,54 @@ if ($SID && ($uid == $row["MaintainerUID"] || <th><?= __('License') . ': ' ?></th> <td><?= htmlspecialchars($license) ?></td> </tr> + <?php if (count($rels_c) > 0): ?> + <tr> + <th><?= __('Conflicts') . ': ' ?></th> + <td class="wrap relatedto"> + <?php foreach($rels_c as $rarr): ?> + <span class="related"> + <?php if ($rarr !== end($rels_c)): ?> + <?= htmlspecialchars($rarr[0]) ?>, + <?php else: ?> + <?= htmlspecialchars($rarr[0]) ?> + <?php endif; ?> + </span> + <?php endforeach; ?> + </td> + </tr> + <?php endif; ?> + <?php if (count($rels_p) > 0): ?> + <tr> + <th><?= __('Provides') . ': ' ?></th> + <td class="wrap relatedto"> + <?php foreach($rels_p as $rarr): ?> + <span class="related"> + <?php if ($rarr !== end($rels_p)): ?> + <?= htmlspecialchars($rarr[0]) ?>, + <?php else: ?> + <?= htmlspecialchars($rarr[0]) ?> + <?php endif; ?> + </span> + <?php endforeach; ?> + </td> + </tr> + <?php endif; ?> + <?php if (count($rels_r) > 0): ?> + <tr> + <th><?= __('Replaces') . ': ' ?></th> + <td class="wrap relatedto"> + <?php foreach($rels_r as $rarr): ?> + <span class="related"> + <?php if ($rarr !== end($rels_r)): ?> + <?= htmlspecialchars($rarr[0]) ?>, + <?php else: ?> + <?= htmlspecialchars($rarr[0]) ?> + <?php endif; ?> + </span> + <?php endforeach; ?> + </td> + </tr> + <?php endif; ?> <tr> <th><?= __('Submitter') .': ' ?></th> <?php -- 1.9.2
Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- UPGRADING | 18 ++++++++++++++++++ schema/aur-schema.sql | 21 +++++++++++++++++++++ web/html/pkgsubmit.php | 9 ++++++++- web/lib/pkgfuncs.inc.php | 43 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 1 deletion(-) diff --git a/UPGRADING b/UPGRADING index f523140..814fea1 100644 --- a/UPGRADING +++ b/UPGRADING @@ -199,6 +199,24 @@ CREATE TABLE PackageRelations ( ) ENGINE = InnoDB; ---- +17. Create tables to store package groups: + +---- +CREATE TABLE Groups ( + ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + Name VARCHAR(64) NOT NULL, + PRIMARY KEY (ID), + UNIQUE (Name) +) ENGINE = InnoDB; +CREATE TABLE PackageGroups ( + PackageID INTEGER UNSIGNED NOT NULL, + GroupID INTEGER UNSIGNED NOT NULL, + PRIMARY KEY (PackageID, GroupID), + FOREIGN KEY (PackageID) REFERENCES Packages(ID) ON DELETE CASCADE, + FOREIGN KEY (GroupID) REFERENCES Groups(ID) ON DELETE CASCADE +) ENGINE = InnoDB; +---- + From 2.2.0 to 2.3.0 ------------------- diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql index c98ba77..ae42fd3 100644 --- a/schema/aur-schema.sql +++ b/schema/aur-schema.sql @@ -133,6 +133,27 @@ CREATE TABLE Packages ( ) ENGINE = InnoDB; +-- Information about groups +-- +CREATE TABLE Groups ( + ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + Name VARCHAR(64) NOT NULL, + PRIMARY KEY (ID), + UNIQUE (Name) +) ENGINE = InnoDB; + + +-- Information about package-group-relations +-- +CREATE TABLE PackageGroups ( + PackageID INTEGER UNSIGNED NOT NULL, + GroupID INTEGER UNSIGNED NOT NULL, + PRIMARY KEY (PackageID, GroupID), + FOREIGN KEY (PackageID) REFERENCES Packages(ID) ON DELETE CASCADE, + FOREIGN KEY (GroupID) REFERENCES Groups(ID) ON DELETE CASCADE +) ENGINE = InnoDB; + + -- Define the package dependency types -- CREATE TABLE DependencyTypes ( diff --git a/web/html/pkgsubmit.php b/web/html/pkgsubmit.php index 3df38d8..107441f 100644 --- a/web/html/pkgsubmit.php +++ b/web/html/pkgsubmit.php @@ -151,6 +151,7 @@ if ($uid): } } $section_info = array( + 'groups' => array(), 'depends' => array(), 'makedepends' => array(), 'checkdepends' => array(), @@ -169,6 +170,7 @@ if ($uid): case 'license': $section_info[$key] = $value; break; + case 'groups': case 'source': case 'depends': case 'makedepends': @@ -196,7 +198,7 @@ if ($uid): if (!isset($pkgbase_info['pkgbase'])) { $pkgbase_info['pkgbase'] = $pkgbase_info['pkgname']; } - foreach (array('source', 'depends', 'makedepends', 'checkdepends', 'optdepends', 'conflicts', 'provides', 'replaces') as $array_opt) { + foreach (array('groups', 'source', 'depends', 'makedepends', 'checkdepends', 'optdepends', 'conflicts', 'provides', 'replaces') as $array_opt) { if (empty($pkgbase_info[$array_opt])) { $pkgbase_info[$array_opt] = array(); } else { @@ -357,6 +359,11 @@ if ($uid): foreach ($pkginfo as $pi) { $pkgid = pkg_create($base_id, $pi['pkgname'], $pi['license'], $pi['full-version'], $pi['pkgdesc'], $pi['url']); + foreach ($pi['groups'] as $grp) { + $grpid = pkg_create_group($grp); + pkg_add_grp($pkgid, $grpid); + } + foreach (array('depends', 'makedepends', 'checkdepends', 'optdepends') as $deptype) { foreach ($pi[$deptype] as $dep) { $deppkgname = preg_replace("/(<|=|>).*/", "", $dep); diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index a04f525..f80d4b4 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -805,3 +805,46 @@ function pkg_add_src($pkgid, $pkgsrc) { $dbh->exec($q); } + +/** + * Creates a new group and returns its ID + * + * If the groups already exists, the ID of the already existing group is + * returned. + * + * @param string $name The name of the group to create + * + * @return int The ID of the group + */ +function pkg_create_group($name) { + $dbh = DB::connect(); + $q = sprintf("SELECT ID FROM Groups WHERE Name = %s", $dbh->quote($name)); + $result = $dbh->query($q); + if ($result) { + $grpid = $result->fetch(PDO::FETCH_COLUMN, 0); + if ($grpid > 0) { + return $grpid; + } + } + + $q = sprintf("INSERT INTO Groups (Name) VALUES (%s)", $dbh->quote($name)); + $dbh->exec($q); + return $dbh->lastInsertId(); +} + +/** + * Add a package to a group + * + * @param int $pkgid The package ID of the package to add + * @param int $grpid The group ID of the group to add the package to + * + * @return void + */ +function pkg_add_grp($pkgid, $grpid) { + $dbh = DB::connect(); + $q = sprintf("INSERT INTO PackageGroups (PackageID, GroupID) VALUES (%d, %d)", + $pkgid, + $grpid + ); + $dbh->exec($q); +} -- 1.9.2
The groups field is hidden if a package doesn't belong to any group. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/lib/pkgfuncs.inc.php | 26 ++++++++++++++++++++++++++ web/template/pkg_details.php | 18 ++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index f80d4b4..6811767 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -105,6 +105,32 @@ function pkg_from_name($name="") { } /** + * Get package groups for a specific package + * + * @param int $pkgid The package to get groups for + * + * @return array All package groups for the package + */ +function pkg_groups($pkgid) { + $grps = array(); + $pkgid = intval($pkgid); + if ($pkgid > 0) { + $dbh = DB::connect(); + $q = "SELECT g.Name FROM Groups g "; + $q.= "INNER JOIN PackageGroups pg ON pg.GroupID = g.ID "; + $q.= "WHERE pg.PackageID = ". $pkgid; + $result = $dbh->query($q); + if (!$result) { + return array(); + } + while ($row = $result->fetch(PDO::FETCH_COLUMN, 0)) { + $grps[] = $row; + } + } + return $grps; +} + +/** * Get package dependencies for a specific package * * @param int $pkgid The package to get dependencies for diff --git a/web/template/pkg_details.php b/web/template/pkg_details.php index da90c9d..ff3f710 100644 --- a/web/template/pkg_details.php +++ b/web/template/pkg_details.php @@ -22,6 +22,8 @@ $out_of_date_time = ($row["OutOfDateTS"] == 0) ? $msg : gmdate("Y-m-d", intval($ $urlpath = URL_DIR . substr($row['BaseName'], 0, 2) . "/" . $row['BaseName']; +$grps = pkg_groups($row["ID"]); + $deps = pkg_dependencies($row["ID"]); $requiredby = pkg_required($row["Name"]); @@ -172,6 +174,22 @@ if ($SID && ($uid == $row["MaintainerUID"] || <th><?= __('License') . ': ' ?></th> <td><?= htmlspecialchars($license) ?></td> </tr> + <?php if (count($grps) > 0): ?> + <tr> + <th><?= __('Groups') . ': ' ?></th> + <td class="wrap"> + <?php foreach($grps as $grp): ?> + <span class="related"> + <?php if ($grp !== end($grps)): ?> + <?= htmlspecialchars($grp) ?>, + <?php else: ?> + <?= htmlspecialchars($grp) ?> + <?php endif; ?> + </span> + <?php endforeach; ?> + </td> + </tr> + <?php endif; ?> <?php if (count($rels_c) > 0): ?> <tr> <th><?= __('Conflicts') . ': ' ?></th> -- 1.9.2
Split out package licenses into two separate tables in order to support multiple licenses per package. The code on the package details page is adjusted accordingly. UPGRADING contains instructions on how to convert existing licenses in the database to the new layout. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- UPGRADING | 33 ++++++++++++++++++ schema/aur-schema.sql | 22 +++++++++++- web/html/pkgsubmit.php | 20 +++++++---- web/lib/pkgfuncs.inc.php | 81 ++++++++++++++++++++++++++++++++++++++++---- web/template/pkg_details.php | 17 ++++++++-- 5 files changed, 157 insertions(+), 16 deletions(-) diff --git a/UPGRADING b/UPGRADING index 814fea1..357cd6c 100644 --- a/UPGRADING +++ b/UPGRADING @@ -217,6 +217,39 @@ CREATE TABLE PackageGroups ( ) ENGINE = InnoDB; ---- +18. Create tables to store package licenses: + +---- +CREATE TABLE Licenses ( + ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + Name VARCHAR(64) NOT NULL, + PRIMARY KEY (ID), + UNIQUE (Name) +) ENGINE = InnoDB; +CREATE TABLE PackageLicenses ( + PackageID INTEGER UNSIGNED NOT NULL, + LicenseID INTEGER UNSIGNED NOT NULL, + PRIMARY KEY (PackageID, LicenseID), + FOREIGN KEY (PackageID) REFERENCES Packages(ID) ON DELETE CASCADE, + FOREIGN KEY (LicenseID) REFERENCES Licenses(ID) ON DELETE CASCADE +) ENGINE = InnoDB; +---- + +19. Convert existing licenses to the new storage format: + +---- +INSERT INTO Licenses (Name) SELECT DISTINCT License FROM Packages; +INSERT INTO PackageLicenses (PackageID, LicenseID) + SELECT Packages.ID, Licenses.ID FROM Packages + INNER JOIN Licenses ON Licenses.Name = Packages.License; +---- + +20. Delete the license column from the Packages table: + +---- +ALTER TABLE Packages DROP COLUMN License; +---- + From 2.2.0 to 2.3.0 ------------------- diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql index ae42fd3..8533548 100644 --- a/schema/aur-schema.sql +++ b/schema/aur-schema.sql @@ -126,13 +126,33 @@ CREATE TABLE Packages ( Version VARCHAR(32) NOT NULL DEFAULT '', Description VARCHAR(255) NOT NULL DEFAULT "An Arch Package", URL VARCHAR(255) NOT NULL DEFAULT "https://www.archlinux.org", - License VARCHAR(40) NOT NULL DEFAULT '', PRIMARY KEY (ID), UNIQUE (Name), FOREIGN KEY (PackageBaseID) REFERENCES PackageBases(ID) ON DELETE CASCADE ) ENGINE = InnoDB; +-- Information about licenses +-- +CREATE TABLE Licenses ( + ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + Name VARCHAR(64) NOT NULL, + PRIMARY KEY (ID), + UNIQUE (Name) +) ENGINE = InnoDB; + + +-- Information about package-license-relations +-- +CREATE TABLE PackageLicenses ( + PackageID INTEGER UNSIGNED NOT NULL, + LicenseID INTEGER UNSIGNED NOT NULL, + PRIMARY KEY (PackageID, LicenseID), + FOREIGN KEY (PackageID) REFERENCES Packages(ID) ON DELETE CASCADE, + FOREIGN KEY (LicenseID) REFERENCES Licenses(ID) ON DELETE CASCADE +) ENGINE = InnoDB; + + -- Information about groups -- CREATE TABLE Groups ( diff --git a/web/html/pkgsubmit.php b/web/html/pkgsubmit.php index 107441f..1075620 100644 --- a/web/html/pkgsubmit.php +++ b/web/html/pkgsubmit.php @@ -151,6 +151,7 @@ if ($uid): } } $section_info = array( + 'license' => array(), 'groups' => array(), 'depends' => array(), 'makedepends' => array(), @@ -167,9 +168,9 @@ if ($uid): case 'pkgver': case 'pkgrel': case 'url': - case 'license': $section_info[$key] = $value; break; + case 'license': case 'groups': case 'source': case 'depends': @@ -198,7 +199,7 @@ if ($uid): if (!isset($pkgbase_info['pkgbase'])) { $pkgbase_info['pkgbase'] = $pkgbase_info['pkgname']; } - foreach (array('groups', 'source', 'depends', 'makedepends', 'checkdepends', 'optdepends', 'conflicts', 'provides', 'replaces') as $array_opt) { + foreach (array('license', 'groups', 'source', 'depends', 'makedepends', 'checkdepends', 'optdepends', 'conflicts', 'provides', 'replaces') as $array_opt) { if (empty($pkgbase_info[$array_opt])) { $pkgbase_info[$array_opt] = array(); } else { @@ -263,9 +264,11 @@ if ($uid): $error = __("Error - Package description cannot be greater than %d characters", 255); break; } - if (strlen($pi['license']) > 40) { - $error = __("Error - Package license cannot be greater than %d characters", 40); - break; + foreach ($pi['license'] as $lic) { + if (strlen($lic > 64)) { + $error = __("Error - Package license cannot be greater than %d characters", 64); + break; + } } if (strlen($pkginfo[$key]['full-version']) > 32) { $error = __("Error - Package version cannot be greater than %d characters", 32); @@ -357,7 +360,12 @@ if ($uid): } foreach ($pkginfo as $pi) { - $pkgid = pkg_create($base_id, $pi['pkgname'], $pi['license'], $pi['full-version'], $pi['pkgdesc'], $pi['url']); + $pkgid = pkg_create($base_id, $pi['pkgname'], $pi['full-version'], $pi['pkgdesc'], $pi['url']); + + foreach ($pi['license'] as $lic) { + $licid = pkg_create_license($lic); + pkg_add_lic($pkgid, $licid); + } foreach ($pi['groups'] as $grp) { $grpid = pkg_create_group($grp); diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index 6811767..f800e34 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -105,6 +105,32 @@ function pkg_from_name($name="") { } /** + * Get licenses for a specific package + * + * @param int $pkgid The package to get licenses for + * + * @return array All licenses for the package + */ +function pkg_licenses($pkgid) { + $lics = array(); + $pkgid = intval($pkgid); + if ($pkgid > 0) { + $dbh = DB::connect(); + $q = "SELECT l.Name FROM Licenses l "; + $q.= "INNER JOIN PackageLicenses pl ON pl.LicenseID = l.ID "; + $q.= "WHERE pl.PackageID = ". $pkgid; + $result = $dbh->query($q); + if (!$result) { + return array(); + } + while ($row = $result->fetch(PDO::FETCH_COLUMN, 0)) { + $lics[] = $row; + } + } + return $lics; +} + +/** * Get package groups for a specific package * * @param int $pkgid The package to get groups for @@ -756,20 +782,18 @@ function pkg_details_by_name($pkgname) { * * @param int $base_id ID of the package base * @param string $pkgname Name of the new package - * @param string $license License of the new package * @param string $pkgver Version of the new package * @param string $pkgdesc Description of the new package * @param string $pkgurl Upstream URL for the new package * * @return int ID of the new package */ -function pkg_create($base_id, $pkgname, $license, $pkgver, $pkgdesc, $pkgurl) { +function pkg_create($base_id, $pkgname, $pkgver, $pkgdesc, $pkgurl) { $dbh = DB::connect(); - $q = sprintf("INSERT INTO Packages (PackageBaseID, Name, License, " . - "Version, Description, URL) VALUES (%d, %s, %s, %s, %s, %s)", - $base_id, $dbh->quote($pkgname), $dbh->quote($license), - $dbh->quote($pkgver), $dbh->quote($pkgdesc), - $dbh->quote($pkgurl)); + $q = sprintf("INSERT INTO Packages (PackageBaseID, Name, Version, " . + "Description, URL) VALUES (%d, %s, %s, %s, %s)", + $base_id, $dbh->quote($pkgname), $dbh->quote($pkgver), + $dbh->quote($pkgdesc), $dbh->quote($pkgurl)); $dbh->exec($q); return $dbh->lastInsertId(); } @@ -874,3 +898,46 @@ function pkg_add_grp($pkgid, $grpid) { ); $dbh->exec($q); } + +/** + * Creates a new license and returns its ID + * + * If the license already exists, the ID of the already existing license is + * returned. + * + * @param string $name The name of the license to create + * + * @return int The ID of the license + */ +function pkg_create_license($name) { + $dbh = DB::connect(); + $q = sprintf("SELECT ID FROM Licenses WHERE Name = %s", $dbh->quote($name)); + $result = $dbh->query($q); + if ($result) { + $licid = $result->fetch(PDO::FETCH_COLUMN, 0); + if ($licid > 0) { + return $licid; + } + } + + $q = sprintf("INSERT INTO Licenses (Name) VALUES (%s)", $dbh->quote($name)); + $dbh->exec($q); + return $dbh->lastInsertId(); +} + +/** + * Add a license to a package + * + * @param int $pkgid The package ID of the package + * @param int $grpid The ID of the license to add + * + * @return void + */ +function pkg_add_lic($pkgid, $licid) { + $dbh = DB::connect(); + $q = sprintf("INSERT INTO PackageLicenses (PackageID, LicenseID) VALUES (%d, %d)", + $pkgid, + $licid + ); + $dbh->exec($q); +} diff --git a/web/template/pkg_details.php b/web/template/pkg_details.php index ff3f710..7836596 100644 --- a/web/template/pkg_details.php +++ b/web/template/pkg_details.php @@ -22,6 +22,7 @@ $out_of_date_time = ($row["OutOfDateTS"] == 0) ? $msg : gmdate("Y-m-d", intval($ $urlpath = URL_DIR . substr($row['BaseName'], 0, 2) . "/" . $row['BaseName']; +$lics = pkg_licenses($row["ID"]); $grps = pkg_groups($row["ID"]); $deps = pkg_dependencies($row["ID"]); @@ -170,10 +171,22 @@ if ($SID && ($uid == $row["MaintainerUID"] || <?php endif; ?> </td> </tr> + <?php if (count($lics) > 0): ?> <tr> - <th><?= __('License') . ': ' ?></th> - <td><?= htmlspecialchars($license) ?></td> + <th><?= __('Licenses') . ': ' ?></th> + <td class="wrap"> + <?php foreach($lics as $lic): ?> + <span class="related"> + <?php if ($lic !== end($lics)): ?> + <?= htmlspecialchars($lic) ?>, + <?php else: ?> + <?= htmlspecialchars($lic) ?> + <?php endif; ?> + </span> + <?php endforeach; ?> + </td> </tr> + <?php endif; ?> <?php if (count($grps) > 0): ?> <tr> <th><?= __('Groups') . ': ' ?></th> -- 1.9.2
Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/html/pkgsubmit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/html/pkgsubmit.php b/web/html/pkgsubmit.php index 1075620..180a0b2 100644 --- a/web/html/pkgsubmit.php +++ b/web/html/pkgsubmit.php @@ -404,7 +404,7 @@ if ($uid): end_atomic_commit(); - header('Location: ' . get_pkg_uri($pi[0]['pkgname'])); + header('Location: ' . get_pkgbase_uri($pkgbase_info['pkgbase'])); } chdir($cwd); -- 1.9.2
participants (1)
-
Lukas Fleischer