Giter Site home page Giter Site logo

androrm's Introduction

ANDRORM ORM FOR ANDROID

For installation instructions and detailed information please visit:

http://www.androrm.com/

androrm's People

Contributors

frontendphil avatar gak avatar goncharov avatar ynh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

androrm's Issues

BLOB support

As reported by some users, BLOB support needs to be added.

Range queries with date fields

It is currently not possible to query models based on information stored in date fields. It should be possible to create filters for =, >, <, >=, <=.

update

hi phil as I can I update a table object, simply put 0-1 for example

Cursor returned by DatabaseAdapter seems volatile.

First off, I love your work.
Calls to the ORM seems to behave reliably even when initiated from multiple threads. However I'm experiencing issues using Androrm's DatabaseAdapter with a ContentProvider.

An example:

public class OWContentProvider extends ContentProvider {
    public Cursor query(Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder) {
      DatabaseAdapter adapter = DatabaseAdapter.getInstance(getContext().getApplicationContext());
      ...
      Cursor result = adapter.open().query(SQLString);
      adapter.close();  // I've tried removing this line and modifying DatabaseAdapter to never close it's connection
      return
    }
} 

Within a few requests this will inevitably produce a java.lang.IllegalStateException: attempt to re-open an already-closed object or a android.database.StaleDataException: Attempting to access a closed CursorWindow.Most probable cause: cursor is deactivated prior to calling this method. . If I call adapter.close() before returning I'll get the IllegalStateException pretty reliably.

Is there a preferred way to safely get a Cursor via androrm?

Example java.lang.IllegalStateException trace. The ContentProvider calls are coming from a Loader which is controlled by a AutoCompleteTextView.
12-23 01:17:11.155: E/AndroidRuntime(11696): java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT _id, name FROM owrecordingtag where name LIKE "%p%" 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:58) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:151) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:124) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:214) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.database.CursorWrapper.moveToPosition(CursorWrapper.java:162) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.support.v4.widget.CursorAdapter.getItem(CursorAdapter.java:213) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.widget.AutoCompleteTextView.buildImeCompletions(AutoCompleteTextView.java:1122) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1082) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:971) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.widget.AutoCompleteTextView.onFilterComplete(AutoCompleteTextView.java:953) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:285) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.os.Handler.dispatchMessage(Handler.java:99) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.os.Looper.loop(Looper.java:137) 12-23 01:17:11.155: E/AndroidRuntime(11696): at android.app.ActivityThread.main(ActivityThread.java:5039) 12-23 01:17:11.155: E/AndroidRuntime(11696): at java.lang.reflect.Method.invokeNative(Native Method) 12-23 01:17:11.155: E/AndroidRuntime(11696): at java.lang.reflect.Method.invoke(Method.java:511) 12-23 01:17:11.155: E/AndroidRuntime(11696): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 12-23 01:17:11.155: E/AndroidRuntime(11696): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 12-23 01:17:11.155: E/AndroidRuntime(11696): at dalvik.system.NativeStart.main(Native Method)

Renaming of Models

As users may wish to rename their models but also want to keep all existing data, it has to be possible to rename old tables into new ones.

Add data fields to existing model

As part of the migration support it has to be possible to add data fields to a model after it has been created for the first time.

Automatic Model discovery

In the current implementation you need to specify all your model classes by hand. It would be a neat feature, if you only had to specify the package in which the classes reside or if the application could determine everything on it's own.

Limit Errors

There is a problem with the limit(int offset, int limit) function. it only works with 0 offset. when another offset is set, it returns more than the limit index. Thanks, hoping to hear from you soon.

Iterative migrations.

Migrations have to be rolled out iteratively so that it does not matter if a user upgrades from version 0.1 to 0.2 of and app or 0.1 to 0.5. The system should recognize which migrations have already been applied and only apply the missing ones. Therefore androrm itself needs to keep a record of the migrations.

Transactions

