#include "spatialite/geopackage.h"
#include "spatialite/gaiaaux.h"
#include "config.h"
#include "geopackage_internal.h"
#ifdef ENABLE_GEOPACKAGE
GEOPACKAGE_PRIVATE void
fnct_gpkgAddGeometryTriggers (sqlite3_context * context, int argc
__attribute__ ((unused)), sqlite3_value ** argv)
{
const char *table;
const char *column;
char *xtable;
char *xcolumn;
char *sql_stmt = NULL;
sqlite3 *sqlite = NULL;
char *errMsg = NULL;
int ret = 0;
int i = 0;
const char *trigger_stmts[] = {
"CREATE TRIGGER \"fgti_%s_%s\"\n"
"BEFORE INSERT ON \"%s\"\n"
"FOR EACH ROW BEGIN\n"
"SELECT RAISE (ROLLBACK, 'insert on \"%s\" violates constraint: "
"ST_GeometryType(\"%s\") is not assignable from "
"gpkg_geometry_columns.geometry_type_name value')\n"
"WHERE (SELECT geometry_type_name\n"
"FROM gpkg_geometry_columns\n"
"WHERE Lower(table_name) = Lower(%Q)\n"
"AND Lower(column_name) = Lower(%Q)\n"
"AND gpkg_IsAssignable(geometry_type_name, "
"ST_GeometryType(NEW.\"%s\")) = 0);\nEND",
"CREATE TRIGGER \"fgtu_%s_%s\"\n"
"BEFORE UPDATE OF \"%s\" ON \"%s\"\n"
"FOR EACH ROW BEGIN\n"
"SELECT RAISE (ROLLBACK, 'update of \"%s\" on \"%s\" violates constraint: "
"ST_GeometryType(\"%s\") is not assignable from "
"gpkg_geometry_columns.geometry_type_name value')\n"
"WHERE (SELECT geometry_type_name\n"
"FROM gpkg_geometry_columns\n"
"WHERE Lower(table_name) = Lower(%Q) "
"AND Lower(column_name) = Lower(%Q) "
"AND gpkg_IsAssignable(geometry_type_name, "
"ST_GeometryType(NEW.\"%s\")) = 0);\nEND",
"CREATE TRIGGER \"fgsi_%s_%s\"\n"
"BEFORE INSERT ON \"%s\"\n"
"FOR EACH ROW BEGIN\n"
"SELECT RAISE (ROLLBACK, 'insert on \"%s\" violates constraint: "
"ST_SRID(\"%s\") does not match gpkg_geometry_columns.srs_id value')\n"
"WHERE (SELECT srs_id FROM gpkg_geometry_columns\n"
"WHERE Lower(table_name) = Lower(%Q) "
"AND Lower(column_name) = Lower(%Q) "
"AND ST_SRID(NEW.\"%s\") <> srs_id);\nEND",
"CREATE TRIGGER \"fgsu_%s_%s\"\n"
"BEFORE UPDATE OF \"%s\" ON \"%s\"\n"
"FOR EACH ROW BEGIN\n"
"SELECT RAISE (ROLLBACK, 'update of \"%s\" on \"%s\" violates constraint: "
"ST_SRID(\"%s\") does not match gpkg_geometry_columns.srs_id value')\n"
"WHERE (SELECT srs_id FROM gpkg_geometry_columns\n"
"WHERE Lower(table_name) = Lower(%Q) "
"AND Lower(column_name) = Lower(%Q) "
"AND ST_SRID(NEW.\"%s\") <> srs_id);\nEND",
NULL
};
if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
{
sqlite3_result_error (context,
"gpkgAddGeometryTriggers() error: argument 1 [table] is not of the String type",
-1);
return;
}
if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
{
sqlite3_result_error (context,
"gpkgAddGeometryTriggers() error: argument 2 [column] is not of the String type",
-1);
return;
}
table = (const char *) sqlite3_value_text (argv[0]);
column = (const char *) sqlite3_value_text (argv[1]);
xtable = gaiaDoubleQuotedSql (table);
xcolumn = gaiaDoubleQuotedSql (column);
sqlite = sqlite3_context_db_handle (context);
for (i = 0; i < 4; i++)
{
if (i == 0 || i == 2)
sql_stmt =
sqlite3_mprintf (trigger_stmts[i], xtable, xcolumn, xtable,
table, xcolumn, column, column, xcolumn);
else
sql_stmt =
sqlite3_mprintf (trigger_stmts[i], xtable, xcolumn, xcolumn,
xtable, table, column, xcolumn, column,
column, xcolumn);
ret = sqlite3_exec (sqlite, sql_stmt, NULL, NULL, &errMsg);
sqlite3_free (sql_stmt);
if (ret != SQLITE_OK)
{
sqlite3_result_error (context, errMsg, -1);
sqlite3_free (errMsg);
free (xtable);
free (xcolumn);
return;
}
}
free (xtable);
free (xcolumn);
sql_stmt = sqlite3_mprintf ("INSERT INTO gpkg_extensions "
"(table_name, column_name, extension_name, definition, scope) "
"VALUES (Lower(%Q), Lower(%Q), 'gpkg_geometry_type_trigger', "
"'GeoPackage 1.0 Specification Annex N', 'write-only')",
table, column);
ret = sqlite3_exec (sqlite, sql_stmt, NULL, NULL, &errMsg);
sqlite3_free (sql_stmt);
if (ret != SQLITE_OK)
{
sqlite3_result_error (context, errMsg, -1);
sqlite3_free (errMsg);
return;
}
sql_stmt = sqlite3_mprintf ("INSERT INTO gpkg_extensions "
"(table_name, column_name, extension_name, definition, scope) "
"VALUES (Lower(%Q), Lower(%Q), 'gpkg_srs_id_trigger', "
"'GeoPackage 1.0 Specification Annex N', 'write-only')",
table, column);
ret = sqlite3_exec (sqlite, sql_stmt, NULL, NULL, &errMsg);
sqlite3_free (sql_stmt);
if (ret != SQLITE_OK)
{
sqlite3_result_error (context, errMsg, -1);
sqlite3_free (errMsg);
return;
}
}
#endif