コード例 #1
0
def test_switch_pre_import_post_import(data_working_copy,
                                       data_archive_readonly, cli_runner):
    with data_archive_readonly("gpkg-au-census") as data:
        with data_working_copy("polygons") as (repo_path, wc_path):
            wc = KartRepo(repo_path).working_copy

            r = cli_runner.invoke([
                "import",
                data / "census2016_sdhca_ot_short.gpkg",
                "census2016_sdhca_ot_ced_short",
            ])
            assert r.exit_code == 0, r.stderr
            r = cli_runner.invoke(["checkout", "HEAD^"])
            assert r.exit_code == 0, r.stderr

            with wc.session() as sess:
                count = sess.scalar(
                    f"""SELECT COUNT(name) FROM sqlite_master where type='table' AND name='census2016_sdhca_ot_ced_short';"""
                )
                assert count == 0

            r = cli_runner.invoke(["checkout", "main"])
            assert r.exit_code == 0, r.stderr

            with wc.session() as sess:
                count = sess.scalar(
                    f"""SELECT COUNT(name) FROM sqlite_master where type='table' AND name='census2016_sdhca_ot_ced_short';"""
                )
                assert count == 1
コード例 #2
0
def test_switch_with_trivial_schema_change(data_working_copy, cli_runner):
    # Column renames are one of the only schema changes we can do without having to recreate the whole table.
    with data_working_copy("points") as (repo_path, wc_path):
        wc = KartRepo(repo_path).working_copy
        with wc.session() as sess:
            sess.execute(
                f"""ALTER TABLE "{H.POINTS.LAYER}" RENAME "name_ascii" TO "name_latin1";"""
            )

        r = cli_runner.invoke(["commit", "-m", "change schema"])
        assert r.exit_code == 0, r.stderr
        r = cli_runner.invoke(["checkout", "HEAD^"])
        assert r.exit_code == 0, r.stderr
        with wc.session() as sess:
            name = sess.scalar(
                f"""SELECT name FROM pragma_table_info('{H.POINTS.LAYER}') WHERE cid = 3;"""
            )
            assert name == "name_ascii"

        r = cli_runner.invoke(["checkout", "main"])
        assert r.exit_code == 0, r.stderr
        with wc.session() as sess:
            name = sess.scalar(
                f"""SELECT name FROM pragma_table_info('{H.POINTS.LAYER}') WHERE cid = 3;"""
            )
            assert name == "name_latin1"
コード例 #3
0
def test_switch_with_meta_items(data_working_copy, cli_runner):
    with data_working_copy("points") as (repo_path, wc_path):
        wc = KartRepo(repo_path).working_copy
        with wc.session() as sess:
            sess.execute(
                """UPDATE gpkg_contents SET identifier = 'new identifier', description='new description'"""
            )

        r = cli_runner.invoke(
            ["commit", "-m", "change identifier and description"])
        assert r.exit_code == 0, r.stderr
        r = cli_runner.invoke(["checkout", "HEAD^"])
        assert r.exit_code == 0, r.stderr

        with wc.session() as sess:
            r = sess.execute(
                """SELECT identifier, description FROM gpkg_contents""")
            identifier, description = r.fetchone()
            assert identifier == "NZ Pa Points (Topo, 1:50k)"
            assert description.startswith("Defensive earthworks")

        r = cli_runner.invoke(["checkout", "main"])
        assert r.exit_code == 0, r.stderr

        with wc.session() as sess:
            r = sess.execute(
                """SELECT identifier, description FROM gpkg_contents""")
            identifier, description = r.fetchone()
            assert identifier == "new identifier"
            assert description == "new description"
コード例 #4
0
def test_geopackage_locking_edit(data_working_copy, cli_runner, monkeypatch):
    with data_working_copy("points") as (repo_path, wc_path):
        wc = KartRepo(repo_path).working_copy

        is_checked = False
        orig_func = BaseWorkingCopy._write_features

        def _wrap(*args, **kwargs):
            nonlocal is_checked
            if not is_checked:
                with pytest.raises(sqlalchemy.exc.OperationalError,
                                   match=r"database is locked"):
                    with wc.session() as sess:
                        sess.execute(
                            "UPDATE gpkg_contents SET table_name=table_name;")
                is_checked = True

            return orig_func(*args, **kwargs)

        monkeypatch.setattr(BaseWorkingCopy, "_write_features", _wrap)

        r = cli_runner.invoke(["checkout", H.POINTS.HEAD1_SHA])
        assert r.exit_code == 0, r
        assert is_checked

        with wc.session() as sess:
            assert H.last_change_time(sess) == "2019-06-11T11:03:58.000000Z"