It would be good to have transactions, e.g.:

DatabaseAdapter db = getDatabaseAdapter(context);
db.beginTransaction()
ExampleModel new m = ExampleModel();
m.save();
db.setTransactionSuccessful();
db.endTransaction();

I started implementing this myself but it became problematic.

Each statement in the DatabaseAdapter class has an open() and close() call surrounding it. For an SQLite transaction, the database connection should remain open for each statement, then finally closed after endTransaction() is called.

I tried to trick open()/close() by storing a "transactionInProgress" boolean in DatabaseAdapter, which within open()/close() simply returns if transactionInProgress is true. Unfortunately when Model.save() is called, a new DatabaseAdapter is instantiated and therefore loses the transactionInProgress status.

There is a (probably undesirable) way to get around it, by setting boolean to static, similarly to DATABASE_NAME. I went down this road and it became necessary to make mDb also static, since mDb is set in open(). This is how I've implemented transactions in my code.

Another way (also probably undesirable) is to force the user to call open() and close() around any database access. This way transactions will just work as expected.

There's probably a nicer way of doing this. Thoughts?

Can't delete a row.

I've saved many accounts into my database, here is my code:

public class Account extends Model {
protected CharField username;
protected CharField hobby;
protected ManyToManyField<Account, TimeDetail> time;

public Account() {
    super();
    username = new CharField(20);
    hobby = new CharField(100);
    time = new ManyToManyField<Account, TimeDetail>(Account.class, TimeDetail.class);
}

public void setUsername(String name) {
    username.set(name);
}

public void setHobby(String hobby) {
    this.hobby.set(hobby);
}

public String getUsername() {
    return username.get();
}

public String getHobby() {
    return hobby.get();
}

public static final QuerySet<Account> objects (Context context) {
    return objects(context, Account.class);
}

}
Now I want to delete an account with a specified username. I've read the document and know that I must know the id of the object, while I don't know the id of the object, I just know the username data field. Can I delete the account with a filter or something like that?
Thanks in advance.

ForeignKey null

Filed in phabricator:

I have a "News" object with a ForeignKeyField to a "Shop" object. But not all "News" has a "Shop" designated. So the ForeignKeyField can be null.
However, I can't save an object with the ForeignKey field to null.

Actu actu = new Actu();
actu.setBody("Blah");
actu.save(this);

05-11 13:57:15.935: E/AndroidRuntime(26416): Caused by: java.lang.NullPointerException
05-11 13:57:15.935: E/AndroidRuntime(26416): at com.orm.androrm.ForeignKeyField.set(ForeignKeyField.java:172)
05-11 13:57:15.935: E/AndroidRuntime(26416): at com...models.Actu.setShop(Actu.java:64)

Is there a way that I didn't think about ? Or do I have to fork the project and code it ?

Thanks !

Dumb class names

I just wasted hours scratching my head about an sqlite excpetion raised
during initialization of the androrm database. I only write this here because
I cannot find another way of contacting anyone involved (feel free to mark this
as solved immediately...).

The trouble stemmed from the fact that I foolishly named a class Transaction
and then tried to manage it via androrm... Maybe you could escape the class
names in the sql statements? Or just put up a big red warning to not used sql
reserved keywords as class names.

Better README for github

The current readme forces users to visit the androrm web page. That should be optional. Add a better introduction to the existing readme.

OrderBy of Integer: lexicographically not numerical

I tried to order my model by mId which is definitely a integer field. However the ordering happens lexicographically. I'm pretty sure that there isn't any error in my code.
I explored this issue on a Samsung xCover.

QuerySet<Match> request = mTheUser.getMatchesField().get(User.getContext(), mTheUser).orderBy("mId");

Where mTheUser is some Model extending a AbstractBaseModel as shown below.

User.java

import com.orm.androrm.QuerySet;
import com.orm.androrm.field.OneToManyField;

/**
 * the user model.
 * @author Ralf
 *
 */
