aboutsummaryrefslogtreecommitdiff
path: root/brep
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-01-18 07:35:12 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-01-23 17:47:47 +0200
commit1dc38cf49b6c7a8b661a9cc675ded94c8ab33c36 (patch)
tree5a216148adb9d842a5a15c032a671182faa9ba06 /brep
parentfe6182a8c89675f92e72c881d707e21cdf56f376 (diff)
Implement brep-migrate utility
Diffstat (limited to 'brep')
-rw-r--r--brep/.gitignore2
-rw-r--r--brep/buildfile4
-rw-r--r--brep/database-lock43
-rw-r--r--brep/database-lock.cxx44
-rw-r--r--brep/mod-package-search.cxx16
-rwxr-xr-xbrep/odb.sh18
-rw-r--r--brep/package6
-rw-r--r--brep/package-extra.sql20
-rw-r--r--brep/package.xml406
9 files changed, 544 insertions, 15 deletions
diff --git a/brep/.gitignore b/brep/.gitignore
index 2c23e23..852a40d 100644
--- a/brep/.gitignore
+++ b/brep/.gitignore
@@ -2,4 +2,4 @@ options
options.?xx
package-odb*
package.sql
-
+package-extra
diff --git a/brep/buildfile b/brep/buildfile
index 9826504..1aa4d08 100644
--- a/brep/buildfile
+++ b/brep/buildfile
@@ -10,7 +10,7 @@ define sql: file
sql{*}: extension = sql
sql{*}: install = data
-./: lib{brep} mod{brep} sql{package}
+./: lib{brep} mod{brep} sql{package package-extra}
# lib{brep}
#
@@ -20,8 +20,10 @@ import libs += libbpkg%lib{bpkg}
lib{brep}: \
{hxx cxx}{ package } \
+{file }{ package.xml } \
{hxx ixx cxx}{ package-odb } \
{hxx cxx}{ package-traits } \
+{hxx cxx}{ database-lock } \
{hxx }{ types } \
{hxx }{ utility } \
{hxx }{ version } \
diff --git a/brep/database-lock b/brep/database-lock
new file mode 100644
index 0000000..72036a1
--- /dev/null
+++ b/brep/database-lock
@@ -0,0 +1,43 @@
+// file : brep/database-lock -*- C++ -*-
+// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BREP_DATABASE_LOCK
+#define BREP_DATABASE_LOCK
+
+#include <memory> // unique_ptr
+#include <exception>
+
+#include <odb/pgsql/forward.hxx> // database, transaction
+#include <odb/pgsql/connection.hxx>
+
+namespace brep
+{
+ struct database_locked: std::exception
+ {
+ virtual char const*
+ what () const throw () {return "database locked";}
+ };
+
+ // Try to "lock" the PostgreSQL database in the constructor and release the
+ // lock in the destructor. Throw database_locked if the database is already
+ // locked by someone else. May also throw odb::pgsql::database_exception.
+ //
+ // This mechanism is used by the brep loader and schema migration tool to
+ // make sure they don't step on each others toes.
+ //
+ // Note: movable but not copyable.
+ //
+ class database_lock
+ {
+ public:
+ explicit
+ database_lock (odb::pgsql::database&);
+
+ private:
+ odb::pgsql::connection_ptr connection_;
+ std::unique_ptr<odb::pgsql::transaction> transaction_;
+ };
+}
+
+#endif // BREP_DATABASE_LOCK
diff --git a/brep/database-lock.cxx b/brep/database-lock.cxx
new file mode 100644
index 0000000..3b8ae21
--- /dev/null
+++ b/brep/database-lock.cxx
@@ -0,0 +1,44 @@
+// file : brep/database-lock.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <brep/database-lock>
+
+#include <odb/pgsql/database.hxx>
+#include <odb/pgsql/exceptions.hxx>
+#include <odb/pgsql/transaction.hxx>
+
+namespace brep
+{
+ using namespace odb::pgsql;
+
+ database_lock::
+ database_lock (database& db)
+ {
+ // Before locking the table make sure it exists.
+ //
+ {
+ transaction t (db.begin ());
+ db.execute ("CREATE TABLE IF NOT EXISTS database_mutex ()");
+ t.commit ();
+ }
+
+ connection_ = db.connection ();
+
+ // Don't make current. Will be rolled back in destructor.
+ //
+ transaction_.reset (new transaction (connection_->begin (), false));
+
+ try
+ {
+ connection_->execute ("LOCK TABLE database_mutex NOWAIT");
+ }
+ catch (const database_exception& e)
+ {
+ if (e.sqlstate () == "55P03") // The table is already locked.
+ throw database_locked ();
+
+ throw;
+ }
+ }
+}
diff --git a/brep/mod-package-search.cxx b/brep/mod-package-search.cxx
index 4326435..d649ff4 100644
--- a/brep/mod-package-search.cxx
+++ b/brep/mod-package-search.cxx
@@ -9,6 +9,7 @@
#include <odb/session.hxx>
#include <odb/database.hxx>
#include <odb/transaction.hxx>
+#include <odb/schema-catalog.hxx>
#include <web/xhtml>
#include <web/module>
@@ -16,6 +17,7 @@
#include <brep/types>
#include <brep/utility>
+#include <brep/version>
#include <brep/page>
#include <brep/options>
@@ -38,6 +40,20 @@ init (scanner& s)
options_->root (dir_path ("/"));
db_ = shared_database (*options_);
+
+ // Check that the database schema matches the current one. It's enough to
+ // perform the check in just a single module implementation (and we don't
+ // do in the dispatcher because it doesn't use the database).
+ //
+ // Note that the failure can be reported by each web server worker process.
+ // While it could be tempting to move the check to the
+ // repository_root::version() function, it would be wrong. The function can
+ // be called by a different process (usually the web server root one) not
+ // having the proper permissions to access the database.
+ //
+ if (schema_catalog::current_version (*db_) != db_->schema_version ())
+ fail << "database schema differs from the current one (module "
+ << BREP_VERSION_STR << ")";
}
template <typename T>
diff --git a/brep/odb.sh b/brep/odb.sh
index 489d423..d68b28f 100755
--- a/brep/odb.sh
+++ b/brep/odb.sh
@@ -1,11 +1,13 @@
#! /usr/bin/env bash
odb -d pgsql --std c++11 --generate-query --generate-schema \
- --odb-epilogue '#include <brep/wrapper-traits>' \
- --hxx-prologue '#include <brep/wrapper-traits>' \
- --hxx-prologue "#include <brep/package-traits>" \
- --sql-epilogue-file package-extra.sql \
- -I .. -I ../../libbpkg -I ../../libbutl \
- --hxx-suffix "" --include-with-brackets \
- --include-prefix brep --guard-prefix BREP \
- package
+ --schema-format sql --schema-format embedded \
+ --odb-epilogue '#include <brep/wrapper-traits>' \
+ --hxx-prologue '#include <brep/wrapper-traits>' \
+ --hxx-prologue '#include <brep/package-traits>' \
+ -I .. -I ../../libbpkg -I ../../libbutl \
+ --hxx-suffix "" --include-with-brackets \
+ --include-prefix brep --guard-prefix BREP \
+ package
+
+xxd -i <package-extra.sql >package-extra
diff --git a/brep/package b/brep/package
index 92a2320..2700e8a 100644
--- a/brep/package
+++ b/brep/package
@@ -19,6 +19,12 @@
#include <brep/types>
#include <brep/utility>
+// Used by the data migration entries.
+//
+#define LIBBREP_SCHEMA_VERSION_BASE 1
+
+#pragma db model version(LIBBREP_SCHEMA_VERSION_BASE, 1, open)
+
// The uint16_t value range is not fully covered by SMALLINT PostgreSQL type
// to which uint16_t is mapped by default.
//
diff --git a/brep/package-extra.sql b/brep/package-extra.sql
index dc37d1f..9a847e3 100644
--- a/brep/package-extra.sql
+++ b/brep/package-extra.sql
@@ -1,12 +1,22 @@
-DROP TYPE IF EXISTS weighted_text CASCADE;
-CREATE TYPE weighted_text AS (a TEXT, b TEXT, c TEXT, d TEXT);
-
+-- This file should be parsable by the brep-migrate utility. To decrease the
+-- parser complexity, the following restrictions are placed:
+--
+-- * comments must start with -- at the beginning of the line (ignoring
+-- leading spaces)
+-- * only CREATE and DROP statements for FUNCTION and TYPE
+-- * function bodies must be defined using $$-quoted strings
+-- * strings other then function bodies must be quoted with ' or "
+-- * statements must end with ";\n"
+--
DROP FUNCTION IF EXISTS to_tsvector(IN document weighted_text);
DROP FUNCTION IF EXISTS search_packages(IN query tsquery, INOUT name TEXT);
DROP FUNCTION IF EXISTS search_latest_packages(IN query tsquery);
DROP FUNCTION IF EXISTS latest_package(INOUT name TEXT);
DROP FUNCTION IF EXISTS latest_packages();
+DROP TYPE IF EXISTS weighted_text CASCADE;
+CREATE TYPE weighted_text AS (a TEXT, b TEXT, c TEXT, d TEXT);
+
-- Return the latest versions of internal packages as a set of package rows.
--
CREATE FUNCTION
@@ -72,9 +82,9 @@ $$ LANGUAGE SQL STABLE;
-- Search for packages matching the search query and having the specified name.
-- Return a set of rows containing the package id and search rank. If query
-- is NULL, then match all packages and return 0 rank for all rows.
---
+--
CREATE FUNCTION
-search_packages(IN query tsquery,
+search_packages(IN query tsquery,
INOUT name TEXT,
OUT version_epoch INTEGER,
OUT version_canonical_upstream TEXT,
diff --git a/brep/package.xml b/brep/package.xml
new file mode 100644
index 0000000..9c88f25
--- /dev/null
+++ b/brep/package.xml
@@ -0,0 +1,406 @@
+<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="pgsql" version="1">
+ <model version="1">
+ <table name="repository" kind="object">
+ <column name="name" type="TEXT" null="false"/>
+ <column name="location" type="TEXT" null="false"/>
+ <column name="display_name" type="TEXT" null="false"/>
+ <column name="priority" type="INTEGER" null="false"/>
+ <column name="url" type="TEXT" null="true"/>
+ <column name="email" type="TEXT" null="true"/>
+ <column name="summary" type="TEXT" null="true"/>
+ <column name="description" type="TEXT" null="true"/>
+ <column name="local_path" type="TEXT" null="false"/>
+ <column name="packages_timestamp" type="BIGINT" null="false"/>
+ <column name="repositories_timestamp" type="BIGINT" null="false"/>
+ <column name="internal" type="BOOLEAN" null="false"/>
+ <primary-key>
+ <column name="name"/>
+ </primary-key>
+ </table>
+ <table name="repository_complements" kind="container">
+ <column name="repository" type="TEXT" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="complement" type="TEXT" null="false"/>
+ <foreign-key name="repository_fk" on-delete="CASCADE">
+ <column name="repository"/>
+ <references table="repository">
+ <column name="name"/>
+ </references>
+ </foreign-key>
+ <index name="repository_complements_repository_i">
+ <column name="repository"/>
+ </index>
+ <index name="repository_complements_index_i">
+ <column name="index"/>
+ </index>
+ <foreign-key name="complement_fk" deferrable="DEFERRED">
+ <column name="complement"/>
+ <references table="repository">
+ <column name="name"/>
+ </references>
+ </foreign-key>
+ </table>
+ <table name="repository_prerequisites" kind="container">
+ <column name="repository" type="TEXT" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="prerequisite" type="TEXT" null="false"/>
+ <foreign-key name="repository_fk" on-delete="CASCADE">
+ <column name="repository"/>
+ <references table="repository">
+ <column name="name"/>
+ </references>
+ </foreign-key>
+ <index name="repository_prerequisites_repository_i">
+ <column name="repository"/>
+ </index>
+ <index name="repository_prerequisites_index_i">
+ <column name="index"/>
+ </index>
+ <foreign-key name="prerequisite_fk" deferrable="DEFERRED">
+ <column name="prerequisite"/>
+ <references table="repository">
+ <column name="name"/>
+ </references>
+ </foreign-key>
+ </table>
+ <table name="package" kind="object">
+ <column name="name" type="TEXT" null="false"/>
+ <column name="version_epoch" type="INTEGER" null="false"/>
+ <column name="version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="version_revision" type="INTEGER" null="false"/>
+ <column name="version_upstream" type="TEXT" null="false"/>
+ <column name="version_release" type="TEXT" null="true"/>
+ <column name="priority" type="INTEGER" null="false"/>
+ <column name="priority_comment" type="TEXT" null="false"/>
+ <column name="summary" type="TEXT" null="false"/>
+ <column name="description" type="TEXT" null="true"/>
+ <column name="changes" type="TEXT" null="false"/>
+ <column name="url" type="TEXT" null="false"/>
+ <column name="url_comment" type="TEXT" null="false"/>
+ <column name="package_url" type="TEXT" null="true"/>
+ <column name="package_url_comment" type="TEXT" null="true"/>
+ <column name="email" type="TEXT" null="false"/>
+ <column name="email_comment" type="TEXT" null="false"/>
+ <column name="package_email" type="TEXT" null="true"/>
+ <column name="package_email_comment" type="TEXT" null="true"/>
+ <column name="internal_repository" type="TEXT" null="true"/>
+ <column name="location" type="TEXT" null="true"/>
+ <column name="search_index" type="tsvector" null="true"/>
+ <primary-key>
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </primary-key>
+ <foreign-key name="internal_repository_fk" deferrable="DEFERRED">
+ <column name="internal_repository"/>
+ <references table="repository">
+ <column name="name"/>
+ </references>
+ </foreign-key>
+ <index name="package_search_index_i" method="GIN">
+ <column name="search_index"/>
+ </index>
+ </table>
+ <table name="package_license_alternatives" kind="container">
+ <column name="name" type="TEXT" null="false"/>
+ <column name="version_epoch" type="INTEGER" null="false"/>
+ <column name="version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="version_revision" type="INTEGER" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="comment" type="TEXT" null="false"/>
+ <foreign-key name="object_id_fk" on-delete="CASCADE">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <references table="package">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_license_alternatives_object_id_i">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ <index name="package_license_alternatives_index_i">
+ <column name="index"/>
+ </index>
+ </table>
+ <table name="package_licenses" kind="container">
+ <column name="name" type="TEXT" null="false"/>
+ <column name="version_epoch" type="INTEGER" null="false"/>
+ <column name="version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="version_revision" type="INTEGER" null="false"/>
+ <column name="alternative_index" type="BIGINT" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="license" type="TEXT" null="false"/>
+ <foreign-key name="object_id_fk" on-delete="CASCADE">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <references table="package">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_licenses_object_id_i">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ </table>
+ <table name="package_tags" kind="container">
+ <column name="name" type="TEXT" null="false"/>
+ <column name="version_epoch" type="INTEGER" null="false"/>
+ <column name="version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="version_revision" type="INTEGER" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="tag" type="TEXT" null="false"/>
+ <foreign-key name="object_id_fk" on-delete="CASCADE">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <references table="package">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_tags_object_id_i">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ <index name="package_tags_index_i">
+ <column name="index"/>
+ </index>
+ </table>
+ <table name="package_dependencies" kind="container">
+ <column name="name" type="TEXT" null="false"/>
+ <column name="version_epoch" type="INTEGER" null="false"/>
+ <column name="version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="version_revision" type="INTEGER" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="conditional" type="BOOLEAN" null="false"/>
+ <column name="comment" type="TEXT" null="false"/>
+ <foreign-key name="object_id_fk" on-delete="CASCADE">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <references table="package">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_dependencies_object_id_i">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ <index name="package_dependencies_index_i">
+ <column name="index"/>
+ </index>
+ </table>
+ <table name="package_dependency_alternatives" kind="container">
+ <column name="name" type="TEXT" null="false"/>
+ <column name="version_epoch" type="INTEGER" null="false"/>
+ <column name="version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="version_revision" type="INTEGER" null="false"/>
+ <column name="dependency_index" type="BIGINT" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="dep_name" type="TEXT" null="false"/>
+ <column name="dep_version_epoch" type="INTEGER" null="false"/>
+ <column name="dep_version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="dep_version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="dep_version_revision" type="INTEGER" null="false"/>
+ <column name="dep_min_version_epoch" type="INTEGER" null="true"/>
+ <column name="dep_min_version_canonical_upstream" type="TEXT" null="true"/>
+ <column name="dep_min_version_canonical_release" type="TEXT" null="true"/>
+ <column name="dep_min_version_revision" type="INTEGER" null="true"/>
+ <column name="dep_min_version_upstream" type="TEXT" null="true"/>
+ <column name="dep_min_version_release" type="TEXT" null="true"/>
+ <column name="dep_max_version_epoch" type="INTEGER" null="true"/>
+ <column name="dep_max_version_canonical_upstream" type="TEXT" null="true"/>
+ <column name="dep_max_version_canonical_release" type="TEXT" null="true"/>
+ <column name="dep_max_version_revision" type="INTEGER" null="true"/>
+ <column name="dep_max_version_upstream" type="TEXT" null="true"/>
+ <column name="dep_max_version_release" type="TEXT" null="true"/>
+ <column name="dep_min_open" type="BOOLEAN" null="true"/>
+ <column name="dep_max_open" type="BOOLEAN" null="true"/>
+ <foreign-key name="object_id_fk" on-delete="CASCADE">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <references table="package">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_dependency_alternatives_object_id_i">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ <foreign-key name="dep_package_fk" deferrable="DEFERRED">
+ <column name="dep_name"/>
+ <column name="dep_version_epoch"/>
+ <column name="dep_version_canonical_upstream"/>
+ <column name="dep_version_canonical_release"/>
+ <column name="dep_version_revision"/>
+ <references table="package">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ </table>
+ <table name="package_requirements" kind="container">
+ <column name="name" type="TEXT" null="false"/>
+ <column name="version_epoch" type="INTEGER" null="false"/>
+ <column name="version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="version_revision" type="INTEGER" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="conditional" type="BOOLEAN" null="false"/>
+ <column name="comment" type="TEXT" null="false"/>
+ <foreign-key name="object_id_fk" on-delete="CASCADE">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <references table="package">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_requirements_object_id_i">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ <index name="package_requirements_index_i">
+ <column name="index"/>
+ </index>
+ </table>
+ <table name="package_requirement_alternatives" kind="container">
+ <column name="name" type="TEXT" null="false"/>
+ <column name="version_epoch" type="INTEGER" null="false"/>
+ <column name="version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="version_revision" type="INTEGER" null="false"/>
+ <column name="requirement_index" type="BIGINT" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="id" type="TEXT" null="false"/>
+ <foreign-key name="object_id_fk" on-delete="CASCADE">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <references table="package">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_requirement_alternatives_object_id_i">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ </table>
+ <table name="package_other_repositories" kind="container">
+ <column name="name" type="TEXT" null="false"/>
+ <column name="version_epoch" type="INTEGER" null="false"/>
+ <column name="version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="version_revision" type="INTEGER" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="repository" type="TEXT" null="false"/>
+ <foreign-key name="object_id_fk" on-delete="CASCADE">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <references table="package">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_other_repositories_object_id_i">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ <index name="package_other_repositories_index_i">
+ <column name="index"/>
+ </index>
+ <foreign-key name="repository_fk" deferrable="DEFERRED">
+ <column name="repository"/>
+ <references table="repository">
+ <column name="name"/>
+ </references>
+ </foreign-key>
+ </table>
+ </model>
+</changelog>