/* * Copyright 2013 Robotoworks Limited * 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. */ package com.robotoworks.mechanoid.db; import com.robotoworks.mechanoid.Mechanoid; import com.robotoworks.mechanoid.util.Closeables; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; /** * <p>Base for all generated Mechanoid DB ActiveRecord implementations</p> * */ public abstract class ActiveRecord { protected final Uri mContentUri; private long mId; public long getId() { return mId; } public void setId(long id) { if(mId != id) { makeDirty(true); } mId = id; } protected ActiveRecord(Uri contentUri) { mContentUri = contentUri; } protected abstract String[] _getProjection(); protected abstract AbstractValuesBuilder createBuilder(); public ContentValues toValues() { return createBuilder().getValues(); } public abstract void makeDirty(boolean b); protected abstract void setPropertiesFromCursor(Cursor c); /** * <p>Save this record to the database, this is a convenience method, use * {@link #insert()} or {@link #update()} if you want to explicitly perform * an INSERT or UPDATE.</p> * * <p>If the <b>id</b> column for this record is zero, then saving will cause * an insert, after saving the <b>id</b> will be set with the new id of the inserted record, * If the id column is not zero, then saving will cause an update to the record with the <b>id</b>. * </p> * * @param resolver the resolver * @return the new <b>id</b> of the record, the id property of this active record * will also be updated */ public long save(){ return save(true); } /** * <p>Same as {@link #save()} but with the option to notify content observers that the record * has changed, by default, content observers are always notified, set to false to disable.</p> * @param notifyChange Whether to notify observers, default is true * @return the <b>id</b> of the record, the id property of this active record * will also be set */ public long save(boolean notifyChange){ mId = mId > 0 ? update(notifyChange) : insert(notifyChange); return mId; } public boolean delete(){ return delete(true); } public boolean delete(boolean notifyChange){ ContentResolver resolver = Mechanoid.getContentResolver(); Uri uri = mContentUri.buildUpon() .appendPath(String.valueOf(mId)) .appendQueryParameter( MechanoidContentProvider.PARAM_NOTIFY, String.valueOf(notifyChange)).build(); boolean result = resolver.delete(uri, null, null) > 0; makeDirty(false); return result; } /** * <p>Insert this record into the database</p> * @return the new <b>id</b> of the record, the id property of this active record * will also be updated */ public long insert() { return insert(true); } /** * <p>Like {@link #insert()} with the option to enable/disable change notification.</p> * @param notifyChange Whether to notify observers, default is true * @return the <b>id</b> of the record, the id property of this active record * will also be updated */ public long insert(boolean notifyChange) { AbstractValuesBuilder builder = createBuilder(); Uri uri = builder.insert(notifyChange); mId = ContentUris.parseId(uri); makeDirty(false); return mId; } /** * <p>Updates this record into the database</p> * @return the <b>id</b> of the record, the id property of this active record * will also be updated */ public long update() { return update(true); } /** * <p>Like {@link #update()} with the option to enable/disable change notification.</p> * @param notifyChange Whether to notify observers, default is true * @return the <b>id</b> of the record, the id property of this active record * will also be updated */ public long update(boolean notifyChange) { AbstractValuesBuilder builder = createBuilder(); builder.update(mId, notifyChange); makeDirty(false); return mId; } public void reload(){ if(mId == 0) { return; } Cursor c = null; ContentResolver resolver = Mechanoid.getContentResolver(); try { c = resolver.query(mContentUri.buildUpon() .appendPath(String.valueOf(mId)).build(), _getProjection(), null, null, null); if(c.moveToFirst()) { setPropertiesFromCursor(c); makeDirty(false); } } finally { Closeables.closeSilently(c); } } public void reload(SQuery query){ if(mId == 0) { return; } Cursor c = null; try { c = query.selectFirst(mContentUri, _getProjection()); if(c.moveToFirst()) { setPropertiesFromCursor(c); makeDirty(false); } } finally { Closeables.closeSilently(c); } } }