diff options
Diffstat (limited to 'brep')
-rw-r--r-- | brep/.gitignore | 2 | ||||
-rw-r--r-- | brep/buildfile | 4 | ||||
-rw-r--r-- | brep/database-lock | 43 | ||||
-rw-r--r-- | brep/database-lock.cxx | 44 | ||||
-rw-r--r-- | brep/mod-package-search.cxx | 16 | ||||
-rwxr-xr-x | brep/odb.sh | 18 | ||||
-rw-r--r-- | brep/package | 6 | ||||
-rw-r--r-- | brep/package-extra.sql | 20 | ||||
-rw-r--r-- | brep/package.xml | 406 |
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 "C""/> + <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 "C""/> + <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 "C""/> + <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 "C""/> + <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 "C""/> + <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 "C""/> + <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 "C""/> + <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 "C""/> + <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 "C""/> + <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 "C""/> + <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> |