mirror of
https://github.com/rbreu/beeref.git
synced 2026-03-11 08:54:28 +00:00
Make bee file sqlar compliant
This commit is contained in:
parent
ef086f1468
commit
e42ed2d598
5 changed files with 64 additions and 39 deletions
|
|
@ -27,3 +27,5 @@ Run unittests with coverage report::
|
|||
coverage html
|
||||
|
||||
If your browser doesn't open automatically, view ``htmlcov/index.html``.
|
||||
|
||||
Beeref files are sqlite databases, so they can be inspected with any sqlite browser.
|
||||
|
|
|
|||
12
README.rst
12
README.rst
|
|
@ -24,6 +24,18 @@ At the moment, you need to have a working Python 3 environment to install BeeRef
|
|||
Then run ``beeref`` or ``beeref filename.bee``.
|
||||
|
||||
|
||||
Regarding the bee file format
|
||||
-----------------------------
|
||||
|
||||
Currently, all images are embedded into the bee file as png files. While png is a lossless format, it may also produce larger file sizes than compressed jpg files, so bee files may become bigger than the imported images. More embedding options are to come later.
|
||||
|
||||
The bee file format is a sqlite database inside which the images are stored in an sqlar table—meaning they can be extracted with the `sqlite command line program <https://www.sqlite.org/cli.html>`_::
|
||||
|
||||
sqlite3 myfile.bee -Axv
|
||||
|
||||
Options for exporting from inside BeeRef are planned, but the above always works independently of BeeRef.
|
||||
|
||||
|
||||
Notes for developers
|
||||
--------------------
|
||||
|
||||
|
|
|
|||
29
beeref/fileio/schema.py
Normal file
29
beeref/fileio/schema.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
SCHEMA = [
|
||||
"""
|
||||
CREATE TABLE items (
|
||||
id INTEGER PRIMARY KEY,
|
||||
type TEXT NOT NULL,
|
||||
pos_x REAL DEFAULT 0,
|
||||
pos_y REAL DEFAULT 0,
|
||||
scale REAL DEFAULT 1,
|
||||
rotation REAL DEFAULT 0,
|
||||
flip_h INTEGER DEFAULT 0,
|
||||
flip_v INTEGER DEFAULT 0,
|
||||
filename TEXT
|
||||
)
|
||||
""",
|
||||
"""
|
||||
CREATE TABLE sqlar (
|
||||
name TEXT PRIMARY KEY,
|
||||
item_id INTEGER NOT NULL,
|
||||
mode INT,
|
||||
mtime INT default current_timestamp,
|
||||
sz INT,
|
||||
data BLOB,
|
||||
FOREIGN KEY (item_id)
|
||||
REFERENCES items (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
)
|
||||
""",
|
||||
]
|
||||
|
|
@ -13,9 +13,14 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with BeeRef. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
"""BeeRef's native file format is using SQLite. For more info, see:
|
||||
"""BeeRef's native file format is using SQLite. Embedded files are
|
||||
stored in an sqlar table so that they can be extracted using sqlite's
|
||||
archive command line option.
|
||||
|
||||
For more info, see:
|
||||
|
||||
https://www.sqlite.org/appfileformat.html
|
||||
https://www.sqlite.org/sqlar.html
|
||||
"""
|
||||
|
||||
import os
|
||||
|
|
@ -24,34 +29,7 @@ import sqlite3
|
|||
from PyQt6 import QtGui
|
||||
|
||||
from beeref.items import BeePixmapItem
|
||||
|
||||
|
||||
SCHEMA = [
|
||||
"""
|
||||
CREATE TABLE items (
|
||||
id INTEGER PRIMARY KEY,
|
||||
type TEXT NOT NULL,
|
||||
pos_x REAL DEFAULT 0,
|
||||
pos_y REAL DEFAULT 0,
|
||||
scale REAL DEFAULT 1,
|
||||
rotation REAL DEFAULT 0,
|
||||
flip_h INTEGER DEFAULT 0,
|
||||
flip_v INTEGER DEFAULT 0,
|
||||
filename TEXT
|
||||
)
|
||||
""",
|
||||
"""
|
||||
CREATE TABLE imgdata (
|
||||
id INTEGER PRIMARY KEY,
|
||||
item_id INTEGER NOT NULL,
|
||||
data BLOB,
|
||||
FOREIGN KEY (item_id)
|
||||
REFERENCES items (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
)
|
||||
""",
|
||||
]
|
||||
from .schema import SCHEMA
|
||||
|
||||
|
||||
class SQLiteIO:
|
||||
|
|
@ -94,9 +72,9 @@ class SQLiteIO:
|
|||
|
||||
def read(self):
|
||||
rows = self.fetchall(
|
||||
'SELECT pos_x, pos_y, scale, filename, imgdata.data, items.id '
|
||||
'SELECT pos_x, pos_y, scale, filename, sqlar.data, items.id '
|
||||
'FROM items '
|
||||
'INNER JOIN imgdata on imgdata.item_id = items.id')
|
||||
'INNER JOIN sqlar on sqlar.item_id = items.id')
|
||||
for row in rows:
|
||||
item = BeePixmapItem(QtGui.QImage(), filename=row[3])
|
||||
item.save_id = row[5]
|
||||
|
|
@ -130,8 +108,12 @@ class SQLiteIO:
|
|||
('pixmap', item.pos().x(), item.pos().y(), item.scale_factor,
|
||||
item.filename))
|
||||
item.save_id = self.cursor.lastrowid
|
||||
self.ex('INSERT INTO imgdata (item_id, data) VALUES (?, ?)',
|
||||
(item.save_id, item.pixmap_to_bytes()))
|
||||
pixmap = item.pixmap_to_bytes()
|
||||
name = '%04d.png' % item.save_id
|
||||
self.ex(
|
||||
'INSERT INTO sqlar (item_id, name, mode, sz, data) '
|
||||
'VALUES (?, ?, 644, ?, ?)',
|
||||
(item.save_id, name, len(pixmap), pixmap))
|
||||
self.connection.commit()
|
||||
|
||||
def update_item(self, item):
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@ class SQLiteIOWriteTestCase(BeeTestCase):
|
|||
|
||||
assert item.save_id == 1
|
||||
result = self.io.fetchone(
|
||||
'SELECT pos_x, pos_y, scale, filename, imgdata.data, type '
|
||||
'SELECT pos_x, pos_y, scale, filename, sqlar.data, type '
|
||||
'FROM items '
|
||||
'INNER JOIN imgdata on imgdata.item_id = items.id')
|
||||
'INNER JOIN sqlar on sqlar.item_id = items.id')
|
||||
assert result[0] == 44.0
|
||||
assert result[1] == 55.0
|
||||
assert result[2] == 1.3
|
||||
|
|
@ -103,9 +103,9 @@ class SQLiteIOWriteTestCase(BeeTestCase):
|
|||
|
||||
assert self.io.fetchone('SELECT COUNT(*) from items') == (1,)
|
||||
result = self.io.fetchone(
|
||||
'SELECT pos_x, pos_y, scale, filename, imgdata.data '
|
||||
'SELECT pos_x, pos_y, scale, filename, sqlar.data '
|
||||
'FROM items '
|
||||
'INNER JOIN imgdata on imgdata.item_id = items.id')
|
||||
'INNER JOIN sqlar on sqlar.item_id = items.id')
|
||||
assert result[0] == 20
|
||||
assert result[1] == 30
|
||||
assert result[2] == 0.7
|
||||
|
|
@ -124,7 +124,7 @@ class SQLiteIOWriteTestCase(BeeTestCase):
|
|||
self.io.write()
|
||||
|
||||
assert self.io.fetchone('SELECT COUNT(*) from items') == (0,)
|
||||
assert self.io.fetchone('SELECT COUNT(*) from imgdata') == (0,)
|
||||
assert self.io.fetchone('SELECT COUNT(*) from sqlar') == (0,)
|
||||
|
||||
|
||||
class SQLiteIOLOadTestCase(BeeTestCase):
|
||||
|
|
@ -143,7 +143,7 @@ class SQLiteIOLOadTestCase(BeeTestCase):
|
|||
'INSERT INTO items (type, pos_x, pos_y, scale, filename) '
|
||||
'VALUES (?, ?, ?, ?, ?) ',
|
||||
('pixmap', 22.2, 33.3, 3.4, 'bee.png'))
|
||||
self.io.ex('INSERT INTO imgdata (item_id, data) VALUES (?, ?)',
|
||||
self.io.ex('INSERT INTO sqlar (item_id, data) VALUES (?, ?)',
|
||||
(1, imgdata))
|
||||
self.io.read()
|
||||
assert len(self.scene.items()) == 1
|
||||
|
|
|
|||
Loading…
Reference in a new issue