-
Notifications
You must be signed in to change notification settings - Fork 1
/
block_sqlite.go
76 lines (65 loc) · 1.92 KB
/
block_sqlite.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package mtdb
import "database/sql"
type sqliteBlockRepository struct {
db *sql.DB
}
//https://bitbucket.org/s_l_teichmann/mtsatellite/src/e1bf980a2b278c570b3f44f9452c9c087558acb3/common/coords.go?at=default&fileviewer=file-view-default
const (
numBitsPerComponent = 12
modulo = 1 << numBitsPerComponent
maxPositive = modulo / 2
minValue = -1 << (numBitsPerComponent - 1)
maxValue = 1<<(numBitsPerComponent-1) - 1
MinPlainCoord = -34351347711
)
func CoordToPlain(x, y, z int) int64 {
return int64(z)<<(2*numBitsPerComponent) +
int64(y)<<numBitsPerComponent +
int64(x)
}
func unsignedToSigned(i int16) int {
if i < maxPositive {
return int(i)
}
return int(i - maxPositive*2)
}
// To match C++ code.
func pythonModulo(i int16) int16 {
const mask = modulo - 1
if i >= 0 {
return i & mask
}
return modulo - -i&mask
}
func PlainToCoord(i int64) (x, y, z int) {
x = unsignedToSigned(pythonModulo(int16(i)))
i = (i - int64(x)) >> numBitsPerComponent
y = unsignedToSigned(pythonModulo(int16(i)))
i = (i - int64(y)) >> numBitsPerComponent
z = unsignedToSigned(pythonModulo(int16(i)))
return x, y, z
}
func (repo *sqliteBlockRepository) GetByPos(x, y, z int) (*Block, error) {
pos := CoordToPlain(x, y, z)
rows, err := repo.db.Query("select pos,data from blocks where pos=$1", pos)
if err != nil {
return nil, err
}
if !rows.Next() {
return nil, nil
}
entry := &Block{}
err = rows.Scan(&pos, &entry.Data)
entry.PosX, entry.PosY, entry.PosZ = PlainToCoord(pos)
return entry, err
}
func (repo *sqliteBlockRepository) Update(block *Block) error {
pos := CoordToPlain(block.PosX, block.PosY, block.PosZ)
_, err := repo.db.Exec("replace into blocks(pos,data) values($1, $2)", pos, block.Data)
return err
}
func (repo *sqliteBlockRepository) Delete(x, y, z int) error {
pos := CoordToPlain(x, y, z)
_, err := repo.db.Exec("delete from blocks where pos=$1", pos)
return err
}