142 lines
2.9 KiB
Go
142 lines
2.9 KiB
Go
package postgis
|
|
|
|
import (
|
|
"fmt"
|
|
"imposm3/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) CopySQL() string {
|
|
var cols []string
|
|
for _, col := range spec.Columns {
|
|
cols = append(cols, "\""+col.Name+"\"")
|
|
}
|
|
columns := strings.Join(cols, ", ")
|
|
|
|
return fmt.Sprintf(`COPY "%s"."%s" (%s) FROM STDIN`,
|
|
spec.Schema,
|
|
spec.Name,
|
|
columns,
|
|
)
|
|
}
|
|
|
|
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
|
|
}
|