{"id":17066781,"url":"https://github.com/fabianterhorst/iron","last_synced_at":"2025-04-12T18:20:25.246Z","repository":{"id":73384513,"uuid":"48594490","full_name":"FabianTerhorst/Iron","owner":"FabianTerhorst","description":"Fast and easy to use NoSQL data storage with RxJava support","archived":false,"fork":false,"pushed_at":"2017-09-14T09:18:13.000Z","size":398,"stargazers_count":108,"open_issues_count":2,"forks_count":15,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-26T12:37:47.977Z","etag":null,"topics":["android-database-api","gradle","nosql-data-storage","rxjava","rxjava-support"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FabianTerhorst.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}},"created_at":"2015-12-26T00:08:46.000Z","updated_at":"2024-03-31T14:17:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"a1a68eb3-f64d-40cd-8082-5b6d10e7547d","html_url":"https://github.com/FabianTerhorst/Iron","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FabianTerhorst%2FIron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FabianTerhorst%2FIron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FabianTerhorst%2FIron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FabianTerhorst%2FIron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FabianTerhorst","download_url":"https://codeload.github.com/FabianTerhorst/Iron/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248610636,"owners_count":21132978,"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":["android-database-api","gradle","nosql-data-storage","rxjava","rxjava-support"],"created_at":"2024-10-14T11:08:17.435Z","updated_at":"2025-04-12T18:20:25.216Z","avatar_url":"https://github.com/FabianTerhorst.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://travis-ci.org/FabianTerhorst/Iron.svg?branch=master\"\u003e\u003c/img\u003e\n[![Join the chat at https://gitter.im/FabianTerhorst/Iron](https://badges.gitter.im/FabianTerhorst/Iron.svg)](https://gitter.im/FabianTerhorst/Iron?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Iron-brightgreen.svg?style=flat)](http://android-arsenal.com/details/1/2990)\n[![Codacy Badge](https://api.codacy.com/project/badge/grade/c0703e14011042bf9233a2604af85636)](https://www.codacy.com/app/fabian-terhorst/Iron)\n\u003ca href=\"http://www.methodscount.com/?lib=io.fabianterhorst%3Airon%3A0.6.4\"\u003e\u003cimg src=\"https://img.shields.io/badge/Size-28 KB-e91e63.svg\"\u003e\u003c/img\u003e\u003c/a\u003e\n\u003cimg src=\"https://img.shields.io/bintray/v/fabianterhorst/maven/iron.svg?label=Core\"\u003e\u003c/img\u003e\n\u003cimg src=\"https://img.shields.io/bintray/v/fabianterhorst/maven/iron-compiler.svg?label=Compiler\"\u003e\u003c/img\u003e\n\u003cimg src=\"https://img.shields.io/bintray/v/fabianterhorst/maven/iron-retrofit.svg?label=Retrofit\"\u003e\u003c/img\u003e\n\u003cimg src=\"https://img.shields.io/bintray/v/fabianterhorst/maven/iron-annotations.svg?label=Annotations\"\u003e\u003c/img\u003e\n\u003cimg src=\"https://img.shields.io/bintray/v/fabianterhorst/maven/iron-encryption.svg?label=Encryption\"\u003e\u003c/img\u003e\n\u003cimg src=\"https://img.shields.io/github/license/fabianterhorst/iron.svg\"\u003e\u003c/img\u003e\n\n# Iron\n\nFast and easy to use NoSQL data storage with RxJava and Kotlin support\n\nAndroid sdk version 8 support\n\n#### Add dependency\n\nAdd apt plugin in your top level gradle build file\n\n```groovy\nclasspath 'com.neenbedankt.gradle.plugins:android-apt:1.8'\n```\n\nApply apt plugin in your application gradle build file.\n\n```groovy\napply plugin: 'com.neenbedankt.android-apt'\n```\n\nAdd dependencies to your application gradle build file\n\nThe Core\n```groovy\ncompile 'io.fabianterhorst:iron:0.8.0'\n```\nThe Extensions\n```groovy\ncompile 'io.fabianterhorst:iron-retrofit:0.8.0'\ncompile 'io.fabianterhorst:iron-encryption:0.8.0'\n//is only required for using the compiler\ncompile 'io.fabianterhorst:iron-annotations:0.8.0'\napt 'io.fabianterhorst:iron-compiler:0.8.0'\n```\n\nInitiate Iron instance with application context\n\n```java\npublic class MyApplication extends Application {\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        Iron.init(getApplicationContext());\n        Iron.setCache(Cache.MEMORY);//default is NONE\n        //Optional if iron-retrofit is included\n        Iron.setLoader(new IronRetrofit());\n        //Optional if iron-encryption is included\n        Iron.setEncryption(new IronEncryption());\n    }\n}\n```\n\nUse the @Store annotation on any plain old Java object.\n\n```java\n@Store\npublic class Main {\n    @DefaultObject\n    @Name(value = \"contributor_list\", transaction = true, listener = true, loader = true, async = true)\n    ArrayList\u003cContributor\u003e contributors;\n\n    String userName;\n\n    @DefaultLong(120)\n    Long myLong;\n}\n```\nNow you can access the generated Methods from your Main + \"Store\" file.\n\n```java\n MainStore.setContributors(contributors);\n```\n\nGet value synced\n\n```java\n MainStore.getContributors(contributors);\n```\n\nGet value asynced\n\n```java\nMainStore.getContributors(new Chest.ReadCallback\u003cArrayList\u003cContributor\u003e\u003e() {\n    @Override\n    public void onResult(ArrayList\u003cContributor\u003e contributors) {\n    }\n});\n```\n\nRemove value\n\n```java\n MainStore.removeContributors();\n```\n\n```java\n Iron.chest().addOnDataChangeListener(new DataChangeCallback(this) {\n    @Override\n    public void onDataChange(String key, Object value) {\n        if(key.equals(MainStore.Keys.CONTRIBUTORS.toString())){\n            Log.d(TAG, ((ArrayList\u003cContributor\u003e)value).toString());\n        }\n    }\n});\n```\n\ntransactions (changes will be saved)\n\n```java\n MainStore.executeContributorsTransaction(new Chest.Transaction\u003cArrayList\u003cContributor\u003e\u003e() {\n    @Override\n    public void execute(ArrayList\u003cContributor\u003e contributors) {\n    \tContributor contributor = new Contributor();\n    \tcontributor.setName(\"fabianterhorst\");\n        contributors.add(contributor);\n    }\n});\n```\nUse a internal transaction to add a object to the list and save it automatically\n\n```java\nContributor contributor = new Contributor();\ncontributor.setName(\"test\");\nMainStore.addContributor(contributor);\n```\n\nUse a internal transaction to add objects to the list and save it automatically\n\n```java\nArrayList\u003cContributor\u003e contributors = new ArrayList\u003c\u003e();\nfor(int i = 0;i \u003c 10;i++){\n    Contributor contributor = new Contributor();\n    contributor.setName(\"name\" + i);\n    contributors.add(contributor);\n}\nMainStore.addContributors(contributors);\n```\n\n\nData change listener\n\n```java\nMainStore.addOnContributorsDataChangeListener(new DataChangeCallback\u003cArrayList\u003cContributor\u003e\u003e(this) {\n    @Override\n    public void onDataChange(ArrayList\u003cContributor\u003e value) {\n    }\n});\n```\n\nGeneric data change listener\n\n```java\nMainStore.addOnDataChangeListener(new DataChangeCallback(this) {\n    @Override\n    public void onDataChange(String key, Object value) {\n        if(key.equals(MainStore.Keys.CONTRIBUTORS.toString()))\n            //contributors changed\n    }\n});\n```\n\nSearch for object with field and value\n\n```java\nMainStore.getContributorsForField(\"login\", \"fabianterhorst\", new Chest.ReadCallback\u003cContributor\u003e() {\n    @Override\n    public void onResult(Contributor contributor) {\n        if(contributor != null)\n            Log.d(TAG, contributor.toString());\n    }\n});\n```\n\n#### RxJava support\n\nSet a value asynchron with RxJava\n\n```java\nIron.chest().set(\"name\", \"Fabian\");\n```\n\nGet a value asynchron with RxJava\n\n```java\nIron.chest().\u003cString\u003eget(\"name\").compose(this.\u003cString\u003ebindToLifecycle()).subscribe(new Subscriber\u003cString\u003e() {\n\n            @Override\n            public void onError(Throwable e) {\n                e.printStackTrace();\n            }\n\n            @Override\n            public void onNext(String s) {\n                //called when name changed and when name was loaded asynchron\n                Log.d(\"name\", s);\n            }\n\n            @Override\n            public void onCompleted() {\n\n            }\n        });\n```\n\nWith RxJava the Retrofit extension isn´t needed anymore.\n\n```java\nObservable\u003cList\u003cRepo\u003e\u003e reposCallObservable = service.listReposRxJava(\"fabianterhorst\");\nIron.chest().load(reposCallObservable, Repo.class);\n```\n\nYou can also use Iron.chest()´s methods.\n\n```java\nIron.chest().write(\"username\", \"fabian\");\n```\n\nRead data objects. Iron instantiates exactly the classes which has been used in saved data. The limited backward and forward compatibility is supported.\n\n```java\nString username = Iron.chest().read(\"username\");\n```\n\nLaod and save data with retrofit. Need loader extension to be added in application.\n\n```java\nCall\u003cList\u003cRepo\u003e\u003e reposCall = service.listRepos(\"fabianterhorst\");\nIron.chest().load(reposCall, Repo.class);\n```\n\nGet value asynced with default value\n\n```java\nIron.chest().get(\"contributors\", new Chest.ReadCallback\u003cArrayList\u003cContributor\u003e\u003e() {\n    @Override\n    public void onResult(ArrayList\u003cContributor\u003e contributors) {      \n    }\n}, new ArrayList\u003cContributor\u003e());\n```\n\nRemove listener to prevent memory leaks\n\n```java\n@Override\nprotected void onDestroy() {\n    super.onDestroy();\n    MainStore.removeListener(this);\n    //Iron.chest().removeListener(this);\n}\n```\n\n#### Handle data structure changes\nClass fields which has been removed will be ignored on restore and new fields will have their default values. For example, if you have following data class saved in Paper storage:\n\n```java\nclass User {\n    public String name; //Fabian\n    public boolean isActive;\n}\n```\n\nAnd then you realized you need to change the class like:\n\n```java\nclass User {\n    public String name; //Fabian\n    // public boolean isActive; removed field\n    public Location location; // New field\n}\n```\n\nThen on restore the _isActive_ field will be ignored and new _location_ field will have its default value _null_.\n\nRetrofit support\n```java\nCall\u003cList\u003cContributor\u003e\u003e userCall = service.contributors(\"fabianterhorst\", \"iron\");\nMainStore.loadContributors(userCall);\n```\n\nwith Cache:\n\nRunning [Benchmark](https://github.com/fabianterhorst/Iron/blob/master/iron/src/androidTest/java/io/fabianterhorst/iron/benchmark/Benchmark.java) on Nexus 6p, in ms:\n\n| Benchmark                 | Iron    | [Hawk](https://github.com/orhanobut/hawk) | [sqlite](http://developer.android.com/reference/android/database/sqlite/package-summary.html) |\n|---------------------------|----------|----------|----------|\n| Read/write 500 contacts   | 29      | 142      |          |\n| Write 500 contacts        | 27      | 60      |          |\n| Read 500 contacts         | 0       | 63      |          |\n\nRunning [Benchmark](https://github.com/fabianterhorst/Iron/master/iron/src/androidTest/java/io/fabianterhorst/iron/benchmark/Benchmark.java) on Emulator, in ms:\n\n| Benchmark                 | Iron    | [Hawk](https://github.com/orhanobut/hawk) | [sqlite](http://developer.android.com/reference/android/database/sqlite/package-summary.html) |\n|---------------------------|----------|----------|----------|\n| Read/write 500 contacts   | 12      | 54      |          |\n| Write 500 contacts        | 11      | 25      |          |\n| Read 500 contacts         | 0       | 24      |          |\n\nwith Encryption (only in Iron):\n\nRunning [Benchmark](https://github.com/fabianterhorst/Iron/master/iron/src/androidTest/java/io/fabianterhorst/iron/benchmark/Benchmark.java) on Nexus 6p, in ms:\n\n| Benchmark                 | Iron    | [Hawk](https://github.com/orhanobut/hawk) | [sqlite](http://developer.android.com/reference/android/database/sqlite/package-summary.html) |\n|---------------------------|----------|----------|----------|\n| Read/write 500 contacts   | 53      | 142      |          |\n| Write 500 contacts        | 28      | 61      |          |\n| Read 500 contacts         | 23       | 63      |          |\n\n\n#### Snapshot Builds\n\nAdd the jitpack repository in your root build.gradle at the end of repositories\n```groovy\nallprojects {\n    repositories {\n        maven { url \"https://jitpack.io\" }\n    }\n}\n```\n\n```groovy\n//Latest commit\ncompile 'com.github.FabianTerhorst:Iron:-SNAPSHOT'\n```\n\n### License\n    Copyright 2016 Fabian Terhorst\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabianterhorst%2Firon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffabianterhorst%2Firon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabianterhorst%2Firon/lists"}