public class User extends AbstractBaseModel {
    /**
     * the matches.
     */
    protected OneToManyField<User, Session> mSessionsField;

    /**
     * the matches.
     */
    protected OneToManyField<User, Match> mMatchesField;

    /**
     * the user constructor.
     */
    public User() {
        super();

        mSessionsField = new OneToManyField<User, Session>(User.class, Session.class);

        mMatchesField = new OneToManyField<User, Match>(User.class, Match.class);
    }

    /**
     * @return the users query set.
     */
    public static QuerySet<User> objects() {
        return User.objects(getContext(), User.class);
    }

    /**
     * @return the mSessionsField
     */
    public OneToManyField<User, Session> getSessionsField() {
        return mSessionsField;
    }

    /**
     * @return the mMatches
     */
    public OneToManyField<User, Match> getMatchesField() {
        return mMatchesField;
    }
}

AbstractBaseModel.java

import java.util.Date;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;

import com.orm.androrm.Model;
import com.orm.androrm.field.BooleanField;
import com.orm.androrm.field.DateField;
import com.orm.androrm.field.IntegerField;

/**
 * The abstract base object.
 * @author Ralf
 *
 */
public abstract class AbstractBaseModel extends Model implements JSONObjectSerializable {
    /**
     * the never date.
     */
    public static final Date NEVER_DATE;

    /**
     * string length.
     */
    public static final int NAME_LENGTH = 64;

    /**
     * gender length.
     */
    public static final int GENDER_LENGTH = 10;

    /**
     * the position name length.
     */
    public static final int POSITION_LENGTH = 64;

    /**
     * the nationality name length.
     */
    public static final int NATIONALITY_LENGTH = 2;

    static {
        NEVER_DATE = new Date();
        NEVER_DATE.setTime(0L);
    }

    /**
     * context.
     */
    protected static Context appContext;

    /**
     * the point in time where a modification took place.
     */
    protected DateField mModificationPoint;

    /**
     * the extern used id.
     */
    protected IntegerField mExternId;

    /**
     * the deleted flag.
     */
    protected BooleanField mDeleted;

    /**
     * the synchronization point.
     */
    protected DateField mSynchronizationPoint;

    /**
     * the base object.
     */
    public AbstractBaseModel() {
        super();

        mModificationPoint = new DateField();
        mSynchronizationPoint = new DateField();
        mSynchronizationPoint.set(NEVER_DATE);
        mExternId = new IntegerField();
        mDeleted = new BooleanField();
        mDeleted.set(false);
    }

    /**
     * @return the context
     */
    public static Context getContext() {
        return appContext;
    }

    /**
     * the context.
     * @param cxt the context to use
     */
    public static void setContext(Context cxt) {
        appContext = cxt;
    }

    /**
     * @return the mModificationPoint
     */
    public Date getModificationPoint() {
        return mModificationPoint.get();
    }

    /**
     * @param modPoint the mModificationPoint to set
     */
    public void setModificationPoint(Date modPoint) {
        this.mModificationPoint.set(modPoint);
    }

    /**
     * @return the mExternId
     */
    public Integer getExternId() {
        return mExternId.get();
    }

    /**
     * @param externId the mExternId to set
     */
    public void setExternId(Integer externId) {
        this.mExternId.set(externId);
    }

    /**
     * @return the mDeleted
     */
    public Boolean isDeleted() {
        return mDeleted.get();
    }

    /**
     * @param state the mDeleted state to set
     */
    public void setDeleted(Boolean state) {
        this.mDeleted.set(state);
    }

    /**
     * @return the mSynchronizationPoint
     */
    public Date getSynchronizationPoint() {
        return mSynchronizationPoint.get();
    }

    /**
     * @param syncPoint the mSynchronizationPoint to set
     */
    public void setSynchronizationPoint(Date syncPoint) {
        this.mSynchronizationPoint.set(syncPoint);
    }