コード例 #5
0
def test_switch_with_schema_change(data_working_copy, cli_runner):
    with data_working_copy("polygons") as (repo_path, wc_path):
        wc = KartRepo(repo_path).working_copy
        with wc.session() as sess:
            sess.execute(
                f"""ALTER TABLE "{H.POLYGONS.LAYER}" ADD COLUMN "colour" TEXT;"""
            )
        r = cli_runner.invoke(["commit", "-m", "change schema"])
        assert r.exit_code == 0, r.stderr
        r = cli_runner.invoke(["checkout", "HEAD^"])
        assert r.exit_code == 0, r.stderr
        with wc.session() as sess:
            r = sess.execute(
                f"""SELECT name, type FROM pragma_table_info('{H.POLYGONS.LAYER}');"""
            )
            result = list(r)
            assert result == [
                ("id", "INTEGER"),
                ("geom", "MULTIPOLYGON"),
                ("date_adjusted", "DATETIME"),
                ("survey_reference", "TEXT(50)"),
                ("adjusted_nodes", "MEDIUMINT"),
            ]

        r = cli_runner.invoke(["checkout", "main"])
        assert r.exit_code == 0, r.stderr
        with wc.session() as sess:
            r = sess.execute(
                f"""SELECT name, type FROM pragma_table_info('{H.POLYGONS.LAYER}');"""
            )
            result = list(r)
            assert result == [
                ("id", "INTEGER"),
                ("geom", "MULTIPOLYGON"),
                ("date_adjusted", "DATETIME"),
                ("survey_reference", "TEXT(50)"),
                ("adjusted_nodes", "MEDIUMINT"),
                ("colour", "TEXT"),
            ]
コード例 #6
0
def test_switch_xml_metadata_added(data_working_copy, cli_runner):
    with data_working_copy("table") as (repo_path, wc_path):
        wc = KartRepo(repo_path).working_copy
        with wc.session() as sess:
            sess.execute("""
                INSERT INTO gpkg_metadata (id, md_scope, md_standard_uri, mime_type, metadata)
                VALUES (1, "dataset", "http://www.isotc211.org/2005/gmd", "text/xml", "<test metadata>");
                """)
            sess.execute("""
                INSERT INTO gpkg_metadata_reference (reference_scope, table_name, md_file_id)
                VALUES ("table", "countiestbl", 1);
                """)

        r = cli_runner.invoke(["commit", "-m", "change xml metadata"])
        assert r.exit_code == 0, r.stderr
        r = cli_runner.invoke(["checkout", "HEAD^"])
        assert r.exit_code == 0, r.stderr

        with wc.session() as sess:
            xml_metadata = sess.execute("""
                SELECT m.metadata
                FROM gpkg_metadata m JOIN gpkg_metadata_reference r
                ON m.id = r.md_file_id
                WHERE r.table_name = 'countiestbl'
                """).fetchone()
            assert not xml_metadata

        r = cli_runner.invoke(["checkout", "main"])
        assert r.exit_code == 0, r.stderr

        with wc.session() as sess:
            xml_metadata = sess.execute("""
                SELECT m.metadata
                FROM gpkg_metadata m JOIN gpkg_metadata_reference r
                ON m.id = r.md_file_id
                WHERE r.table_name = 'countiestbl'
                """).scalar()
            assert xml_metadata == "<test metadata>"
コード例 #7
0
def test_reset_transaction(data_working_copy, cli_runner, edit_points):
    with data_working_copy("points") as (repo_path, wc_path):
        wc = KartRepo(repo_path).working_copy
        with wc.session() as sess:
            edit_points(sess)

        r = cli_runner.invoke(["status", "--output-format=json"])
        assert r.exit_code == 0, r
        changes = json.loads(
            r.stdout)["kart.status/v1"]["workingCopy"]["changes"]
        assert changes == {
            H.POINTS.LAYER: {
                "feature": {
                    "inserts": 1,
                    "updates": 2,
                    "deletes": 5
                }
            }
        }

        with wc.session() as sess:
            # This modification makes the gpkg_kart_state table work like normal for reading,
            # but writing to it will fail due to the CHECK.
            sess.execute(
                """ALTER TABLE "gpkg_kart_state" RENAME TO "gpkg_kart_state_backup";"""
            )
            value = sess.scalar("SELECT value FROM gpkg_kart_state_backup;")
            sess.execute(f"""
                CREATE TABLE "gpkg_kart_state"
                    ("table_name" TEXT NOT NULL, "key" TEXT NOT NULL, "value" TEXT NULL CHECK("value" = '{value}'));
                """)
            sess.execute(
                """INSERT INTO "gpkg_kart_state" SELECT * FROM "gpkg_kart_state_backup";"""
            )

        # This should fail and so the entire transaction should be rolled back.
        # Therefore, the GPKG should remain unchanged with 6 uncommitted changes -
        # even though the failed write to gpkg_kart_state happens after the changes
        # are discarded and after working copy is reset to the new commit - all of
        # that will be rolled back.
        with pytest.raises(sqlalchemy.exc.IntegrityError):
            r = cli_runner.invoke(["checkout", "HEAD^", "--discard-changes"])

        with wc.session() as sess:
            sess.execute("DROP TABLE IF EXISTS gpkg_kart_state;")
            sess.execute(
                """ALTER TABLE "gpkg_kart_state_backup" RENAME TO "gpkg_kart_state";"""
            )

        r = cli_runner.invoke(["status", "--output-format=json"])
        assert r.exit_code == 0, r.stderr
        changes = json.loads(
            r.stdout)["kart.status/v1"]["workingCopy"]["changes"]
        assert changes == {
            H.POINTS.LAYER: {
                "feature": {
                    "inserts": 1,
                    "updates": 2,
                    "deletes": 5
                }
            }
        }