diff --git a/swh/core/cli.py b/swh/core/cli.py --- a/swh/core/cli.py +++ b/swh/core/cli.py @@ -14,7 +14,10 @@ from importlib import import_module from swh.core.utils import numfile_sortkey as sortkey -from swh.core.tests.db_testing import pg_createdb, pg_restore, DB_DUMP_TYPES +from swh.core.tests.db_testing import ( + pg_createdb, pg_restore, DB_DUMP_TYPES, + swh_db_version +) @click.command() @@ -40,7 +43,6 @@ PGPORT=5434 swh-db-init indexer -d swh-indexer """ - dump_files = [] for modname in module: @@ -59,13 +61,24 @@ '(no sql/ dir)'.format(modname)) dump_files.extend(sorted(glob.glob(path.join(sqldir, '*.sql')), key=sortkey)) - if create: - pg_createdb(db_name) - - dump_files = [(x, DB_DUMP_TYPES[path.splitext(x)[1]]) - for x in dump_files] - for dump, dtype in dump_files: - click.secho('Loading {}'.format(dump), fg='yellow') - pg_restore(db_name, dump, dtype) - click.secho('DONE database is {}'.format(db_name), fg='green', bold=True) + # Create the db (or fail silently if already existing) + pg_createdb(db_name, check=False) + # Try to retrieve the db version if any + db_version = swh_db_version(db_name) + if not db_version: # Initialize the db + dump_files = [(x, DB_DUMP_TYPES[path.splitext(x)[1]]) + for x in dump_files] + for dump, dtype in dump_files: + print('dump: %s, type: %s' % (dump, dtype)) + click.secho('Loading {}'.format(dump), fg='yellow') + pg_restore(db_name, dump, dtype) + + if not db_version: + db_version = swh_db_version(db_name) + + # TODO: Ideally migrate the version from db_version to the latest + # db version + + click.secho('DONE database is {} version {}'.format(db_name, db_version), + fg='green', bold=True) diff --git a/swh/core/tests/db_testing.py b/swh/core/tests/db_testing.py --- a/swh/core/tests/db_testing.py +++ b/swh/core/tests/db_testing.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 The Software Heritage developers +# Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -13,6 +13,35 @@ DB_DUMP_TYPES = {'.sql': 'psql', '.dump': 'pg_dump'} +def swh_db_version(dbname_or_service): + """Retrieve the swh version if any. In case of the db not initialized, + this returns None. Otherwise, this returns the db's version. + + Args: + dbname_or_service (str): The db's name or service + + Returns: + Optional[Int]: Either the db's version or None + + """ + query = 'select version from dbversion order by dbversion desc limit 1' + cmd = [ + 'psql', '--tuples-only', '--no-psqlrc', '--quiet', + '-v', 'ON_ERROR_STOP=1', "--command=%s" % query, + dbname_or_service, + ] + + print('cmd: %s' % cmd) + + try: + r = subprocess.run(cmd, check=True, stdout=subprocess.PIPE, + universal_newlines=True) + result = int(r.stdout.strip()) + except Exception: # db not initialized + result = None + return result + + def pg_restore(dbname, dumpfile, dumptype='pg_dump'): """ Args: @@ -41,8 +70,15 @@ subprocess.check_call(['dropdb', dbname]) -def pg_createdb(dbname): - subprocess.check_call(['createdb', dbname]) +def pg_createdb(dbname, check=True): + """Create a db. If check is True and the db already exists, this will + raise an exception (original behavior). If check is False and + the db already exists, this will fail silently. If the db does + not exist, the db will be created. + + """ + _run = subprocess.check_call if check else subprocess.call + _run(['createdb', dbname]) def db_create(dbname, dumps=None):