{"id":16019598,"url":"https://github.com/iboard/repox","last_synced_at":"2025-04-05T03:25:09.291Z","repository":{"id":31716999,"uuid":"35282817","full_name":"iboard/repox","owner":"iboard","description":"An Elixir repository pattern","archived":false,"fork":false,"pushed_at":"2015-10-18T17:35:05.000Z","size":228,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-04T08:08:48.781Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","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/iboard.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-05-08T14:09:30.000Z","updated_at":"2015-05-08T19:29:06.000Z","dependencies_parsed_at":"2022-07-22T04:31:59.979Z","dependency_job_id":null,"html_url":"https://github.com/iboard/repox","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboard%2Frepox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboard%2Frepox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboard%2Frepox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboard%2Frepox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iboard","download_url":"https://codeload.github.com/iboard/repox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247283373,"owners_count":20913562,"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":[],"created_at":"2024-10-08T17:04:53.265Z","updated_at":"2025-04-05T03:25:09.268Z","avatar_url":"https://github.com/iboard.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"Repox\n=====\n\nThis is a \"practicing project\" and a try to implement the\nrepository pattern with Elixir.\n\nPlease stay tuned for further (massive) changes.\n\n## Github\n\n  * [On Github](https://github.com/iboard/repox)\n\n## Installation\n\n    git clone https://github.com/iboard/repox.git\n    cd repox\n    cp config/dev.sample_exs config/dev.exs\n    mix deps.get\n    mix test --trace\n\n## Configuration\n\nThere should be an environment file for each defined environment\n(MIX_ENV, :test, :dev, :production.\n\nApplication specific configuration is done in section :repox\n\n\u003e (By now, only the Mongo db-connection is defined here)\n\n### example config/dev.ex\n\n    use Mix.Config\n\n    config :repox,\n      mongo_db_name: \"dev\",\n      mongo_collection: \"dev_collection\"\n\nAll keys in this config definition are accessible through\n`Repox.config(:key)` where valid keys are:\n\n| Key name          | possible values \u0026 meaning              | example       |\n|-------------------|----------------------------------------|---------------|\n| :mongo_db_name    | any string valid as a mongo db-name    | 'addressbook' |\n| :mongo_collection | any string valid as a mongo collection | 'people'      |\n\n\n## Documentation\n\nRun `mix docs` will generate documentation in `doc`\nThen open `doc/index.html`\n\nYou may find an online-version of docs on\n[static.iboard.cc](http://static.iboard.cc/repox/index.html)\n\n## Concept\n\n    +-----------------+                  +----------------+\n    | GatewayProtocol | \u003c--------------- | GatewayService |\u003c\u003c\u003c\u003c-API-\u003e\u003e\n    +-----------------+                  +----------------+\n            ^\n            |\n            |---------------+--------------+\n    +-------------+   +-------------+   +------+\n    | ListGateway |   | FileGateway |   | .... |\n    +-------------+   +-------------+   +------+\n\nThe _GatewayProtocol_ defines all functions needed for a persistence gateway.\n_ListGateway_, _FileGateway_, and others (eg SQLGateway, MongoDBGateway,...)\nmust implement the functions defined in the _GatewayProtocol_.\n\nThe _GatewayService_ is an OTP _GenServer_ and implements mostly the same\nfunctions as defined in the _GatewayProtocol_. It gets initialized with a\nconcrete _GatewayImplementation_ (_ListGateway_, ...).\n\nThe user of the _GatewayService_ then calls functions on the service doesn't\nhave to know how the _GatewayImplementation_ handles the persistence layer.\n\n### Example:\n\n    in_memory_store = %ListGateway{}\n    file_store      = %FileGateway{path: \"/path/to/file\"}\n\n    entry           = \"Some data of any kind\"\n\n    {:ok, in_memory_service} = GatewayService.start_service(in_memory_store)\n    {:ok, file_service}      = GatewayService.start_service(file_store)\n\n    # Now save the entry to both services\n    GatewayService.put(in_memory_service, entry)\n    GatewayService.put(file_service, entry)\n\n    # And get it back from the gateway\n    enttries = GatewayService.where(in_memory_service, \u0026( \u00261 != nil ))\n    # or\n    entries  = GatewayService.where(file_service, \u0026( \u00261 != nil ))\n\nAs you can see there is no difference in using the service with either a\n_ListGateway_ or _FileGateway_, or any other implementation.\n\n\"\u0026(\u00261 != nil)\" if you new to Elixir this definition will confuse you a bit.\n`\u0026()` defines an anonymous function and `\u00261` in `\u00261 != nil` means the first\nparameter passed to the function.\nThis anonymous function gets passed through to the gateway's filter function.\nThe gateway implementation iterates all entries and will filter all of them\nwhere the entry (`\u00261`) fulfills the condition ` != nil`.\n\nAssuming our `entry` is a structure like `%{ id: 12, value: \"something\" }` you\ncan pass a filter like `\u00261( \u00261.id == 12 )`\n\n## Benchmarks\n\nTo run benchmarks do\n\n    mix bench\n\n    ## BenchmarksBench\n    [21:07:46] 0/3: 100x put to a Mongo collection\n    [21:07:58] 0/3: 100x put to a Memory List\n    [21:07:59] 0/3: 100x put to a File List\n\n    Finished in 16.89 seconds\n\n    ## BenchmarksBench\n    100x put to a Memory List             1000   1498.35 µs/op\n    100x put to a Mongo collection         500   22170.77 µs/op\n    100x put to a File List                  1   3204996.00 µs/op\n\n## Linked Projects\n\n  * [repox] This open source repository, implementing a\n    Repository-pattern for Elixir. Supporting InMemory, File, MongoDB\n    Gateways.\n  * [elixir_iboard] Defines a \"Boards Repository\", using Repox.\n  * [iboard_phoenix] Phoenix Web-project using [elixir_iboard]\n\n## License\n\nCopyright (C) 2015 Andreas Altendorfer, \u003candreas@altendorfer.at\u003e\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the \"Software\"),\nto deal in the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense,\nand/or sell copies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\nDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE\nOR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n[iboard_phoenix]: https://bitbucket.org/n0ckenfell/iboard_phoenix/overview\n[elixir_iboard]:  https://bitbucket.org/n0ckenfell/elixir_iboard\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiboard%2Frepox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiboard%2Frepox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiboard%2Frepox/lists"}