A simple NoSQL client for Android. Meant as a document store using key/value pairs and some rudimentary querying. Useful for avoiding the hassle of SQL code.

Overview

SimpleNoSQL

A simple NoSQL client for Android. If you ever wanted to just save some data but didn't really want to worry about where it was going to be stored and didn't want to go through the hassle of setting up a database manually, this library can really speed things up. Saving data is pretty easy:

NoSQLEntity<SampleBean> entity = new NoSQLEntity<SampleBean>("bucket", "entityId");
SampleBean data = new SampleBean();
data.setName("Colin");
Map<String, Integer> birthday = new HashMap<String, Integer>();
birthday.put("day", 17);
birthday.put("month", 2);
birthday.put("year", 1982);
data.setBirthdayMap(birthday);
entity.setData(data);

NoSQL.with(context).using(SampleBean.class).save(entity);

Later, when you want to retrieve it, you can use a callback interface and the bucket and ID you saved with:

NoSQL.with(context).using(SampleBean.class)
    .bucketId("bucket")
    .entityId("entityId")
    .retrieve(new RetrievalCallback<SampleBean>() {
    public void retrieveResults(List<NoSQLEntity<SampleBean> entities) {
        // Display results or something 
        SampleBean firstBean = entities.get(0).getData(); // always check length of a list first...
    }   
});

If you'd like to delete data, you can use

NoSQL.with(context).using(SampleBean.class)
    .bucketId("bucket")
    .entityId("entityId")
    .delete()

To delete a single entity. Or you can delete an entire bucket via:

NoSQL.with(context).using(SampleBean.class)
    .bucketId("bucket")
    .delete()

When making a query, you can filter results by including a DataFilter. You can also order the results by including a DataComparator.

NoSQL.with(context).using(SampleBean.class)
    .bucketId("bucket")
    .filter(new DataFilter<SampleBean>() {
        public boolean isIncluded(NoSQLEntity<SampleBean> item) {
            if (item != null && item.getData() != null) {
                SampleBean bean = item.getData();
                return bean.hasBirthdaymap();
            }
            return false;
        }
    })
    .orderBy(new DataComparator<SampleBean>() {
        public int compare(NoSQLEntity<SampleBean> lhs, NoSQLEntity<SampleBean> rhs) {
            if (lhs != null && lhs.getData() != null) {
                if (rhs != null && rhs.getData() != null) {
                    return lhs.getData().getName().compareTo(rhs.getData().getName());
                } else {
                    return 1;
                }
            } else if (rhs != null && rhs.getData() != null) {
                return -1;
            } else {
                return 0;
            }
        }
    })
    .retrieve(new RetrievalCallback<SampleBean>() {
        public void retrieveResults(List<NoSQLEntity<SampleBean> entities) {
            // Display results or something
            SampleBean firstBean = entities.get(0).getData(); // always check length of a list first...
        }
    });

Development

This project is still very new and under active development. The API is in a wildly fluctuating state as I figure out the best way of making it simple to access documents. The current API uses gson for serialization and deserialization. You can access releases on sonatype by adding the following to your modules build.gradle:

repositories {
    maven {
            url 'https://oss.sonatype.org/content/groups/public'
        }
}

dependencies {
    compile 'com.colintmiller:simplenosql:0.5.1'
}

License

Copyright (C) 2014 Colin Miller (http://colintmiller.com)

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Comments
  • Provide simple get()

    Provide simple get()

    In addition to retrieve() method, it will be great if i can handle all by myself. Simple synchronous call. Useful when i want to dispatch db calls through my own executor for example.

    enhancement 
    opened by dsvoronin 8
  • Callback never returns when calling retrieve synchronously

    Callback never returns when calling retrieve synchronously

    I have implemented a method to retrieve results from a bucket in a Synchronous way. But the callback never returns. Any idea?

    public List getAll(String bucket, Class type) {

        final CountDownLatch latch = new CountDownLatch(1);
        final List<T> result = new ArrayList<T>();
        try {
    
            NoSQL.with(contextReference.get()).using(type).bucketId(bucket).retrieve(
                    new RetrievalCallback<T>() {
                        @Override
                        public void retrievedResults(List<NoSQLEntity<T>> noSQLEntities) {
                            System.out.println("NEVER RETURNS!!!!");
    
                            for (int i = 0; i < noSQLEntities.size(); i++) {
                                result.add(noSQLEntities.get(i).getData());
                            }
                            latch.countDown();
                        }
                    });
            latch.await();
            return result;
        } catch (Exception e) {
            return null;
        }
    
    
    }
    
    opened by jjvargas 6
  • How  to Support List  like HashMap?

    How to Support List like HashMap?

    I want save a list in entify like HashMap

    public void testSaveEntities2() throws Throwable {

        NoSQLEntity<SampleBean2> entity = new NoSQLEntity<SampleBean2>(
                "bucket", "entityId");
        SampleBean2 data = new SampleBean2();
        data.setField1("abc");
        data.setId(9);
        List<User> mUsers = new ArrayList<User>();
        for (int i = 0; i < 100; i++) {
    
            User mUser = new User();
            mUser.setAge("15" + i);
            mUser.setName("name" + i);
            mUsers.add(mUser);
    
        }
    
        data.setmUsers(mUsers);
        entity.setData(data);
        //NoSQL.with(context).using(SampleBean2.class).bucketId("bucket")
       // .entityId("entityId").delete();
        NoSQL.with( getInstrumentation().getTargetContext()).using(SampleBean2.class).save(entity);
    
    }
    

    but the result like this

    image

    link

    How to Support List like HashMap?

    opened by longtaoge 5
  • Leaked connection

    Leaked connection

    W/SQLiteConnectionPool﹕ A SQLiteConnection object for database '/data/data//databases/simplenosql.db' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.

    got this in log on every retrieve request

    opened by dsvoronin 4
  • Add RxJava support

    Add RxJava support

    Since the data retrieval is already async by default, it'd be pretty sweet to provide a option to return an RxJava Observable from which to receive the data.

    Retrofit does this in an optional way so you don't have to have RxJava in your project, but if you do it all just works. Not exactly sure how they accomplish that.

    RxJava: https://github.com/ReactiveX/RxJava

    Android version of RxJava: https://github.com/ReactiveX/RxAndroid

    Retrofit: https://github.com/square/retrofit

    opened by Wavesonics 3
  • The operator (") should be used.">

    The operator ("<>") should be used.

    This pull request is focused on resolving occurrences of Sonar rule squid:S2293 - “The diamond operator ("<>") should be used ”. You can find more information about the issue here: https://dev.eclipse.org/sonar/rules/show/squid:S2293 Please let me know if you have any questions. Ayman Abdelghany.

    opened by AymanDF 1
  • Is this thread safe?

    Is this thread safe?

    Hey @Jearil great API design :)

    First I think there is a typo in the sample doc/article you should use bucketId instead of bucket.

    Second: I was wondering if your 4 thread dispatcher array is acting like a ThreadPool ? if yes just if I understood correctly the API, I should be able to submit 3 operation let's say

    • OP1_SAVE
    • OP2_DELETE
    • OP3-RETRIEVE

    let's suppose OP1 takes more times to complete (& another thread becomes available) you may run into some race condition when you try to delete an non existing value (OP2)? same goes for retrieval (OP3)

    BTW IMHO you may consider using a size of thread pool relative to the number of core/processor instead of the fix 4 value :)

        private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
        private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
        private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    
    public static final Executor THREAD_POOL_EXECUTOR
                = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                        TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
    

    Credit to AsynTask

    Cheers

    opened by nhachicha 1
  • NoSQL instance and its dependencies

    NoSQL instance and its dependencies

    What about single NoSQL instance for context? sounds like a great idea. Same for serializer/deserializer as optional dependency.

    Like: new NoSQL(context); new NoSQL(context, serializer, deserializer); //maybe a single interface for both?

    take a look at Picasso instance creation for example. Builder. https://github.com/square/picasso/blob/master/picasso/src/main/java/com/squareup/picasso/Picasso.java#L491

    Why its good? i dont need to provide context and my (de)serializers on every call.

    Do we still need NoSQL.with(context)? Yes.

    Im not sure about .using() method name.

    opened by dsvoronin 1
  • NoSQL should use applicationContext to avoid memory leak

    NoSQL should use applicationContext to avoid memory leak

    as pointed out by daniel_sk (http://www.reddit.com/r/androiddev/comments/2dktqe/releasing_simplenosql_data_library_for_easy/), the NoSQL.with(Context) method should use getApplicationContext to prevent leaking an activity.

    bug 
    opened by Jearil 1
  • SQLite cursor must be closed

    SQLite cursor must be closed

    as pointed out by daniel_sk (http://www.reddit.com/r/androiddev/comments/2dktqe/releasing_simplenosql_data_library_for_easy/) the cursor is never closed and is a resource leak.

    bug 
    opened by Jearil 1
  • Utility classes should not have public constructors

    Utility classes should not have public constructors

    This pull request is focused on resolving occurrences of Sonar rule squid:S1118 - “Utility classes should not have public constructors ”. You can find more information about the issue here: https://dev.eclipse.org/sonar/rules/show/squid:S1118 Please let me know if you have any questions. Ayman Abdelghany.

    opened by AymanDF 0
  • Failed to change locale for db

    Failed to change locale for db

    Today I've received the following crash when the app tried to delete some entities. It's the first time I am receiving this error, I did not change anything in the calling code.

    Fatal Exception: android.database.sqlite.SQLiteException
    Failed to change locale for db '/data/user/0/com.my.app/databases/simplenosql.db' to 'en_US'.
    

    As far as I understand https://stackoverflow.com/a/19491862/2350644 might fix the issue. I.e. in SimpleNoSQLDBHelper.java change the constuctor call from this:

    public SimpleNoSQLDBHelper(Context context, DataSerializer serializer, DataDeserializer deserializer) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            this.serializer = serializer;
            this.deserializer = deserializer;
        }
    

    to this:

    public SimpleNoSQLDBHelper(Context context, DataSerializer serializer, DataDeserializer deserializer) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION, SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.OPEN_READWRITE);
            this.serializer = serializer;
            this.deserializer = deserializer;
        }
    

    I wasn't yet able to reproduce this error and test if this really works. I will answer to this post (and possibly create a PR) if it solves the error.

    Here is the detailed stack trace:

    Fatal Exception: android.database.sqlite.SQLiteException
    Failed to change locale for db '/data/user/0/com.my.app/databases/simplenosql.db' to 'en_US'.
    android.database.sqlite.SQLiteConnection.setLocaleFromConfiguration (SQLiteConnection.java:567)
    android.database.sqlite.SQLiteConnection.open (SQLiteConnection.java:305)
    android.database.sqlite.SQLiteConnection.open (SQLiteConnection.java:215)
    android.database.sqlite.SQLiteConnectionPool.openConnectionLocked (SQLiteConnectionPool.java:705)
    android.database.sqlite.SQLiteConnectionPool.open (SQLiteConnectionPool.java:272)
    android.database.sqlite.SQLiteConnectionPool.open (SQLiteConnectionPool.java:239)
    android.database.sqlite.SQLiteDatabase.openInner (SQLiteDatabase.java:1292)
    android.database.sqlite.SQLiteDatabase.open (SQLiteDatabase.java:1247)
    android.database.sqlite.SQLiteDatabase.openDatabase (SQLiteDatabase.java:903)
    android.database.sqlite.SQLiteDatabase.openDatabase (SQLiteDatabase.java:893)
    android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked (SQLiteOpenHelper.java:355)
    android.database.sqlite.SQLiteOpenHelper.getWritableDatabase (SQLiteOpenHelper.java:298)
    com.colintmiller.simplenosql.db.SimpleNoSQLDBHelper.deleteEntity (SimpleNoSQLDBHelper.java:75)
    com.colintmiller.simplenosql.threading.DataDispatcher.delete (DataDispatcher.java:106)
    com.colintmiller.simplenosql.threading.DataDispatcher.run (DataDispatcher.java:80)
    
    opened by hiasel 0
  • SQLiteDatabaseCorruptException: file is encrypted or is not a database (code 26)

    SQLiteDatabaseCorruptException: file is encrypted or is not a database (code 26)

    In certain cases I get reports of the following error, however, I am unable to reproduce it reliably right now. I am not sure if it has to do directly with this library, but I am using it in my project. I do not have file encryption.

    Does this happen for someone else as well, by any chance. Do you have a clue, of it is caused by the library, or if it is an error of SQLLite or the android file system.

    According to this: https://sqlite.org/rescode.html#notadb the db file was not existing, which shouldn't be the case.

    2018-11-19 10:48:30.751 12786-12859/? E/AndroidRuntime: FATAL EXCEPTION: Thread-13
        Process: com.myapp.example, PID: 12786
        android.database.sqlite.SQLiteDatabaseCorruptException: file is encrypted or is not a database (code 26)
            at android.database.sqlite.SQLiteConnection.nativeExecuteForLong(Native Method)
            at android.database.sqlite.SQLiteConnection.executeForLong(SQLiteConnection.java:599)
            at android.database.sqlite.SQLiteSession.executeForLong(SQLiteSession.java:652)
            at android.database.sqlite.SQLiteStatement.simpleQueryForLong(SQLiteStatement.java:107)
            at android.database.DatabaseUtils.longForQuery(DatabaseUtils.java:842)
            at android.database.DatabaseUtils.longForQuery(DatabaseUtils.java:830)
            at android.database.sqlite.SQLiteDatabase.getVersion(SQLiteDatabase.java:940)
            at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:311)
            at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:262)
            at com.colintmiller.simplenosql.db.SimpleNoSQLDBHelper.getEntities(SimpleNoSQLDBHelper.java:116)
            at com.colintmiller.simplenosql.db.SimpleNoSQLDBHelper.getEntities(SimpleNoSQLDBHelper.java:107)
            at com.colintmiller.simplenosql.threading.DataDispatcher.retrieve(DataDispatcher.java:121)
            at com.colintmiller.simplenosql.threading.DataDispatcher.run(DataDispatcher.java:83)
    
    opened by peshkira 2
  • Update Readme to correct not close

    Update Readme to correct not close "<" error

    NoSQL.with(context).using(SampleBean.class)
        .bucketId("bucket")
        .entityId("entityId")
        .retrieve(new RetrievalCallback<SampleBean>() {
        public void retrieveResults(List<NoSQLEntity<SampleBean>> entities) {
            // Display results or something 
            SampleBean firstBean = entities.get(0).getData(); // always check length of a list first...
        }   
    });
    In this code the writter forgot to close the "<" and this caused errors when the code is used. Hereby the error is corrected from the readme.
    opened by orklar 0
  • Crash somewhere on start

    Crash somewhere on start

    Any ideas how to prevent this from crashing? We have no control over this code from the app.

    Fatal Exception: android.database.sqlite.SQLiteException: table simplenosql already exists (code 1)
    #################################################################
    Error Code : 1 (SQLITE_ERROR)
    Caused By : SQL(query) error or missing database.
    	(table simplenosql already exists (code 1))
    #################################################################
           at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(SQLiteConnection.java)
           at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:817)
           at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
           at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
           at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1878)
           at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1807)
           at com.colintmiller.simplenosql.db.SimpleNoSQLDBHelper.onCreate(SimpleNoSQLDBHelper.java:54)
           at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:251)
           at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
           at com.colintmiller.simplenosql.db.SimpleNoSQLDBHelper.getEntities(SimpleNoSQLDBHelper.java:116)
           at com.colintmiller.simplenosql.db.SimpleNoSQLDBHelper.getEntities(SimpleNoSQLDBHelper.java:107)
           at com.colintmiller.simplenosql.threading.DataDispatcher.retrieve(DataDispatcher.java:121)
           at com.colintmiller.simplenosql.threading.DataDispatcher.run(DataDispatcher.java:83)
    
    opened by ghost 0
  • Crash due to database lock (Random)

    Crash due to database lock (Random)

    Getting random crashes due to database lock, even when I' writing only once in a bucket on a activity

    Crash Log

    android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5) at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method) at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:780) at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788) at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86) at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1473) at com.colintmiller.simplenosql.db.SimpleNoSQLDBHelper.saveEntity(SimpleNoSQLDBHelper.java:70) at com.colintmiller.simplenosql.threading.DataDispatcher.save(DataDispatcher.java:96) at com.colintmiller.simplenosql.threading.DataDispatcher.run(DataDispatcher.java:77)

    opened by ghost 2
Owner
Colin Miller
Colin Miller
基于属性委托的 key-value 方式存储封装

KvPref 基于属性委托的 key-value 方式存储封装 使用 allprojects { repositories { ... maven { url 'https://jitpack.io' } } } dependencies {

Espoir 8 Jul 26, 2022
sql-delight example, a plugin by Square which is pure kotlin and it is useful in kmm

Sql-Delight-Example01 Developed by Mahdi Razzaghi Ghaleh first example of sql-delight What is SqlDelight? Kotlin Multiplatform is one of the most inte

rq_mehdi 0 Jan 24, 2022
Android library for auto generating SQL schema and Content provider

Android-AnnotatedSQL Android library for auto generating SQL schema and Content Provider by annotations. You will get a full-featured content provider

Gennadiy Dubina 161 Dec 3, 2022
requery - modern SQL based query & persistence for Java / Kotlin / Android

A light but powerful object mapping and SQL generator for Java/Kotlin/Android with RxJava and Java 8 support. Easily map to or create databases, perfo

requery 3.1k Dec 29, 2022
A lightweight wrapper around SQLiteOpenHelper which introduces reactive stream semantics to SQL operations.

SQL Brite A lightweight wrapper around SupportSQLiteOpenHelper and ContentResolver which introduces reactive stream semantics to queries. Deprecated T

Square 4.6k Jan 5, 2023
Upsert DSL extension for Exposed, Kotlin SQL framework

Exposed Upsert Upsert DSL extension for Exposed, Kotlin SQL framework. Project bases on various solutions provided by community in the official "Expos

Dzikoysk 23 Oct 6, 2022
Upsert DSL extension for Exposed, Kotlin SQL framework

Exposed Upsert Upsert DSL extension for Exposed, Kotlin SQL framework. Project bases on various solutions provided by community in the official "Expos

Reposilite Playground 23 Oct 6, 2022
A simple ToDo app to demonstrate the use of Realm Database in android to perform some basic CRUD operations like Create, Update and Delete.

Creating a Realm Model Class @RealmClass open class Note() : RealmModel { @PrimaryKey var id: String = "" @Required var title: String

Joel Kanyi 15 Dec 18, 2022
A blazing fast, powerful, and very simple ORM android database library that writes database code for you.

README DBFlow is fast, efficient, and feature-rich Kotlin database library built on SQLite for Android. DBFlow utilizes annotation processing to gener

Andrew Grosner 4.9k Dec 30, 2022
A blazing fast, powerful, and very simple ORM android database library that writes database code for you.

README DBFlow is fast, efficient, and feature-rich Kotlin database library built on SQLite for Android. DBFlow utilizes annotation processing to gener

Andrew Grosner 4.9k Dec 30, 2022
AndroidQuery is an Android ORM for SQLite and ContentProvider which focuses on easy of use and performances thanks to annotation processing and code generation

WARNING: now that Room is out, I no longer maintain that library. If you need a library to easy access to default android ContentProvider, I would may

Frédéric Julian 19 Dec 11, 2021
Exposed spring integration and code generator for dsl interface

Infra-ORM 欢迎使用 Infra-ORM, 这是一个基于 Exposed 的 ORM 框架,可以和 Spring Boot 集成良好,如果你是 Kotlin 开发者,推荐你试试 Exposed, 配合 Infra-ORM 可以给你带来最佳的开发体验。 为什么造这个轮子? Exposed 提供

Red Sparrow 1 Jan 2, 2022
LiteOrm is a fast, small, powerful ORM framework for Android. LiteOrm makes you do CRUD operarions on SQLite database with a sigle line of code efficiently.

#LiteOrm:Android高性能数据库框架 A fast, small, powerful ORM framework for Android. LiteOrm makes you do CRUD operarions on SQLite database with a sigle line

马天宇 1.5k Nov 19, 2022
Starter code for Android Kotlin Fundamentals Codelab 6.1 Room

TrackMySleepQuality - Starter Code Starter code for Android Kotlin Fundamentals Codelab 6.1 Room Introduction TrackMySleepQuality is an app for record

YamanAswal 0 Jan 15, 2022
⚒ A multiplatform-friendly common utility module targeting code flexibility

⚒ mechanism A multiplatform-friendly common utility module targeting code flexibility. ?? Getting Started You can find information about how to use th

Hexalite Network 3 Aug 31, 2022
⚒ A multiplatform-friendly common utility module targeting code flexibility

⚒ mechanism A multiplatform-friendly common utility module targeting code flexibility. ?? Getting Started You can find information about how to use th

Southdust Team 3 Aug 31, 2022
Code samples for the second edition of "Kotlin in Action".

Code samples for Kotlin in Action, Second Edition This project contains the code samples from book "Kotlin in Action, Second Edition" by Roman Elizaro

Kotlin 16 Dec 29, 2022
An Android helper class to manage database creation and version management using an application's raw asset files

THIS PROJECT IS NO LONGER MAINTAINED Android SQLiteAssetHelper An Android helper class to manage database creation and version management using an app

Jeff Gilfelt 2.2k Dec 23, 2022
ORMDroid is a simple ORM persistence framework for your Android applications.

ORMDroid is a simple ORM persistence framework for your Android applications, providing an easy to use, almost-zero-config way to handle model persist

Ross Bamford 87 Nov 10, 2022