{"id":19387732,"url":"https://github.com/haraka/haraka-nosql","last_synced_at":"2025-04-23T23:31:23.273Z","repository":{"id":30779247,"uuid":"34336062","full_name":"haraka/haraka-nosql","owner":"haraka","description":"NoSQL for Haraka, with RAM, SSC, and Redis backends","archived":false,"fork":false,"pushed_at":"2022-08-29T17:56:42.000Z","size":30,"stargazers_count":8,"open_issues_count":1,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-02T22:11:20.150Z","etag":null,"topics":["haraka","haraka-plugin","nosql"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/haraka-nosql","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/haraka.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-04-21T15:35:58.000Z","updated_at":"2023-11-25T04:45:04.000Z","dependencies_parsed_at":"2022-08-25T06:01:21.192Z","dependency_job_id":null,"html_url":"https://github.com/haraka/haraka-nosql","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haraka%2Fharaka-nosql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haraka%2Fharaka-nosql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haraka%2Fharaka-nosql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haraka%2Fharaka-nosql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/haraka","download_url":"https://codeload.github.com/haraka/haraka-nosql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250522901,"owners_count":21444620,"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":["haraka","haraka-plugin","nosql"],"created_at":"2024-11-10T10:10:19.216Z","updated_at":"2025-04-23T23:31:22.989Z","avatar_url":"https://github.com/haraka.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# haraka-nosql\n\n[![Build Status][ci-img]][ci-url]\n[![Coverage Status][cov-img]][cov-url]\n\n\nStore stuff in memory-backed objects, smartly.\n\n## Usage\n\n    var NoSQL = require('haraka-nosql');\n    var nosql = new NoSQL('myindex', {\n        storage: 'redis',  // or 'ram' or 'ssc'\n        expire: 10,        // minutes\n    });\n\nExports the following functions:\n\n## set\n\n    nosql.set('foo', 'bar', function (err, result) {\n        if (err) {\n            // error handling code\n            return;\n        }\n        // do fun stuff with result\n    });\n\nYou're confident it'll work out?  Skip the callback, it's optional. For all of these methods.\n\n    nosql.set('foo', 'bar');  // going commando\n\n## get\n\n    nosql.get('foo', function (err, result) {\n        if (err) { return; }\n        // result == 'bar'  (because that's what we set it to)\n    });\n\n## del\n\n    nosql.del('foo', function (err, result) {\n        if (err) { return; }\n        // result == 1   (# of objects keys deleted)\n    });\n\n## incrby\n\n    nosql.incrby('my_counter', 1, function (err, result) {\n        if (err) { return; }\n        // result == 1  (it was undef, now it's initialized to 1)\n    });\n\n    nosql.incrby('my_counter', 2);  // breezy!\n    // now my_counter == 3   (increment 1 with 2 and math!)\n\n\n## reset\n\n    nosql.reset();\n\n    // all your keys are belong to /dev/null\n\n\n# RAM? That ain't workin'\n\n## Pros\n\n* simple\n* no dependencies\n\n## Cons\n\n* Data disappears when Haraka is restarted.\n* Not shared across hosts\n* With [cluster](https://nodejs.org/api/cluster.html), worker processes share no data. Therefore, each worker process has a partial (incomplete) view of the state data.\n\n# Cluster RAM\n\n* When running with cluster, `nosql` attempts to load [strong-store-cluster](http://apidocs.strongloop.com/strong-store-cluster/), which stores data in the master worker.\n\n## Pros\n\n* All Haraka processes share a single RAM backed data store.\n\n## Cons\n\n* There's no \"reset\" operation. Instead, keys expire after 10 minutes (edit\n  `config/nosql.ini [cluster]expire` to alter. This is great for features such\n  as concurrency or brute-force auth tracking.\n\n# Redis\n\n## Pros\n\n* disk backed RAM storage\n* same view across Harka master \u0026 worker processes\n* persistence across Haraka \u0026 server reboots\n* network service, can be shared by many hosts\n\n## Enable Redis\n\n    sed -i.bak -e 's/; backend=redis/backend=redis/' /my/haraka/config/nosql.ini\n\n\n### Redis isn't running on localhost!\n\n    $EDITOR config/nosql.ini\n\nEdit the settings in the [redis] section.\n\n### I need more Redis features\n\nWhen Redis is configured, the redis connection is exported as `nosql.redis`. Use it like so:\n\n    var nosql = require('haraka-nosql');\n    var redis = nosql.redis;\n\n    redis.multi()\n         .hget('something')\n         .get('else')\n         .exec(function (err, res) {\n         });\n\nRefer to the excellent [Redis command docs](http://redis.io/commands)\n\n\n# Other\n\n## What about key collisions?\n\nCollisions are only possible within your namespace. Each caller of `nosql` automatically gets its own namespace. In RAM, each namespace is a JS object, rather like this:\n\n    {\n        karma: {\n            key: val,\n            key2: val2,\n        },\n        limit: {\n            key: val,\n            key2: val2,\n        }\n    }\n\nIn Strong Store Cluster, each caller gets its own collection.\n\nIn Redis, get|del|incrby operations are mapped to their hash equivalents (hget, hdel, hincrby).\n\n\n[ci-img]: https://github.com/haraka/haraka-nosql/actions/workflows/ci.yml/badge.svg\n[ci-url]: https://github.com/haraka/haraka-nosql/actions/workflows/ci.yml\n[cov-img]: https://coveralls.io/repos/haraka/haraka-nosql/badge.png\n[cov-url]: https://coveralls.io/r/haraka/haraka-nosql\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharaka%2Fharaka-nosql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fharaka%2Fharaka-nosql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharaka%2Fharaka-nosql/lists"}