{"id":13411908,"url":"https://github.com/jameycribbs/hare","last_synced_at":"2026-01-17T17:02:27.960Z","repository":{"id":141870905,"uuid":"70095048","full_name":"jameycribbs/hare","owner":"jameycribbs","description":"Hare is a nimble little database management system for Go.","archived":false,"fork":false,"pushed_at":"2021-02-25T00:05:34.000Z","size":219,"stargazers_count":88,"open_issues_count":1,"forks_count":10,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-22T13:31:58.525Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jameycribbs.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2016-10-05T20:05:45.000Z","updated_at":"2024-04-19T19:27:58.000Z","dependencies_parsed_at":"2024-01-07T21:53:58.756Z","dependency_job_id":"f29b8bca-4a23-49e7-8a07-fca04ee895e8","html_url":"https://github.com/jameycribbs/hare","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/jameycribbs/hare","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jameycribbs%2Fhare","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jameycribbs%2Fhare/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jameycribbs%2Fhare/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jameycribbs%2Fhare/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jameycribbs","download_url":"https://codeload.github.com/jameycribbs/hare/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jameycribbs%2Fhare/sbom","scorecard":{"id":504447,"data":{"date":"2025-08-11","repo":{"name":"github.com/jameycribbs/hare","commit":"1e37662981b57a0fcdc8dee1390941a21ea3a482"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T22:56:26.778Z","repository_id":141870905,"created_at":"2025-08-19T22:56:26.779Z","updated_at":"2025-08-19T22:56:26.779Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28511876,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T13:38:16.342Z","status":"ssl_error","status_checked_at":"2026-01-17T13:37:44.060Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2024-07-30T20:01:18.327Z","updated_at":"2026-01-17T17:02:27.933Z","avatar_url":"https://github.com/jameycribbs.png","language":"Go","funding_links":[],"categories":["Database","Data Integration Frameworks","Generators","数据库","Go","Uncategorized"],"sub_categories":["Databases Implemented in Go","Go中实现的数据库","Advanced Console UIs"],"readme":"\u003cimg src=\"https://raw.githubusercontent.com/jameycribbs/hare/master/hare.jpg\" width=\"400\" /\u003e\n\nHare - A nimble little database management system written in Go\n====\n\nHare is a pure Go database management system that stores each table as\na text file of line-delimited JSON.  Each line of JSON represents a \nrecord.  It is a good fit for applications that require a simple embedded DBMS.\n\n## Table of Contents\n\n- [Getting Started](#getting-started)\n  - [Installing](#installing)\n  - [Usage](#usage)\n- [Features](#features)\n\n## Getting Started\n\n### Installing\n\nTo start using Hare, install Go and run `go get`:\n\n```sh\n$ go get github.com/jameycribbs/hare\n```\n\n\n### Usage\n\n#### Setting up Hare to use your JSON file(s)\n\nA directory of JSON files is represented by a hare.Database. Each JSON file\nneeds a struct with it's members cooresponding to the JSON field names.\nAdditionally, you need to implement 3 simple boilerplate methods on that\nstruct that allow it to satisfy the hare.Record interface.\n\nA good way to structure this is to put this boilerplate code in a \"models\"\npackage in your project.  You can find an example of this boilerplate code in the\nexamples/crud/models/episodes.go file.\n\nNow you are ready to go!\n\nLet's say you have a \"data\" directory with a file in it called \"contacts.json\".\n\nThe top-level object in Hare is a `Database`. It represents the directory on\nyour disk where the JSON files are located.\n\nTo open your database, you first need a new instance of a datastore.  In this\nexample, we are using the `Disk` datastore:\n\n```go\nds, err := disk.New(\"./data\", \".json\")\n```\nHare also has the `Ram` datastore for in-memory databases.\n\nNow, you will pass the datastore to Hare's New function and it will return\na `Database` instance:\n```go\ndb, err := hare.New(ds)\n```\n\n\n#### Creating a record\n\nTo add a record, you can use the `Insert` method:\n\n```go\nrecID, err := db.Insert(\"contacts\", \u0026models.Contact{FirstName: \"John\", LastName: \"Doe\", Phone: \"888-888-8888\", Age: 21})\n```\n\n\n#### Finding a record\n\nTo find a record if you know the record ID, you can use the `Find` method:\n\n```go\nvar c models.Contact\n\nerr = db.Find(\"contacts\", 1, \u0026c)\n```\n\n\n#### Updating a record\n\nTo update a record, you can use the `Update` method:\n\n```go\nc.Age = 22\n\nerr = db.Update(\"contacts\", \u0026c)\n```\n\n\n#### Deleting a record\n\nTo delete a record, you can use the `Delete` method:\n\n```go\nerr = db.Delete(\"contacts\", 3)\n```\n\n\n#### Querying\n\nTo query the database, you can write your query expression in pure Go and pass\nit to your model's QueryContacts function as a closure.  You would need to create\nthe QueryContacts function for your model as part of setup.  You can find an\nexample of what this function should look like in examples/models/episodes.go.\n\n```go\nresults, err := models.QueryContacts(db, func(c models.Contact) bool {\n  return c.firstname == \"John\" \u0026\u0026 c.lastname == \"Doe\"\n}, 0)\n```\n\n\n#### Associations\n\nYou can create associations (similar to \"belongs_to\" in Rails, but with less\nfeatures).  For example, you could create another table called \"relationships\" with\nthe fields \"id\" and \"type\" (i.e. \"Spouse\", \"Sister\", \"Co-worker\", etc.).  Next,\nyou would add a \"relationship_id\" field to the contacts table and you would also add\nan embeded Relationship struct.  Finally, in the Contact models \"AfterFind\" method,\nwhich is automatically called by Hare everytime the \"Find\" method is executed, you\nwould add code to look-up the associated relationship and populate the embedded\nRelationship struct.  Take a look at the crud.go file in the \"examples\" directory\nfor an example of how this is done.\n\nYou can also mimic a \"has_many\" association, using a similar technique.  Take a\nlook at the files in the examples directory for how to do that.\n\n\n#### Database Administration\n\nThere are also built-in methods you can run against the database\nto create a new table or delete an existing table. Take a look at the\nexamples/dbadmin/dbadmin.go file for examples of how these can be used.\n\nWhen Hare updates an existing record, if the changed record's length is\nless than the old record's length, Hare will overwrite the old data\nand pad the extra space on the line with all \"X\"s.\n\nIf the changed record's length is greater than the old record's length,\nHare will write the changed record at the end of the file and overwrite\nthe old record with all \"X\"s.\n\nSimilarly, when Hare deletes a record, it simply overwrites the record\nwith all \"X\"s.\n\nEventually, you will want to remove these obsolete records.  For an\nexample of how to do this, take a look at the examples/dbadmin/compact.go\nfile.\n\n\n## Features\n\n* Records for each table are stored in a newline-delimited JSON file.\n\n* Mutexes are used for table locking.  You can have multiple readers\n  or one writer for that table at one time, as long as all processes \n  share the same Database connection.\n\n* Querying is done using Go itself.  No need to use a DSL.\n\n* An AfterFind callback is run automatically, everytime a record is\n  read, allowing you to do creative things like auto-populate\n  associations, etc.\n  \n* When using the `Disk` datastore, the database is not read into\n  memory, but is queried from disk, so no need to worry about a large\n  dataset filling up memory.  Of course, if your database is THAT\n  big, you should probably be using a real DBMS, instead of Hare!\n\n* Two different back-end datastores to choose from:  `Disk` or `Ram`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjameycribbs%2Fhare","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjameycribbs%2Fhare","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjameycribbs%2Fhare/lists"}