diff --git a/src/main/java/mil/nga/geopackage/GeoPackageCore.java b/src/main/java/mil/nga/geopackage/GeoPackageCore.java index fa9bd9c9..e1d16ba2 100644 --- a/src/main/java/mil/nga/geopackage/GeoPackageCore.java +++ b/src/main/java/mil/nga/geopackage/GeoPackageCore.java @@ -15,6 +15,7 @@ import mil.nga.geopackage.db.GeoPackageTableCreator; import mil.nga.geopackage.extension.ExtensionManager; import mil.nga.geopackage.extension.ExtensionsDao; +import mil.nga.geopackage.extension.schema.SchemaExtension; import mil.nga.geopackage.features.columns.GeometryColumnsDao; import mil.nga.geopackage.features.user.FeatureTable; import mil.nga.geopackage.features.user.FeatureTableMetadata; @@ -1022,4 +1023,13 @@ public AttributesTable createAttributesTable( */ public void createUserTable(UserTable table); + /** + * Save the table schema using the {@link SchemaExtension} + * + * @param table + * user table + * @since 6.6.7 + */ + public void saveSchema(UserTable table); + } diff --git a/src/main/java/mil/nga/geopackage/GeoPackageCoreImpl.java b/src/main/java/mil/nga/geopackage/GeoPackageCoreImpl.java index e3ebe813..70eef6cc 100644 --- a/src/main/java/mil/nga/geopackage/GeoPackageCoreImpl.java +++ b/src/main/java/mil/nga/geopackage/GeoPackageCoreImpl.java @@ -24,6 +24,8 @@ import mil.nga.geopackage.extension.ExtensionManager; import mil.nga.geopackage.extension.Extensions; import mil.nga.geopackage.extension.ExtensionsDao; +import mil.nga.geopackage.extension.schema.SchemaExtension; +import mil.nga.geopackage.extension.schema.columns.DataColumnsDao; import mil.nga.geopackage.features.columns.GeometryColumns; import mil.nga.geopackage.features.columns.GeometryColumnsDao; import mil.nga.geopackage.features.user.FeatureTable; @@ -907,6 +909,8 @@ public FeatureTable createFeatureTable(FeatureTableMetadata metadata) { geometryColumns.setContents(contents); getGeometryColumnsDao().create(geometryColumns); + saveSchema(table); + } catch (RuntimeException e) { deleteTableQuietly(tableName); throw e; @@ -1040,6 +1044,8 @@ public TileTable createTileTable(TileTableMetadata metadata) { tileMatrixSet.setMaxY(tileMatrixSetBoundingBox.getMaxLatitude()); getTileMatrixSetDao().create(tileMatrixSet); + saveSchema(table); + } catch (RuntimeException e) { deleteTableQuietly(tableName); throw e; @@ -1118,6 +1124,8 @@ public AttributesTable createAttributesTable( table.setContents(contents); + saveSchema(table); + } catch (RuntimeException e) { deleteTableQuietly(tableName); throw e; @@ -1591,4 +1599,23 @@ public void createUserTable(UserTable table) { tableCreator.createTable(table); } + /** + * {@inheritDoc} + */ + @Override + public void saveSchema(UserTable table) { + if (table.hasSchema()) { + SchemaExtension schemaExtension = new SchemaExtension(this); + DataColumnsDao dataColumnsDao = schemaExtension.getDataColumnsDao(); + try { + dataColumnsDao.saveSchema(table); + } catch (SQLException e) { + throw new GeoPackageException( + "Failed to save schema for table: " + + table.getTableName(), + e); + } + } + } + } diff --git a/src/main/java/mil/nga/geopackage/dgiwg/DGIWGGeoPackageUtils.java b/src/main/java/mil/nga/geopackage/dgiwg/DGIWGGeoPackageUtils.java index 6b8cbec0..257ccbbb 100644 --- a/src/main/java/mil/nga/geopackage/dgiwg/DGIWGGeoPackageUtils.java +++ b/src/main/java/mil/nga/geopackage/dgiwg/DGIWGGeoPackageUtils.java @@ -117,6 +117,8 @@ public static TileMatrixSet createTiles(GeoPackageCore geoPackage, + tileMatrixSet.getTableName(), e); } + geoPackage.saveSchema(tileTable); + return tileMatrixSet; } @@ -376,6 +378,8 @@ public static GeometryColumns createFeatures(GeoPackageCore geoPackage, + geometryColumns.getTableName(), e); } + geoPackage.saveSchema(featureTable); + return geometryColumns; } diff --git a/src/main/java/mil/nga/geopackage/extension/related/RelatedTablesCoreExtension.java b/src/main/java/mil/nga/geopackage/extension/related/RelatedTablesCoreExtension.java index 6b9fa556..9af3822b 100644 --- a/src/main/java/mil/nga/geopackage/extension/related/RelatedTablesCoreExtension.java +++ b/src/main/java/mil/nga/geopackage/extension/related/RelatedTablesCoreExtension.java @@ -952,6 +952,8 @@ public boolean createRelatedTable( relatedTable.setContents(contents); + geoPackage.saveSchema(relatedTable); + } catch (RuntimeException e) { geoPackage.deleteTableQuietly(relatedTableName); throw e; diff --git a/src/main/java/mil/nga/geopackage/extension/schema/SchemaExtension.java b/src/main/java/mil/nga/geopackage/extension/schema/SchemaExtension.java index f42d62a6..dae5ac0b 100644 --- a/src/main/java/mil/nga/geopackage/extension/schema/SchemaExtension.java +++ b/src/main/java/mil/nga/geopackage/extension/schema/SchemaExtension.java @@ -64,6 +64,10 @@ public SchemaExtension(GeoPackageCore geoPackage) { */ public List getOrCreate() { + // Create tables + createDataColumnConstraintsTable(); + createDataColumnsTable(); + List extensions = new ArrayList<>(); extensions.add(getOrCreate(EXTENSION_NAME, DataColumns.TABLE_NAME, null, @@ -166,6 +170,10 @@ public boolean createDataColumnsTable() { try { if (!dao.isTableExists()) { created = geoPackage.getTableCreator().createDataColumns() > 0; + if (created) { + // Create the schema extension record + createDataColumnsRecord(); + } } } catch (SQLException e) { throw new GeoPackageException( @@ -176,6 +184,17 @@ public boolean createDataColumnsTable() { return created; } + /** + * Create the Data Columns extension record if it does not already exist + * + * @return extension + * @since 6.6.7 + */ + public Extensions createDataColumnsRecord() { + return getOrCreate(EXTENSION_NAME, DataColumns.TABLE_NAME, null, + DEFINITION, ExtensionScopeType.READ_WRITE); + } + /** * Get a Data Column Constraints DAO * @@ -231,7 +250,7 @@ public boolean createDataColumnConstraintsTable() { .createDataColumnConstraints() > 0; if (created) { // Create the schema extension record - getOrCreate(); + createDataColumnConstraintsRecord(); } } } catch (SQLException e) { @@ -242,4 +261,16 @@ public boolean createDataColumnConstraintsTable() { return created; } + /** + * Create the Data Column Constraints extension record if it does not + * already exist + * + * @return extension + * @since 6.6.7 + */ + public Extensions createDataColumnConstraintsRecord() { + return getOrCreate(EXTENSION_NAME, DataColumnConstraints.TABLE_NAME, + null, DEFINITION, ExtensionScopeType.READ_WRITE); + } + } diff --git a/src/main/java/mil/nga/geopackage/extension/schema/columns/DataColumnsDao.java b/src/main/java/mil/nga/geopackage/extension/schema/columns/DataColumnsDao.java index cc2dc6ed..7f39902b 100644 --- a/src/main/java/mil/nga/geopackage/extension/schema/columns/DataColumnsDao.java +++ b/src/main/java/mil/nga/geopackage/extension/schema/columns/DataColumnsDao.java @@ -17,6 +17,7 @@ import mil.nga.geopackage.contents.ContentsDao; import mil.nga.geopackage.db.GeoPackageCoreConnection; import mil.nga.geopackage.db.GeoPackageDao; +import mil.nga.geopackage.db.GeoPackageTableCreator; import mil.nga.geopackage.db.TableColumnKey; import mil.nga.geopackage.user.UserColumn; import mil.nga.geopackage.user.UserColumns; @@ -372,6 +373,9 @@ public void saveSchema(String table, UserColumn column) schema.setContents(contents); } if (schema.getContents() != null) { + if (!isTableExists()) { + getTableCreator().createDataColumns(); + } createOrUpdate(schema); } @@ -477,6 +481,15 @@ public DataColumns getSchema(String table, String column) return schema; } + /** + * Get the Table Creator + * + * @return table creator + */ + private GeoPackageTableCreator getTableCreator() { + return new GeoPackageTableCreator(db); + } + /** * Get or create a Contents DAO * diff --git a/src/main/java/mil/nga/geopackage/user/UserColumn.java b/src/main/java/mil/nga/geopackage/user/UserColumn.java index db844000..d186cdad 100644 --- a/src/main/java/mil/nga/geopackage/user/UserColumn.java +++ b/src/main/java/mil/nga/geopackage/user/UserColumn.java @@ -962,8 +962,8 @@ public String buildConstraintSql(Constraint constraint) { } /** - * Get the data columns schema. Not saved as part of the column, loaded - * using {@link DataColumnsDao}. + * Get the in-memory data columns schema. Not saved as part of the column, + * loaded using {@link DataColumnsDao}. * * @return column schema or null * @since 6.6.7 @@ -972,6 +972,16 @@ public DataColumns getSchema() { return schema; } + /** + * Check if the column has an in-memory data columns schema + * + * @return true if has column schema + * @since 6.6.7 + */ + public boolean hasSchema() { + return schema != null; + } + /** * Set the data columns schema. Not saved as part of the column, saved using * {@link DataColumnsDao}. diff --git a/src/main/java/mil/nga/geopackage/user/UserColumns.java b/src/main/java/mil/nga/geopackage/user/UserColumns.java index 7b8185fa..607ecd3c 100644 --- a/src/main/java/mil/nga/geopackage/user/UserColumns.java +++ b/src/main/java/mil/nga/geopackage/user/UserColumns.java @@ -611,4 +611,23 @@ public void alterColumn(TColumn column) { columns.set(column.getIndex(), column); } + /** + * Check if any columns have an in-memory data columns schema + * + * @return true if has a column schema + * @since 6.6.7 + */ + public boolean hasSchema() { + boolean schema = false; + if (columns != null) { + for (TColumn column : columns) { + schema = column.hasSchema(); + if (schema) { + break; + } + } + } + return schema; + } + } diff --git a/src/main/java/mil/nga/geopackage/user/UserTable.java b/src/main/java/mil/nga/geopackage/user/UserTable.java index 9b171c87..24054af0 100644 --- a/src/main/java/mil/nga/geopackage/user/UserTable.java +++ b/src/main/java/mil/nga/geopackage/user/UserTable.java @@ -579,4 +579,14 @@ public void alterColumn(TColumn column) { columns.alterColumn(column); } + /** + * Check if any columns have an in-memory data columns schema + * + * @return true if has a column schema + * @since 6.6.7 + */ + public boolean hasSchema() { + return columns != null && columns.hasSchema(); + } + }