    /**
     * @return the success of saving.
     */
    public boolean save() {
        this.setModificationPoint(new Date());
        return super.save(getContext());
    }

    /**
     * @param id the id to set
     * @return the success of saving.
     */
    public boolean save(int id) {
        this.setModificationPoint(new Date());
        return super.save(getContext(), id);
    }

    @Override
    public JSONObject toJSONObject() throws JSONException {
        JSONObject json = new JSONObject();

        json.put("classtype", this.getClass().getName());
        json.put("extern_id", this.getExternId());
        json.put("deleted", mDeleted.get());
        json.put("modification_point", mModificationPoint.getDateString());

        return json;
    }
}

query

how I can do this query in descending order?, ie high to low

 lst = (ArrayList<CAnotaciones>)objAnotaciones.objects(getContext()).filter(filtro).orderBy("mId").toList();

Model save method does not support chinese ??

hi,
i use androrm made a test, when i set a column by chinese, eg: myModel.setName("测试"); and then save, however there is no record in my database, also didn't report any errors,
so, is there a bug in here?

best,
niles

add donate button

Can you add donate button? I want to make small donation (and I'm sure not just me) to the androrm project :)

Model.save() -> overload to accept (context, double)

I found a DoubleField for use in one of my models as i need to save a number/identifier that's around 12-13 digits long, but when suppressing auto increment for primary key fields, I am unable to pass my double because Model.save() arg2 expects an int.

java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase

I have a project with multiple activities each using fragments. I initialize Androrm from an Activity early in my application flow, and everything seems fine when working with the app from the start.

However I get the following error sometimes if the tablet has been idle for some time and is resumed: "java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase"

This comes from an Activity later in the flow (not the activity that initialized Androrm), but of course the tablet resumes to the last Activity it knows about. I read somewhere what in Android 4.x or later SQL connections are automatically closed now. Are there any suggestions to resolve this crash?

Thanks.

Androrm error??

hi phill, in my project I have androrm, sometimes I a get the following error,  everything works fine but come in when it appears

my log

04-18 18:01:58.551: W/IInputConnectionWrapper(5380): getSelectedText on inactive InputConnection
04-18 18:01:58.551: W/IInputConnectionWrapper(5380): setComposingText on inactive InputConnection
04-18 18:01:58.551: W/IInputConnectionWrapper(5380): getExtractedText on inactive InputConnection
04-18 18:01:58.576: W/System.err(5380): java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.silice.qrstorecomerciales/databases/BdComerciales.db
04-18 18:01:58.576: W/System.err(5380): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
04-18 18:01:58.576: W/System.err(5380): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1310)
04-18 18:01:58.576: W/System.err(5380): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
04-18 18:01:58.576: W/System.err(5380): at com.orm.androrm.DatabaseAdapter.query(DatabaseAdapter.java:342)
04-18 18:01:58.576: W/System.err(5380): at com.orm.androrm.QuerySet.getCursor(QuerySet.java:60)
04-18 18:01:58.576: W/System.err(5380): at com.orm.androrm.QuerySet.getItems(QuerySet.java:188)
04-18 18:01:58.576: W/System.err(5380): at com.orm.androrm.QuerySet.toList(QuerySet.java:274)
04-18 18:01:58.576: W/System.err(5380): at com.silice.categoria.CcategoriaDataSource.TodasCaGorias(CcategoriaDataSource.java:48)
04-18 18:01:58.576: W/System.err(5380): at com.silice.jesus.TopMenu.TopMenu$Categorias.doInBackground(TopMenu.java:280)
04-18 18:01:58.581: W/System.err(5380): at com.silice.jesus.TopMenu.TopMenu$Categorias.doInBackground(TopMenu.java:1)
04-18 18:01:58.581: W/System.err(5380): at android.os.AsyncTask$2.call(AsyncTask.java:287)
04-18 18:01:58.581: W/System.err(5380): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
04-18 18:01:58.581: W/System.err(5380): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-18 18:01:58.581: W/System.err(5380): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
04-18 18:01:58.581: W/System.err(5380): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
04-18 18:01:58.586: W/System.err(5380): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
04-18 18:01:58.586: W/System.err(5380): at java.lang.Thread.run(Thread.java:856)

could you please help me?

ModelCache can be unloaded by the VM

ModelCache is an abstract class that is only ever used through static method calls. It has static initiializers and also requires an explicit call to populate the cache. However, since no instance of ModelCache ever exists, it is possible for the VM to unload the class. It then gets reloaded the next time one of the static methods is called, but at this time the cache is re-created, and is empty. This leads to an exception, e.g

com.orm.androrm.NoSuchFieldException: No field named hasNew was found in class     ForumThread! Choices are: [date, endpoint, forum, hasNew, lastFetched, mine, nextToRead, nextUpdated, ordinal, postId, posts, subject, synced, totalPosts, unseen, url, watched, mId]
    at com.orm.androrm.Model.raiseFieldExecption(Model.java:181)
    at com.orm.androrm.Model.getField(Model.java:208)
    at com.orm.androrm.Model.getField(Model.java:204)
    at com.orm.androrm.QueryBuilder.getFieldInstance(QueryBuilder.java:169)
    at com.orm.androrm.QueryBuilder.buildQuery(QueryBuilder.java:101)
    at com.orm.androrm.QueryBuilder.buildQuery(QueryBuilder.java:74)
    at com.orm.androrm.QuerySet.filter(QuerySet.java:113)

This bug has been observed in production code when the app has been paused for some time.

Artifact for Androrm

MOVED FROM PHABRICATOR

It would be nice to have artifacts created for this project. Each one of them being a .zip file containing the source. Would be nice to have a src.zip with just the source files (no doc or test) to easily integrate in project we are working on (I could provide an example ant ask to retreive the file using IVY)
This for an easy way to manage project using Androrm (and for continuous integration).

I also have a dedicated server running sonatype (as-artifacts.org) which I have setup few months ago to have actionscript and android artifacts there.
I could I think provide you with an ant task creating the zip and pushing onto as-artifacts.org.

Let me know how you feel about this.
Cheers,

Xavier

migration example

Please add migration example. And please synchronize github code and downloadable 0.3.3 version

thanks

Filter.in(key,List<String>) can't query result

There is some wrong with Filter.in(key,List).
I have the database like this:
1|tom
2|peter
3|susan
I want to get all name, that are either called "tom" or "peter".

List names = new ArrayList();
names.add("tom");
names.add("peter");
Filter filter = new Filter();
filter.in("mName",names);
queryNameSet = Name.objects(this).filter(filter);

but ,not nothing result!!!
I test using Id or NameObject is all right,
so I think this problem just when We use List in filter.

OrderBy class screws up ordering by integer field

In OrderBy.java lines 57-61, wrapping the column in the UPPER function breaks ordering when the field is an integer. For example, the integers from 0 to 24 are ordered as 0, 1, 10, 11, ... 19, 2, 20, ... instead of sequentially. Removing the call to UPPER makes things work as expected.

Add ManyToMany field to existing model.

As part of the migrations it has to be possible to add a ManyToMany field to an existing model. In that case also the relation table, that is needed for this kind of field needs to be created.

Problems Deleting a row always returns false

This is the code of my aplicion:

this is works:

obj.save(getContext(),id);
obj=objcat.objects(getContext()).get(id);
this is not work:

boolean n= obj.delete(getContext());
false returns the boolean,and my database does not delete the row, but instead if stored properly, and also returns the correct object.

Elimination is the only thing that t does not work,why this may be due?

but as I have it delete the repository and do not know why it does not work, I'm leaving behind?

UUID id fields

Is it possible to use Strings/UUID's for the ID field?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.