128 lines
2.6 KiB
Go
128 lines
2.6 KiB
Go
|
package postgis
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"goposm/mapping"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
type ColumnSpec struct {
|
||
|
Name string
|
||
|
FieldType mapping.FieldType
|
||
|
Type ColumnType
|
||
|
}
|
||
|
type TableSpec struct {
|
||
|
Name string
|
||
|
Schema string
|
||
|
Columns []ColumnSpec
|
||
|
GeometryType string
|
||
|
Srid int
|
||
|
}
|
||
|
|
||
|
type GeneralizedTableSpec struct {
|
||
|
Name string
|
||
|
SourceName string
|
||
|
Source *TableSpec
|
||
|
SourceGeneralized *GeneralizedTableSpec
|
||
|
Tolerance float64
|
||
|
Where string
|
||
|
created bool
|
||
|
}
|
||
|
|
||
|
func (col *ColumnSpec) AsSQL() string {
|
||
|
return fmt.Sprintf("\"%s\" %s", col.Name, col.Type.Name())
|
||
|
}
|
||
|
|
||
|
func (spec *TableSpec) CreateTableSQL() string {
|
||
|
cols := []string{
|
||
|
"id SERIAL PRIMARY KEY",
|
||
|
}
|
||
|
for _, col := range spec.Columns {
|
||
|
if col.Type.Name() == "GEOMETRY" {
|
||
|
continue
|
||
|
}
|
||
|
cols = append(cols, col.AsSQL())
|
||
|
}
|
||
|
columnSQL := strings.Join(cols, ",\n")
|
||
|
return fmt.Sprintf(`
|
||
|
CREATE TABLE IF NOT EXISTS "%s"."%s" (
|
||
|
%s
|
||
|
);`,
|
||
|
spec.Schema,
|
||
|
spec.Name,
|
||
|
columnSQL,
|
||
|
)
|
||
|
}
|
||
|
|
||
|
func (spec *TableSpec) InsertSQL() string {
|
||
|
var cols []string
|
||
|
var vars []string
|
||
|
for _, col := range spec.Columns {
|
||
|
cols = append(cols, "\""+col.Name+"\"")
|
||
|
vars = append(vars,
|
||
|
col.Type.PrepareInsertSql(len(vars)+1, spec))
|
||
|
}
|
||
|
columns := strings.Join(cols, ", ")
|
||
|
placeholders := strings.Join(vars, ", ")
|
||
|
|
||
|
return fmt.Sprintf(`INSERT INTO "%s"."%s" (%s) VALUES (%s)`,
|
||
|
spec.Schema,
|
||
|
spec.Name,
|
||
|
columns,
|
||
|
placeholders,
|
||
|
)
|
||
|
}
|
||
|
|
||
|
func (spec *TableSpec) DeleteSQL() string {
|
||
|
var idColumName string
|
||
|
for _, col := range spec.Columns {
|
||
|
if col.FieldType.Name == "id" {
|
||
|
idColumName = col.Name
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if idColumName == "" {
|
||
|
panic("missing id column")
|
||
|
}
|
||
|
|
||
|
return fmt.Sprintf(`DELETE FROM "%s"."%s" WHERE "%s" = $1`,
|
||
|
spec.Schema,
|
||
|
spec.Name,
|
||
|
idColumName,
|
||
|
)
|
||
|
}
|
||
|
|
||
|
func NewTableSpec(pg *PostGIS, t *mapping.Table) *TableSpec {
|
||
|
spec := TableSpec{
|
||
|
Name: pg.Prefix + t.Name,
|
||
|
Schema: pg.Schema,
|
||
|
GeometryType: t.Type,
|
||
|
Srid: pg.Config.Srid,
|
||
|
}
|
||
|
for _, field := range t.Fields {
|
||
|
fieldType := field.FieldType()
|
||
|
if fieldType == nil {
|
||
|
continue
|
||
|
}
|
||
|
pgType, ok := pgTypes[fieldType.GoType]
|
||
|
if !ok {
|
||
|
log.Errorf("unhandled field type %v, using string type", fieldType)
|
||
|
pgType = pgTypes["string"]
|
||
|
}
|
||
|
col := ColumnSpec{field.Name, *fieldType, pgType}
|
||
|
spec.Columns = append(spec.Columns, col)
|
||
|
}
|
||
|
return &spec
|
||
|
}
|
||
|
|
||
|
func NewGeneralizedTableSpec(pg *PostGIS, t *mapping.GeneralizedTable) *GeneralizedTableSpec {
|
||
|
spec := GeneralizedTableSpec{
|
||
|
Name: pg.Prefix + t.Name,
|
||
|
Tolerance: t.Tolerance,
|
||
|
Where: t.SqlFilter,
|
||
|
SourceName: t.SourceTableName,
|
||
|
}
|
||
|
return &spec
|
||
|
}
|