Welcome to the Achaea Forums! Please be sure to read the Forum Rules.

Script: Lua's 'db' class. Tables that act more like databases and sorting made easy.

FuscoFusco ✭✭ - StalwartMember Posts: 37 ✭✭ - Stalwart

Fusco's Lua Class: 'db'

Links:
the script on GitHub
the GitHub page with example
run script on repl.it

--------------------------------------------------------------------------
Disclaimer:
This script is still immature (hehe...butts....hehehehe). I have not had time to torture test it and I have yet to get error checking completely implemented. If you use it, be sure to back up your sessions and data. I will not guarantee any support, especially not in game where I'm trying to be in character. @Mushclient users: since this written in Lua, it might work for you, but it has the Mudlet functions display, cecho, table.save, and table.load in it. You'll have to replace these with appropriate Muschlient functions.
--------------------------------------------------------------------------

Preface

I've put together a Lua class named 'db' (because it's kind of like a database) with the goal of making the collection and handling of data easier. It mimics the behavior of a database or 2 dimensional table with consistent data types in the columns. While I'm still far from done working on it, I'm posting it here in hopes that some people might find it useful, and in the process come up with good ideas on how to improve it. Anyone may use and distribute this script for free, unless you really wanna gift me some polecat kits (adoribru) or an owl.

What it does

For those who aren't familiar with object-oriented programming, a class works like a template. It sets rules for the creation of objects. An object holds its own interior variables, tables, and functions which dictate how it behaves. Think of this class as a type of Lua table with a bunch of extra features built in.

'db' objects are created with an empty local table called 'members,' which holds all of its data. At the time of creation, you pass it a string to be its primary key. This value in this key is held unique for each member of the members table. The members are not allowed to be directly altered, as they are local, but entries and values in the table can be modified by calling the object's member functions (methods). For example, the function db.sort(field) will sort the entire table by the field chosen.

What can I do with a db object?

Any time you want to keep track of a lot of information to be processed later, a db could be a good solution. Let's say you want to be efficient while bashing. You could set up aliases or triggers that capture the amount of gold a denizen drops, then store that information in the table. After you've hit all your favorite hunting grounds a few times, you could then go back and find out how much gold a certain type of denizen drops on average, even sort by denizen type or bashing area. You always had that feeling that killing brown floppy-eared rabbits was more efficient than barnacle encrusted oysters, but now you'll know for sure. You could keep track of people's city affiliations, pet descriptions, market prices for coal, how many of your city's newbies Dajio has killed, or anything else that's too tedious or onerous to write down by hand or remember.

Notes/Considerations

Type checking and coercion on entered data is not fully fleshed out yet. To ensure things run properly, try to make sure that all the data in a 'column' is of the same type. "5" and 5 are not the same thing. If you try and sort a list of strings with numbers in them, you may or may not get the expected result. Be especially of nil values. If you fill a table up with a bunch of nils and then start pulling them out and plugging them in other functions, Mudlet may not be pleased. Initializing numbers with 0, strings with "" and booleans with either true/false is a good habit to be in. If you don't use them already, the tonumber() and tostring() functions are your friends.

Installation/Usage

All of the code is contained in a single script. Just copy all of the text in the file to an empty script in Mudlet, the name of the script in Mudlet doesn't matter. Now you can create an object:
-- this creates an object of type db named "db_denizens"
-- note, that you don't have to make the name paramater the 
-- same as the object itself, but it's a really good idea
-- the second parameter is the primary key: don't forget the primary key
-- or things will break!

db_denizens = db.new("db_denizens","id")

-- you can now start populating your object with data and getting that data back
groundhog = {id = "99952",name = "a groundhog",icon = "animal",area = "Sangre Plains, the"}
db_denizens.insert(groundhog)
echo(db_denizens.get("99952","area"))  -----> "Sangre Plains, the"
Saving and loading follows the same rules as with tables. You either need to create an empty file to write to before executing your first load, or you need to save your object at least once before trying to do any load operations. What I do is to make an empty object for the first time (db_denizens=db.new("db_denizens","id"), then before I do anything with it, I type in the console /db_denizens.save() . This will save the empty object once, then any load operations from that point on should be successful.

Methods/Functions 

I'll provide more complete documentation later. I've tried to be heavy on commenting in the script, so read all that green text around a function if you don't know what it does.

db.save()
      Saves the members table to file. An internal event ensures the table is automatically saved whenever it is changed.
db.load()
     Loads the members table from file. Note: load and save look like they have path parameters right now, but they don't. I will enable them later.
db.copy(tab)
     Directly writes a table to members. A quick and dirty way to initialize the db. Mostly used for testing, but will be fixed up later to properly hand type consistency. !!!- Do not use this function unless you are prepared to overwrite all of the existing table data -!!!
db.pdCopy(pd)
     Initializes members by converting a table which is a dictionary of sub-dictionaries into an indexed array and sets its outermost keys to the values of the new primary keys.
db.removeKey(pkey)
     Removes a "row" of the table by specifying its primary key.
db.remove(pos)
     Removes a "row" of the table by its index.
db.insert(entry,pos)
     Inserts a "row" into the table at a give position.
db.insertAll(t)
     Inserts a table of "rows".
db.removePairs(key,value)
     Removes all "rows" containing the given key, value pair.
db.add(pkey,field,addend)
     Adds (or subtracts) a number to a value in the table.
db.display(pkey)
     Displays a row or the entire table using Mudlet's display() function.
db.get(pkey,field)
     Returns an individual value from the table.
db.getEntry(pkey)
     Returns an entire row from the table.
db.set(pkey,field,newval)
      Assigns a value to a single table entry.
db.sort(field,descending)
     Returns the entire table sorted by a given field.
db.search(key,value)
     Returns all matching key, value pairs.
db.exists(pkey)
     Returns a boolean to indicate if a given primary key exists.
db.getName(getName)R
     Returns the name of the db.
db.getPrimary()
     Returns the primary key for the db.
db_err(msg)
     Handles internal errors, printing messages to the buffer and to the Mudlet error list.

Watch me run some of these functions
(Or try it for yourself by clicking here to open the script on Kobra.io)



And use them for practical purposes

This super secret table has an alias to resort by 4 different fields.



Thank merciful Sarapis that my lust for hot rajamalan babes didn't cause harm to my data!


Final Thoughts

I'll be adding more functionality to this class as time permits, so if you like it the way it is now, keep your eyes peeled for updates. If you think of a clever thing you'd like to do with data, and I can put together a function that'll do that, I'd love to hear ideas. My short list right now includes improving the way tables are saved and loaded, including options to control how often it saves so it won't have slowdown if you use the table a lot locally (think combat queues and stuff). I also have type checking and checking to ensure good data is being entered at the front of my list. Down the road I'll be looking at things like automatically printing to screen in columns, colored outputs, statistics functions (linear regression also gets my motor running), embedding a serialization library in the class, and maybe linking keys between tables.

Also, expect a readme with better documentation soon. I was actually kind of hoping to use this post as a jumping off point for that.

Links:
the script on GitHub
the GitHub page with example
run script on repl.it
PraxidesExelethril

Comments

  • JacenJacen Member Posts: 2,305 @@ - Legendary Achaean
    Not to crap all over what appears to be some quality work,  but it seems that you are blissfully unaware of Mudlet's already implemented db (class?) Which already does most of what you've implemented, and which is used by at least one very widely used module (svo), for which installing your script would break the implementation of.
    image
    Praxides
  • AhmetAhmet Wherever I wanna beMember Posts: 3,370 @@ - Legendary Achaean
    Yeah... Mudlet already has database support :surprised: 
    Huh. Neat.
  • VadimusesVadimuses Member Posts: 1,119 @ - Epic Achaean
    I'd really recommend renaming it from db - as that would overwrite Mudlet's db and mess with any scripts that expect Mudlets version.
Sign In to Comment.