Tweak things, add vacuum command.

This commit is contained in:
random-geek 2020-07-03 23:37:06 -07:00
parent ba90b7c667
commit 3f2e07adbc
3 changed files with 68 additions and 23 deletions

View File

@ -16,14 +16,16 @@ To install, run:
```
pip install --upgrade setuptools
pip install https://github.com/random-geek/MapEdit/archive/master.zip
pip install --upgrade https://github.com/random-geek/MapEdit/archive/master.zip
```
This will install MapEdit as a script/executable which can be run from anywhere.
This is the easiest way to install, as it will download the latest code directly from the repository.
This is the easiest way to install, as it will download the latest code directly from the repository.
If you wish to install from a downloaded copy instead, install `setuptools` as usual, then run `python setup.py install` in the project directory.
You may also be prompted to add a directory to PATH. If so, follow instructions for your operating system on how to do this.
## Usage
#### About mapblocks
@ -206,6 +208,18 @@ Arguments:
- **`--p1, --p2`**: Area in which to delete objects. If not specified, objects will be deleted across the entire map.
- **`--invert`**: Only delete objects *outside* the given area.
### `vacuum`
**Usage:** `vacuum`
Vacuums the database. This reduces the size of the database, but may take a long time.
All this does is perform an SQLite `VACUUM` command. This shrinks and optimizes the database by efficiently "repacking" all mapblocks.
No map data is changed or deleted.
**Note:** Because data is copied into another file, this command could require as much free disk space as is already occupied by the map.
For example, if your database is 10 GB, make sure you have **at least 10 GB** of free space!
## Acknowledgments
Some of the code for this project was inspired by code from the [map_unexplore](https://github.com/AndrejIT/map_unexplore) project by AndrejIT. All due credit goes to the author(s) of that project.

View File

@ -545,7 +545,7 @@ def replace_in_inv(inst, args):
inst.db.set_block(key, block.serialize())
#
# deletetimers
# deletetimers command
#
def delete_timers(inst, args):
@ -591,7 +591,7 @@ def delete_timers(inst, args):
inst.db.set_block(key, block.serialize())
#
# deleteobjects
# deleteobjects command
#
def delete_objects(inst, args):
@ -639,6 +639,18 @@ def delete_objects(inst, args):
block.serialize_static_objects(objList)
inst.db.set_block(key, block.serialize())
#
# vacuum command
#
def vacuum(inst, args):
inst.log("warning", "Vacuum could require AS MUCH free disk space as\n"
"the current size of the database!")
inst.begin(progBar=False)
inst.log("info", "Vacuuming...")
inst.db.vacuum()
COMMAND_DEFS = {
# Argument format: (<name>: <required>)
@ -754,7 +766,7 @@ COMMAND_DEFS = {
"deleteobjects": {
"func": delete_objects,
"help": "Delete static objects of a certain name and/or from a"
"help": "Delete static objects of a certain name and/or from a "
"certain area.",
"args": {
"searchobj": False,
@ -763,6 +775,13 @@ COMMAND_DEFS = {
"invert": False,
}
},
"vacuum": {
"func": vacuum,
"help": "Vacuum the database. This reduces the size of the database, "
"but may take a long time.",
"args": {}
},
}
@ -789,9 +808,13 @@ class MapEditInstance:
self.print_warnings = True
self.db = None
self.sdb = None
self.has_begun = False
def log(self, level, msg):
if level == "info":
if level == "":
# Print with no formatting.
print(msg)
elif level == "info":
print("INFO: " +
"\n ".join(msg.split("\n")))
elif level == "warning":
@ -803,28 +826,30 @@ class MapEditInstance:
"\n ".join(msg.split("\n")))
raise MapEditError()
def begin(self):
def begin(self, progBar=True):
if self.print_warnings:
self.log("warning", self.STANDARD_WARNING)
if input("Proceed? (Y/n): ").lower() != "y":
self.log("", "Exiting.")
raise MapEditError()
self.has_begun = True
if progBar:
self.progress.set_start()
def finalize(self):
committed = False
if self.db:
if self.db.is_modified():
committed = True
self.log("info", "Committing to database...")
self.db.close(commit=True)
if self.sdb:
self.sdb.close()
if committed:
if self.db:
if self.db.is_modified():
self.log("info", "Committing to database...")
self.db.commit()
self.db.close()
if self.has_begun:
self.log("info", "Finished.")
def update_progress(self, completed, total):
@ -833,7 +858,8 @@ class MapEditInstance:
def _verify_and_run(self, args):
self.print_warnings = not args.no_warnings
if bool(args.p1) != bool(args.p2):
if (hasattr(args, "p1") and hasattr(args, "p2") and
bool(args.p1) != bool(args.p2)):
self.log("fatal", "Missing --p1 or --p2 argument.")
if args.has_not_none("p1") and args.has_not_none("p2"):

View File

@ -158,6 +158,9 @@ class DatabaseHandler:
except sqlite3.DatabaseError:
raise
def is_modified(self):
return self.database.in_transaction
def get_block(self, key):
self.cursor.execute("SELECT data FROM blocks WHERE pos = ?", (key,))
if data := self.cursor.fetchone():
@ -181,13 +184,15 @@ class DatabaseHandler:
self.cursor.execute("UPDATE blocks SET data = ? WHERE pos = ?",
(data, key))
def is_modified(self):
return self.database.in_transaction
def vacuum(self):
self.commit() # In case the database has been modified.
self.cursor.execute("VACUUM")
def close(self, commit=False):
if self.is_modified() and commit:
def commit(self):
if self.is_modified():
self.database.commit()
def close(self):
self.database.close()