{"id":16164754,"url":"https://github.com/aperezdc/lua-shelve","last_synced_at":"2025-04-07T04:49:03.497Z","repository":{"id":142776953,"uuid":"50925677","full_name":"aperezdc/lua-shelve","owner":"aperezdc","description":"Serialization and on-disk persistence for Lua values","archived":false,"fork":false,"pushed_at":"2023-05-16T12:30:33.000Z","size":60,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-02-13T09:19:53.926Z","etag":null,"topics":["gdbm","lua","luajit","ndbm","serialization"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aperezdc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-02-02T14:23:01.000Z","updated_at":"2023-05-16T12:28:36.000Z","dependencies_parsed_at":"2024-11-02T09:40:56.642Z","dependency_job_id":"359259eb-6bbe-489b-a670-66f71717b7ba","html_url":"https://github.com/aperezdc/lua-shelve","commit_stats":{"total_commits":55,"total_committers":1,"mean_commits":55.0,"dds":0.0,"last_synced_commit":"a8d4ac66d73b5964c3653075b6cd7e28cc28a406"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aperezdc%2Flua-shelve","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aperezdc%2Flua-shelve/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aperezdc%2Flua-shelve/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aperezdc%2Flua-shelve/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aperezdc","download_url":"https://codeload.github.com/aperezdc/lua-shelve/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247595382,"owners_count":20963943,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gdbm","lua","luajit","ndbm","serialization"],"created_at":"2024-10-10T02:47:37.614Z","updated_at":"2025-04-07T04:49:03.470Z","avatar_url":"https://github.com/aperezdc.png","language":"C","readme":"# Lua Shelve Module\n\n[![CI Status](https://github.com/aperezdc/lua-shelve/actions/workflows/ci.yml/badge.svg)](https://github.com/aperezdc/lua-shelve/actions/workflows/ci.yml)\n\nThis is a Lua module that uses either GNU Gdbm or the more standard Ndbm\ndatabase libraries to store  data in files, but this data is saved in\na special way: all standard Lua datatypes may be directly stored and\nretrieved in its original form and  contents, including Lua tables. A shelf\nfile is a special kind of userdata that behaves similarly to a Lua table, so\nits contents are accessed in a table- like fashion. Quick example:\n\n```lua\n-- Create data\nmy_table = {\n  name = \"This is a string within a table\",\n  level= 1,\n  is_at_level_one = true,\n  another_table = {\n    name = \"This is a nested table\",\n    level= 2,\n    is_at_level_one = false\n  }\n}\n\n-- Open a 'shelve' file\nfile = shelve.open(\"data\")\n\n-- This encodes \u0026 stores the above table\n-- Dotted and bracketed syntax may be used interchangeably\nfile[\"my_table\"] = my_table\nfile.title = \"File containing a string and a table\"\n\n-- Show contents of the file in (key, value) form\nfor key in file() do\n  print(\"(\" .. key .. \", \" .. tostring(file[key]) .. \")\")\nend\n```\n\nThe name of the module, `shelve`, is taken from the Python's module\nwith the same name, as both work in a similar way. The nuts \u0026 bolts\nof the module are coded directly in C, so operation speed is fairly\nfast.\n\n\n## Requirements\n\nIn order to build and use the this Lua module, you will need the following:\n\n- Working C compiler, GCC recommended.\n- GNU DBM (aka Gdbm) or the standard Unix Ndbm. If you have the old Unix DBM\n  please upgrade to Gdbm or Ndbm. Gdbm is better.\n- Lua 5.0 beta or above, including headers and libraries.\n- GNU Make (ok, you may also  build manually...). I don't know whether other\n  versions of Make will work.\n\nIf you want to compile the module as a dynamically loadable library\n(plugin) you will also need the following:\n\n- Lua interpreter with `loadlib(`\" support. Most modern operating systems\n  (Linux, MacOS X, Windows, BSD...) can handle this.\n\n\n## Operation\n\nTo gain access to a data file, you must open it first. The module defines\nan `open()` function that receives two parameters:\n\n```lua\nfile_handle = shelve.open(file_name, access_mode)\n```\n\n- `file_name` is the path of the file you want to open.\n- `access_mode` is a string describing how the file should be accessed.\n  `\"r\"` means readonly, and any other string will will be interpreted\n  as read+write access. If you don't pass the second parameter,\n  read+write access is assumed. Note that the mode in which a file is\n  opened is important: a writer needs exclusive access to the file, but\n  various readers may read it concurrently. When you need only read-access,\n  please use this option,  and you will get better response when several\n  processes/threads are working with the same data file.\n\nIn order to retain the structure and type information of the data, it must be\nencoded with this  information included. The result of coding is a stream of\nbytes. The `shelve` data files are standard Gdbm/Ndbm files that contain\nthese encoded bytestreams as data, and the specified identifier as key of\nthe data, so the following Lua statement:\n\n```lua\nfile[\"a number\"] = 12345\n```\n\nWill use the string `a number` as key and the encoded form of the `12345`\nnumeric value as data in the Gdbm/Ndbm file.\n\nThe opposite action:\n\n```lua\nnum = file[\"a number\"]\n```\n\nWill look-up for the `a number` key in the Gdbm/Ndbm file. If the key does\n*not* exist, a `nil` value is returned, otherwise the bytestream associated\nwith the key will be read and decoded in order to return the original Lua\nstructure.\n\nTo delete a *(key, data)* pair from  the file, just assign `nil` to the key.\nExample:\n\n```\nfile = shelve.open(\"test\")\nfile.number = 12345  -- this assignment defines \"number\"\nfile.number = nil    -- this assignment deletes \"number\"\n```\n\nIndexing a shelve file with an undefined key will always return `nil`.\nExample:\n\n```\nfile = shelve.open(\"test\")\nfile.number = 12345   -- this assignment defines \"number\"\nprint(file.number)    -- prints \"12345\"\nfile.number = nil     -- this assignment deletes \"number\"\nprint(file.number)    -- prints \"nil\"\nprint(file.undefined) -- prints \"nil\", again\n```\n\nIn order to close a shelf, just assign let it be garbage-collected When Gdbm\nis used as backend and the file was open in  read+write mode, it will be\nreorganized on close.\n\n\n## Extras\n\nThe module also defines two standalone functions that perform the\nencoding/decoding of data:\n\n```lua\nencoded = shelve.marshal(value)\n```\n\nEncodes `value` and returns the encoded bytestream as a Lua string.\n\n```lua\nvalue = shelve.unmarshal(encoded):\n```\n\nTakes an `encoded` Lua string and returns the decoded Lua value.\n\nThe relantionship between these two functions is that one is the\ninverse of the other, so:\n\n```lua\ndata1 == shelve.unmarshal(shelve.marshal(data1))  -- true\ndata2 == shelve.marshal(shelve.unmarshal(data2))  -- true\n```\n\nYou may use these functions to manually encode and decode data.\nNote that `shelve.marshal()` adds a special mark to the end of an\nencoded bytestream: decoding the concatenation of two encoded\nvalues will only return the first one.\n\n\n## Known Limitations\n\n- Data files are NOT portable across:\n  - Platforms with different endianness and word sizes.\n  - Different builds of the shelve module when one uses GDBM and the other\n    uses NDBM (this is because they don't use the same internal file format).\n- Functions, userdata and light userdata **cannot** be encoded and stored in\n  a shelf. If you try to encode one of  these you will get an error. In\n  particular, it is not possible to store/marshal regular or `shelve` file\n  handles.\n- Trying to encode a table that has references to itself produces an infinite\n  loop recursion, thus a hang or a stack overflow will occur.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faperezdc%2Flua-shelve","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faperezdc%2Flua-shelve","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faperezdc%2Flua-shelve/lists"}