-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Database API for mods #3374
Comments
minetest has a tradition of doing our own rewrite instead of taping together some unfitting third party "finished" solutions. Most times they don't fit our standard at second look, or don't fit our needs. For example, I would want to have a consistent API over all database types. Existing "finished" lua solutions can't provide this. Also, we have mod security. So they need to have some way to disable opening arbitrary files, which I guess they lack. |
Also there is the thing that I guess these APIs can't "serve two masters", meaning that we would have to have separate database files for the map and all the other files, or use those APIs for the database access. This is only a minor issue though. |
IIRC we have a "safe write to file" function somewhere in the engine utils. We could expose this to the Lua API. |
The corrupted env_meta.txt (etc.) files might be caused by #3084. |
Wouldn't a simple key/value store in which you can put Lua tables be enough? Something like this:
The mods don't need to know anything about the used database backend, and all you need in the database is another table with two columns and a primary key. |
That would be ideal @RobertZenz |
I don't think the corruption argument is good, as there are ways to save files safely without needing a database (after all, the database has to do it somehow). -- Argument is a database name in the modname:item format that's used
-- to generate a path/database and table for the mod. For example:
-- For SQLite3: `"foomod:foobar"` table in a database at `world/mod_db.sqlite`.
-- For LevelDB: keys prefixed with `"foomod:foobar:"` in `world/mod_db.leveldb/`.
local store = KeyValueStore("foomod:foobar")
store.set("a", "A")
assert(store.get("a") == "A")
-- Additional methods to iterate over all keys/values should also be added. Features like multiple fields and being able to query on arbitrary fields would make this much more useful, but then it would basically just work with SQLite3, and you might as well just give the mod full access to |
http:https://wiki.mudlet.org/w/Manual:Lua_Functions#Database_Functions |
Is the only point of this issue the corruption of files? I think that's silly... Well anyway, I made this commit finally today: 64c060e. I completely forgot that issue and now that I remembered and saw that #3084 had no comments, I went and made the fix. Users should now keep an eye on whether the corruption continues to happen with versions that contain this fix and report somewhere whether or not that is the case. |
For me, having the possibility to easily persist data and data structures in a key/value store would be quite nice. That would allow to centralize how mods are persisting their data. |
Some other potential benefits from unifying data storage into one backend:
Also, it should be feasible to store anything that used to go in files into a single key/value store; not even separate tables are strictly necessary. Use the filename (or a hash, url-encoding, or other sanitization scheme thereof) as the keys, and they can coexist without collision with mapblocks. |
+1 on this, but I don't want to store my mods data using something low-level as selecting in which DB store the data, etc. All I want is fast persistent storage with simple API (key/value, as lua table or, worse, JSON is good enough), and I don't want to write the same load-from-file/write-to-file code from mod to mod. |
Just pointing out that there's still a demand for a database API. (Also as a self-reminder) local my_db = minetest.open_database(path, "sqlite3/leveldb/redis/postgresql")
my_db:exec("DELETE FROM playerstats WHERE password = 'hunter2'") -- probably not possible like this in leveldb
my_db:close() |
i close this issue, we have meta on many objects to handle this now. |
Meta is inappropriate for lists of structured data. To store lists, you need to serialise the contents. This results in the exact same problem as before meta was added - difficulty in searching, performance, and memory use |
ModMetadata is not sufficient for you ? it's the purpose of this object |
Duplicate of #10371 (yes, I know it's newer) |
Nevermind |
Of note: Furthermore, we are already using Redis for rankings storage and we use a library to access it and add the mod to trusted ones. |
Summary:
Details:
Understanding this issue requires a very particular particular knowledge in hardware, OS design, and programming, but I suspect some of the minetest developers should be familiar with the problem.
Basically, any file that minetest writes to while it is running. This includes player info, env_meta, as well as all data stored by mods. The map.sqlite is the only file without this problem because sqlite is specifically designed to prevent such dataloss.
Basically, the chances of it happening are rare, but it does happen (even on what should be a very stable server at a reliable hosting company). Sometimes the data is not even recoverable from backups (because the data would be too far out of date). Any competent person who programs for servers would tell you that you should never store important data in a text file due to this ... it's just too risky. However, until such dataloss has happened to you personally, sometimes it's hard to understand how important this really is.
What is going on?
The solution:
The solution is pretty easy... store data in a database or some other system specifically designed to protect against dataloss like this.
What I am proposing
Examples:
Possible options:
For leveldb:
https://github.com/marcopompili/lua-leveldb -- leveldb is a key/value store which might be a lot easier for programmers to understand than something like sqlite
For sqlite:
http:https://lua.sqlite.org/index.cgi/home -- this one is well documented, so you could just refer people to that documentation.
For reddis:
https://github.com/nrk/redis-lua
Personal note:
For years, I didn't think it was a big deal storing data in text files. After all, crashes on a server should be so rare it shouldn't matter. However, after it happened to me several times on a server at a proper hosting company and after seeing it happen to others, I don't think I can trust storing my mod data in text files anymore. I am hoping minetest can include a database API, otherwise I may have to waste time writing my own database system for minetest. :( Including one of the pre-made APIs would take very little time to implement, then mod developers could migrate to the new system at their own choosing over time.
Sidenote: I may be unable to reply back to this post if you have any follow up questions, so I will just leave it to the minetest devs to discuss it.
The text was updated successfully, but these errors were encountered: