pardom-zz / ollie Goto Github PK
View Code? Open in Web Editor NEWCompile-time active record ORM for Android
License: Apache License 2.0
Compile-time active record ORM for Android
License: Apache License 2.0
Is someone using this?
Do i miss something?
Project build.gradle
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
}
}
allprojects {
repositories {
jcenter()
mavenCentral()
}
}
Module build.gradle
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.example.android.chat"
minSdkVersion 21
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
}
apt {
arguments {
androidManifestFile variant.outputs[0].processResources.manifestFile
resourcePackageName 'com.example.android.chat'
}
}
dependencies {
compile 'com.android.support:support-v4:21.0.3'
compile 'com.joanzapata.android:android-iconify:1.0.8'
compile 'com.jakewharton:butterknife:6.0.0'
compile 'com.michaelpardo:ollie:0.3.1'
apt 'com.michaelpardo:ollie-compiler:0.3.1'
compile fileTree(dir: 'libs', include: ['*.jar'])
}
I tried it also with:
dependencies {
compile 'com.android.support:support-v4:21.0.3'
compile 'com.joanzapata.android:android-iconify:1.0.8'
compile 'com.jakewharton:butterknife:6.0.0'
compile 'com.michaelpardo:ollie:0.3.1'
provided 'com.michaelpardo:ollie-compiler:0.3.1'
compile fileTree(dir: 'libs', include: ['*.jar'])
}
But both versions result in the error
Error:(5, 30) Gradle: error: cannot find symbol class Model
SDK-Version: 24.0.2
Gradle: 2.2.1
IDE: IntelliJ CE 14
If an enum doesn't have a TypeAdapter the compiler should apply a generic enum adapter.
I want to make sure that this assertion is what people expect when an entity is deleted:
Note note = new Note();
note.body = "this is draft";
note.save();
Delete.from(Note.class).execute();
assertThat(note.id).isNull();
There are several operations we might expect (or not) when an entity is deleted. These operations could be supported by overloading Delete.execute()
with booleans.
id
to null.I think it's reasonable to set id
to null
because it no long exists in the database, however I can think of scenarios where there is use for it.
I don't think it's reasonable (as a default) to set the entity to null. If there are entities used elsewhere in the app, they will then be null.
Removing entities from the cache seems reasonable, since there is no scenario where they will be retrieved from it. However, it won't hurt to leave them in there since they will be evicted naturally from lack of use (LRU cache). The only issue with this is that the cache will eventually grow to its max size.
My preference is to only set id
to null
and provide an override of Delete.execute()
whereby passing in false
will not set the id
to null
.
Thoughts?
failing tests #9
03-22 17:11:14.797 11546-25818/at.... W/SQLiteConnectionPool﹕ The connection pool for database '.../databases/MyDatabase.db' has been unable to grant a connection to thread 26636 (Thread-26636) with flags 0x2 for 30.001001 seconds.
Connections: 0 active, 1 idle, 0 available.
I sometimes get a deadlock when working on the database on the same time with different threads.
When writing bulk data I do something like this often:
SQLiteDatabase db = Ollie.getDatabase();
db.beginTransaction();
try {
...
// saving operations
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
Is there a way to prevent this deadlock?
Is it possible to create a TypeAdapters for Lists? Below is what I'm trying at the moment.
@Table("articles")
public class Article extends Model {
@Column("tags")
private List<String> tags;
}
public class StringListTypeAdapter extends TypeAdapter<List<String>, String> {
@Override
public String serialize(List<String> value) {
return StringUtil.join(value, "|||");
}
@Override
public List<String> deserialize(String value) {
return Arrays.asList(value.split("|||"));
}
}
The compile fails with the following stack trace:
Caused by: java.lang.NullPointerException
at ollie.internal.codegen.element.TypeAdapterElement.getDeserializedQualifiedName(TypeAdapterElement.java:69)
at ollie.internal.codegen.Registry.addTypeAdapterModel(Registry.java:91)
at ollie.internal.codegen.step.TypeAdapterStep.process(TypeAdapterStep.java:60)
at ollie.internal.codegen.OllieProcessor.process(OllieProcessor.java:76)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
... 32 more
If it's not possible to do this, is there a good workaround that anyone uses to support Lists in their model?
Could Ollie (Model) made Parcelable?
Why can't I assign the label "question"?
I have an integer column with null-values inside. I store dates in this col.
If I load the ollie-object I always get dates with 0 -> 01.01.1970
How can I get the null value (stored in the database) back?
If I load the value from db with fetchValue(String.class) I get the null value...
Hello. Before anything else, thanks for creating Ollie. Now, I cannot understand why, but I'm unable to build my project with this library. The only error I'm seeing is:
Error:Execution failed for task ':SMSX:compileDebugJava'.
> java.lang.NullPointerException
That's it. Nothing else. Model class: https://gist.github.com/anonymous/3c3cb0465b8ecdd2ee57
I'm initializing Ollie inside my Application class. Any idea how to fix this? Thank you.
Update: So replacing the primitives in my model class with their Wrapper classes fixed the issue. Am I doing this right?
In Android Studio I right click on core/java/test package and hit "run all tests". This results in following error:
!!! JUnit version 3.8 or later expected:
java.lang.RuntimeException: Stub!
I think that I need to adjust run config for tests, but I don't have idea how exactly.
when I define a model, and then run the app, it has errors.
Error:Execution failed for task ':app:compileDebugJava'.
java.lang.NoClassDefFoundError: android/content/ContentValues
i Use api 21.
It would be a life saver :)
How about changing the sourceCompatibility to 1.7?
public class StringArrayAdapter extends TypeAdapter<ArrayList<String>, String> {
@Override
public String serialize(ArrayList<String> value) {
return new Gson().toJson(value);
}
@Override
public ArrayList<String> deserialize(String value) {
return new Gson().fromJson(value, new TypeToken<ArrayList<String>>(){}.getType());
}
}
How to use it?
I'm trying to save a model to the database, and it's not saving for some reason. I have another model that saves fine. I can't seem to nail down the issue.
The object I'm trying to save is call "Message". Here's what it looks like:
public class Message extends Model {
@Column("message_slug")
public String message_slug;
@Column("message_context")
public String message_context;
@Column("message_description")
public String message_description;
public Message() {
}
public String getMessage_slug() {
return message_slug;
}
public String getMessage_description() {
return message_description;
}
}
When I try to save the messages in this way, they don't get saved to the database:
ArrayList<Message> messages = gb.create().fromJson(o.getJSONArray("messages").toString(), listType);
// bulk insert the messages
Ollie.getDatabase().beginTransaction();
try {
for (Message message : messages) {
message.save();
}
Ollie.getDatabase().setTransactionSuccessful();
} catch (Exception e) {
e.printStackTrace();
}
finally {
Ollie.getDatabase().endTransaction();
}
If I create the Message as save as follows, it does get added to the database:
Message message = new Message();
message.context = "context";
message.message_description = "description";
message.message_slug = "message_slug";
message.save();
I'm not getting any errors or anything to indicate why the messages wouldn't be saving. Do you know way the messages wouldn't be getting added?
@pardom, I've thinking about STI implementation in Ollie. The main idea is to be able to store models with different logic but same data structure in a single table, something like this:
@Table(name = "attachments", inheritanceColumn = "Type")
public abstract class Attachment extends Model {
@Column("Url")
public String Url;
@Column("Type")
public String Type;
}
@InheritTable(type = "image_attachment")
public class ImageAttachment extends Attachment {
}
@InheritTable(type = "video_attachment")
public class VideoAttachment extends Attachment {
}
One way is to extend Ollie.processCursor()
with idea to build entity instance based on inheritance_column
value, how do you think, is it correct level for this logic in concept of Ollie?
AndroidDatabaseLibraryComparison is a project that compares the performance of different android orm/db libraries.
The results can be found here
At the moment, it covers greendao, sugar, activeandroid, sprinkles and dbflow (and ormlite is on the way)
Adding Ollie into the mix would be interesting.
What do you think?
I save objects, select, delete...
I only get a log of the select (load):
"V/Ollie﹕ SQLiteQuery: SELECT cars.* FROM cars WHERE _id=?"
but no delete/update or insert.
I use the load-methode like:
public static Car load(long id) {
return Select.from(Car.class).where(_ID + "=?", id).fetchSingle();
}
First off, I'm totally looking forward to continuing to play around with ollie. I stumbled across this issue while testing our ollie in my application. I had a entity lets call it "notebook" which contained a "note". I could successfully create the notebook and see it in my notebook list view and the database looked correct. But once I killed the app and reopened it I would get NPE in my notebook list view because the note was null (even though an tag id was successfully populated in the database)
I traced it back to the ModelAdapter which was attempting to load the Note using the field on the entity. The note field on the entity was null because the entity was being loaded fresh from the database.
Here is the generated source file:
public final class Notebook$$ModelAdapter extends ModelAdapter<Notebook> {
public final Class<? extends Model> getModelType() {
return Notebook.class;
}
public final String getTableName() {
return "notebooks";
}
public final String getSchema() {
return "CREATE TABLE IF NOT EXISTS notebooks (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, note INTEGER)";
}
public final void load(Notebook entity, Cursor cursor) {
entity.id = cursor.getLong(cursor.getColumnIndex("_id"));
entity.name = cursor.getString(cursor.getColumnIndex("name"));
entity.note = Ollie.getOrFindEntity(entity.note.getClass(), cursor.getLong(cursor.getColumnIndex("note"))); // This is the NPE
}
public final Long save(Notebook entity, SQLiteDatabase db) {
ContentValues values = new ContentValues();
values.put("_id", entity.id);
values.put("name", entity.name);
values.put("note", entity.note != null ? entity.note.id : null);
return insertOrUpdate(entity, db, values);
}
public final void delete(Notebook entity, SQLiteDatabase db) {
db.delete("notebooks", "_id=?", new String[]{entity.id.toString()});
}
}
I have multiple DTOs to parse data from my application's backend API. In this API all objects id
s are String
. However Ollie's Model
class id
property is Long
, so it conflicts with my API.
In ActiveAndroid Model's id
was private and there was an getId
method that suited very well in this situation. The application is already working with ActviveAndroid and the API can't be changed.
Have you any clues?
Btw, I'm using Retrofit and Gson on the API side.
Seems like Delete() trying to materialize new entity
failing tests #9
I gathered that the following code must be called:
Ollie.with(context)
.setName(DB_NAME)
.setVersion(DB_VERSION)
.setLogLevel(LogLevel.FULL)
.setCacheSize(CACHE_SIZE)
.init();
What is the best place?
The application initialization?
How should I set CACHE_SIZE
?
note: an android sample would be a huge help to get things started.
Just want to know. Maybe I have some questions in future. :-)
There are 5000 cars inside the table.
Here it would be really nice to have a logging.
How can I delete all the data in one table?
new Delete().from(Car.class).execute();
Gives me a "java.lang.IllegalArgumentException: Empty bindArgs".
EDIT:
With "new Delete().from(Car.class);" I don't get an error - but nothing isn't deleted.
I haven't found an @index
annotation for the Model
classes.
How are indexes generated?
It would be nice to see an option to use getters and setters when loading and saving models.
For instance:
@Model("items")
public class Item {
@Column(value = "name", useGetterAndSetter = true)
private String mName;
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
}
Alternatively, use @Getter
and @Setter
annotations. I'm not familiar with annotation processing, so I'm not sure what would be the easier way to implement.
@Model("items")
public class Item {
@Column("name")
private String mName;
@Getter("name")
public String getName() {
return mName;
}
@Setter("name")
public void setName(String name) {
mName = name;
}
}
if I have an entity with id value, when I call save, it could not be inserted into the database. can you provide model.replace()
method?
when the contentprovider is supported, everytime I save the entity, it will call notifychange()
, sometimes, I want to insert a list of entities into the database, it will call notifychange()
many times, can you provide some funtion to prevent notifychange()
.
I have a pretty basic Model (see below), but I am using gradle-retrolambda if that could affect it.
@Table("Measurements")
public class MeasurementModel extends Model {
@Column("date")
public long date;
@Column("time")
public String time;
@Column("weight")
public double weight;
@Column("fat")
public double fat;
@Column("trend")
public double trend;
Caused by: java.lang.NullPointerException
at ollie.internal.codegen.Registry.getTypeAdapterElement(Registry.java:83)
at ollie.internal.codegen.element.ColumnElement.<init>(ColumnElement.java:73)
at ollie.internal.codegen.step.ModelAdapterStep.addColumnElements(ModelAdapterStep.java:89)
at ollie.internal.codegen.step.ModelAdapterStep.process(ModelAdapterStep.java:65)
at ollie.internal.codegen.OllieProcessor.process(OllieProcessor.java:76)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
What do you think about create some methods to do background operations to the DB?
Hi, so I have just integrated Ollie in my newest app and it is giving me strange errors. It compiles without any errors, but crashes right on startup.
Here's the stacktrace: https://gist.github.com/anonymous/a8d3fcb2fb4cd92a2dc4
I believe I've added it using Gradle the right away:
compile 'com.michaelpardo:ollie:0.3.1'
provided 'com.michaelpardo:ollie-compiler:0.3.1'
Here's the model:
@Table(SavedDefinitions.TABLE_NAME)
public class SavedDefinitionEntry extends Model {
// Data
@Column(SavedDefinitions.KEY_WORD) public String mWord;
@Column(SavedDefinitions.KEY_PHONETIC_TEXT) public String mPhoneticText;
public SavedDefinitionEntry(String mWord, String mPhoneticText) {
this.mWord = mWord;
this.mPhoneticText = mPhoneticText;
}
}
I am having a hard time solving this error. Any ideas? :(
Error:A problem occurred configuring project ':app'.
Could not resolve all dependencies for configuration ':app:_debugCompile'.
Could not find Ollie:ollie:unspecified.
Required by:
MyApplication:app:unspecified > com.michaelpardo:ollie-compiler:0.2.0-SNAPSHOT
Will u continue to maintenance the ActiveAndroid ? Because we used AA in all of our project 。 And I like AA very much。
01-14 18:25:58.495 10589-10608/com.android.raz.gathering E/Ollie﹕ Failed to initialize.
java.lang.ClassNotFoundException: ollie.AdapterHolderImpl
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:308)
at java.lang.Class.forName(Class.java:272)
at ollie.Ollie.init(Ollie.java:133)
at ollie.Ollie$Builder.init(Ollie.java:298)
should I create new class AdapterHolderImpl????
I'm getting a NPE and I don't know why. :-(
:app:compileDebugJava FAILED
Caused by: java.lang.NullPointerException
at ollie.internal.codegen.Registry.getTypeAdapterElement(Registry.java:83)
at ollie.internal.codegen.element.ColumnElement.(ColumnElement.java:73)
at ollie.internal.codegen.step.ModelAdapterStep.addColumnElements(ModelAdapterStep.java:89)
at ollie.internal.codegen.step.ModelAdapterStep.process(ModelAdapterStep.java:65)
at ollie.internal.codegen.OllieProcessor.process(OllieProcessor.java:76)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:793)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:722)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1700(JavacProcessingEnvironment.java:97)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1029)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1163)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1108)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:824)
at com.sun.tools.javac.main.Main.compile(Main.java:439)
... 65 more
BUILD FAILED
Currently model constructors are retrieved using reflection every time cursor is mapped to an entity. Caching the constructor might improve performance. Better yet, the model adapter could have a factory method which returns a new instance of the model.
I have a model like this:
@Table("note")
public class Note extends Model {
public static final String TITLE = "title";
public static final String TAG = "tag";
@Column(TITLE)
public String title;
@Colume(TAG)
public Tag tag;
}
Tag is also a model. Is there a way that, when I say note.delete()
that the corresponding tag also gets deleted (like with e.g. @ForeignKey(onDelete = CASCADE)
).
I've extracted common fields into base abstract class, but run into an issue:
@Table("")
public abstract class BaseModel extends Model{
@Column("created_at")
@NotNull
public Date createdAt;
@Column("updated_at")
@NotNull
public Date updatedAt;
}
@Table("notes")
public class Note extends BaseModel{
}
At this point I expected that Ollie will create table notes
with created_at
and updated_at
columns, but instead got this error
java.lang.RuntimeException: Unable to get provider com.example.ContentProvider: android.database.sqlite.SQLiteException: near "(": syntax error (code 1): , while compiling: CREATE TABLE IF NOT EXISTS (_id INTEGER PRIMARY KEY AUTOINCREMENT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)
Obviously compiler trying to process abstract class BaseModel
since it has @Table
annotation, but i am not able to omit it, because it is required by @Column
.
Hello, I'm receiving several crash reports from one user with this stack-trace:
java.lang.RuntimeException: Unable to start receiver com.tattva.sup.receivers.SmsReceiver: java.lang.NullPointerException
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2856)
at android.app.ActivityThread.access$1700(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1440)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5883)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at ollie.internal.ModelAdapter.insertOrUpdate(ModelAdapter.java:43)
at ollie.FileLogItem$$ModelAdapter.save(FileLogItem$$ModelAdapter.java:37)
at ollie.FileLogItem$$ModelAdapter.save(FileLogItem$$ModelAdapter.java:9)
at ollie.Ollie.save(Ollie.java:247)
at ollie.Model.save(Model.java:74)
at com.tattva.sup.database.FileLog.write(FileLog.java:66)
at com.tattva.sup.database.FileLog.writeStartOfNewBlock(FileLog.java:84)
at com.tattva.sup.receivers.SmsReceiver.logToFileStartOfNewBlock(SmsReceiver.java:171)
at com.tattva.sup.receivers.SmsReceiver.onReceive(SmsReceiver.java:50)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2845)
... 10 more
That is, at this line inside ModelAdapter
:
entity.id = db.insert(getTableName(), null, values);
which means that the SQLiteDatabase
is null. Is this happening because Ollie failed to initialize itself? But the chances of that happening is very low. So maybe that line got called before init() could finish because I am initializing Ollie in a separate thread in my Application class.
I can add this fix, but it would be great if you could confirm this :)
I need a BooleanAdapter
which is able to cope with null values. (well, it would be convenient at least)
Is there a possibility to overwrite the existing BooleanAdapter
?
list data inerting must be in the transaction, but Ollie just has an inserting one by one function.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.