1
0
forked from MTSR/mapserver

mapobject search by key/value on attribute support

This commit is contained in:
Thomas Rudin 2019-04-14 21:13:59 +02:00
parent afbaf97f6a
commit 950bf53c88
6 changed files with 146 additions and 13 deletions

View File

@ -57,11 +57,17 @@ func NewMapObject(MBPos *coords.MapBlockCoords, x int, y int, z int, _type strin
return &o
}
type SearchAttributeLike struct {
Key string `json:"key"`
Value string `json:"value"`
}
type SearchQuery struct {
//mapblock position
Pos1 *coords.MapBlockCoords `json:"pos1"`
Pos2 *coords.MapBlockCoords `json:"pos2"`
Type string `json:"type"`
Pos1 *coords.MapBlockCoords `json:"pos1"`
Pos2 *coords.MapBlockCoords `json:"pos2"`
Type string `json:"type"`
AttributeLike *SearchAttributeLike `json:"attributelike"`
}
type DBAccessor interface {

View File

@ -1,16 +1,33 @@
package postgres
import (
"database/sql"
"mapserver/coords"
"mapserver/mapobjectdb"
)
func (db *PostgresAccessor) GetMapData(q *mapobjectdb.SearchQuery) ([]*mapobjectdb.MapObject, error) {
rows, err := db.db.Query(getMapDataPosQuery,
q.Type,
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
)
var rows *sql.Rows
var err error
if q.AttributeLike == nil {
//plain pos search
rows, err = db.db.Query(getMapDataPosQuery,
q.Type,
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
)
} else {
//attribute like search
rows, err = db.db.Query(getMapDataWithAttributeLikePosQuery,
q.Type,
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
q.AttributeLike.Key, q.AttributeLike.Value,
)
}
if err != nil {
return nil, err

View File

@ -12,6 +12,21 @@ and o.posx >= $2 and o.posy >= $3 and o.posz >= $4
and o.posx <= $5 and o.posy <= $6 and o.posz <= $7
order by o.id
`
const getMapDataWithAttributeLikePosQuery = `
select o.id, o.type, o.mtime,
o.x, o.y, o.z,
o.posx, o.posy, o.posz,
oa.key, oa.value
from objects o
left join object_attributes oa on o.id = oa.objectid
where o.id in (
select objectid from object_attributes where key = $8 and value like $9
)
and o.type = $1
and o.posx >= $2 and o.posy >= $3 and o.posz >= $4
and o.posx <= $5 and o.posy <= $6 and o.posz <= $7
order by o.id
`
const removeMapDataQuery = `
delete from objects where posx = $1 and posy = $2 and posz = $3

View File

@ -1,16 +1,33 @@
package sqlite
import (
"database/sql"
"mapserver/coords"
"mapserver/mapobjectdb"
)
func (db *Sqlite3Accessor) GetMapData(q *mapobjectdb.SearchQuery) ([]*mapobjectdb.MapObject, error) {
rows, err := db.db.Query(getMapDataPosQuery,
q.Type,
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
)
var rows *sql.Rows
var err error
if q.AttributeLike == nil {
//plain pos search
rows, err = db.db.Query(getMapDataPosQuery,
q.Type,
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
)
} else {
//attribute like search
rows, err = db.db.Query(getMapDataWithAttributeLikePosQuery,
q.AttributeLike.Key, q.AttributeLike.Value,
q.Type,
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
)
}
if err != nil {
return nil, err

View File

@ -82,3 +82,65 @@ func TestMapObjects(t *testing.T) {
}
}
func TestMapObjectsQueryWithAttribute(t *testing.T) {
tmpfile, err := ioutil.TempFile("", "TestMapObjects.*.sqlite")
if err != nil {
panic(err)
}
//defer os.Remove(tmpfile.Name())
db, err := New(tmpfile.Name())
if err != nil {
panic(err)
}
err = db.Migrate()
if err != nil {
panic(err)
}
attrs := make(map[string]string)
attrs["X"] = "y"
pos := coords.NewMapBlockCoords(0, 0, 0)
o := mapobjectdb.MapObject{
MBPos: pos,
X: 15,
Y: 15,
Z: 15,
Type: "xy",
Mtime: 1234,
Attributes: attrs,
}
err = db.AddMapData(&o)
if err != nil {
panic(err)
}
q := mapobjectdb.SearchQuery{
Pos1: pos,
Pos2: pos,
Type: "xy",
AttributeLike: &mapobjectdb.SearchAttributeLike{
Key: "X",
Value: "%y",
},
}
objs, err := db.GetMapData(&q)
if err != nil {
panic(err)
}
for _, mo := range objs {
fmt.Println(mo)
}
if len(objs) != 1 {
panic("length mismatch")
}
}

View File

@ -13,6 +13,22 @@ and o.posx <= ? and o.posy <= ? and o.posz <= ?
order by o.id
`
const getMapDataWithAttributeLikePosQuery = `
select o.id, o.type, o.mtime,
o.x, o.y, o.z,
o.posx, o.posy, o.posz,
oa.key, oa.value
from objects o
left join object_attributes oa on o.id = oa.objectid
where o.id in (
select objectid from object_attributes where key = ? and value like ?
)
and o.type = ?
and o.posx >= ? and o.posy >= ? and o.posz >= ?
and o.posx <= ? and o.posy <= ? and o.posz <= ?
order by o.id
`
const removeMapDataQuery = `
delete from objects where posx = ? and posy = ? and posz = ?
`