mtdb
This commit is contained in:
parent
06f44f717d
commit
e22e63967d
@ -45,6 +45,14 @@ Example:
|
|||||||
|
|
||||||
Prefer cbor+gzip for big imports. lzma is much slower than gzip but produces slightly smaller files. cbor is much smaller than json.
|
Prefer cbor+gzip for big imports. lzma is much slower than gzip but produces slightly smaller files. cbor is much smaller than json.
|
||||||
|
|
||||||
|
## Library
|
||||||
|
|
||||||
|
`mtdb.py` is a Python3 library for interacting with MineTest db.
|
||||||
|
|
||||||
|
import mtdb
|
||||||
|
db = mtdb.init_pgsql("host=127.0.0.1 port=5432 user=minetest password=PASSWORD dbname=minetest-world")
|
||||||
|
mtdb.get_chunk(db, (0,0,0)) # Chunk position, not node position (1 chunk = cube of 16*16*16 nodes)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
GNU AGPL 3.0
|
GNU AGPL 3.0
|
||||||
|
68
mtdb.py
Normal file
68
mtdb.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
DB_PGSQL = 1
|
||||||
|
DB_SQLITE = 2
|
||||||
|
|
||||||
|
class Db:
|
||||||
|
def __init__(self, obj, dbtype):
|
||||||
|
self.obj = obj
|
||||||
|
self.dbtype = dbtype
|
||||||
|
|
||||||
|
# Init PostgreSQL database
|
||||||
|
def init_pgsql(connect: str):
|
||||||
|
global psycopg2
|
||||||
|
import psycopg2
|
||||||
|
return Db(psycopg2.connect(connect), DB_PGSQL)
|
||||||
|
|
||||||
|
# Init SQLite database
|
||||||
|
def init_sqlite(dbname: str):
|
||||||
|
global sqlite3
|
||||||
|
import sqlite3
|
||||||
|
return Db(sqlite3.connect(dbname), DB_SQLITE)
|
||||||
|
|
||||||
|
def to_signed(x, bits=11):
|
||||||
|
return x if x >= 0 else (1<<bits)-x
|
||||||
|
|
||||||
|
def from_signed(x, bits=11):
|
||||||
|
b = 1<<bits
|
||||||
|
return x if x < b else (b^x)-b
|
||||||
|
|
||||||
|
def chunk_to_int(pos: (int, int, int)):
|
||||||
|
return to_signed(pos[2])<<24 | to_signed(pos[1])<<12 | to_signed(pos[0])
|
||||||
|
|
||||||
|
def int_to_chunk(pos: int):
|
||||||
|
return (from_signed(pos>>24), from_signed(pos>>12&0xfff), from_signed(pos&0xfff))
|
||||||
|
|
||||||
|
# Read chunk from db
|
||||||
|
def get_chunk(db: Db, pos: (int, int, int)):
|
||||||
|
if db.dbtype == DB_PGSQL:
|
||||||
|
c = db.obj.cursor()
|
||||||
|
c.execute("SELECT data FROM blocks WHERE posx={} AND posy={} AND posz={} LIMIT 1".format(*pos))
|
||||||
|
res = c.fetchone()
|
||||||
|
if res:
|
||||||
|
res = res[0].tobytes()
|
||||||
|
return res
|
||||||
|
else:
|
||||||
|
c = db.obj.cursor()
|
||||||
|
c.execute("SELECT data FROM blocks WHERE pos={} LIMIT 1".format(chunk_to_int(pos)))
|
||||||
|
res = c.fetchone()
|
||||||
|
if res:
|
||||||
|
res = res[0]
|
||||||
|
return res
|
||||||
|
|
||||||
|
# Write chunk to db
|
||||||
|
def set_chunk(db: Db, pos: (int, int, int), data: bytes):
|
||||||
|
if db.dbtype == DB_PGSQL:
|
||||||
|
c = db.obj.cursor()
|
||||||
|
c.execute("SELECT 1 FROM blocks WHERE posx={} AND posy={} AND posz={} LIMIT 1".format(*pos))
|
||||||
|
if c.fetchone():
|
||||||
|
c.execute("UPDATE blocks SET data={} WHERE posx={} AND posy={} AND posz={} LIMIT 1".format(data, *pos))
|
||||||
|
else:
|
||||||
|
c.execute("INSERT INTO blocks (posx, posy, posz, data) VALUES ({}, {}, {}, {})".format(*pos, data))
|
||||||
|
else:
|
||||||
|
chunk_id = chunk_to_int(pos)
|
||||||
|
c.execute("SELECT 1 FROM blocks WHERE pos={} LIMIT 1".format(chunk_id))
|
||||||
|
if c.fetchone():
|
||||||
|
c.execute("UPDATE blocks SET data={} WHERE pos={} LIMIT 1".format(data, chunk_id))
|
||||||
|
else:
|
||||||
|
c.execute("INSERT INTO blocks (pos, data) VALUES ({}, {})".format(chunk_id, data))
|
Loading…
x
Reference in New Issue
Block a user