Example usage for android.database Cursor isClosed

List of usage examples for android.database Cursor isClosed

Introduction

In this page you can find the example usage for android.database Cursor isClosed.

Prototype

boolean isClosed();

Source Link

Document

return true if the cursor is closed

Usage

From source file:org.opendatakit.services.database.utilities.ODKDatabaseImplUtils.java

/**
 * Retrieve the list of user-defined columns for a tableId using the metadata
 * for that table. Returns the unit-of-retention and non-unit-of-retention
 * (grouping) columns./*from w  w w.jav a2  s  .  co  m*/
 *
 * @param db
 * @param tableId
 * @return
 */
public OrderedColumns getUserDefinedColumns(OdkConnectionInterface db, String tableId) {
    ArrayList<Column> userDefinedColumns = new ArrayList<Column>();
    String selection = K_COLUMN_DEFS_TABLE_ID_EQUALS_PARAM;
    Object[] selectionArgs = { tableId };
    //@formatter:off
    String[] cols = { ColumnDefinitionsColumns.ELEMENT_KEY, ColumnDefinitionsColumns.ELEMENT_NAME,
            ColumnDefinitionsColumns.ELEMENT_TYPE, ColumnDefinitionsColumns.LIST_CHILD_ELEMENT_KEYS };
    //@formatter:on
    Cursor c = null;
    try {
        c = db.query(DatabaseConstants.COLUMN_DEFINITIONS_TABLE_NAME, cols, selection, selectionArgs, null,
                null, ColumnDefinitionsColumns.ELEMENT_KEY + " ASC", null);

        int elemKeyIndex = c.getColumnIndexOrThrow(ColumnDefinitionsColumns.ELEMENT_KEY);
        int elemNameIndex = c.getColumnIndexOrThrow(ColumnDefinitionsColumns.ELEMENT_NAME);
        int elemTypeIndex = c.getColumnIndexOrThrow(ColumnDefinitionsColumns.ELEMENT_TYPE);
        int listChildrenIndex = c.getColumnIndexOrThrow(ColumnDefinitionsColumns.LIST_CHILD_ELEMENT_KEYS);
        c.moveToFirst();
        while (!c.isAfterLast()) {
            String elementKey = CursorUtils.getIndexAsString(c, elemKeyIndex);
            String elementName = CursorUtils.getIndexAsString(c, elemNameIndex);
            String elementType = CursorUtils.getIndexAsString(c, elemTypeIndex);
            String listOfChildren = CursorUtils.getIndexAsString(c, listChildrenIndex);
            userDefinedColumns.add(new Column(elementKey, elementName, elementType, listOfChildren));
            c.moveToNext();
        }
    } finally {
        if (c != null && !c.isClosed()) {
            c.close();
        }
    }
    return new OrderedColumns(db.getAppName(), tableId, userDefinedColumns);
}

From source file:org.opendatakit.services.database.utilities.ODKDatabaseImplUtils.java

/**
 * @param db/*  ww w . ja va  2s  .co  m*/
 * @param tableId
 * @param rowId
 * @return the sync state of the row (see {@link SyncState}), or null if the
 * row does not exist.  Rows are required to have non-null sync states.
 * @throws IllegalStateException if the row has a null sync state or has
 *                               2+ conflicts or checkpoints and
 *                               those do not have matching sync states!
 */
public SyncState getSyncState(OdkConnectionInterface db, String tableId, String rowId)
        throws IllegalStateException {
    Cursor c = null;
    try {
        c = db.query(tableId, new String[] { DataTableColumns.SYNC_STATE }, K_DATATABLE_ID_EQUALS_PARAM,
                new Object[] { rowId }, null, null, null, null);

        if (c.moveToFirst()) {
            int syncStateIndex = c.getColumnIndex(DataTableColumns.SYNC_STATE);
            if (c.isNull(syncStateIndex)) {
                throw new IllegalStateException(t + ": row had a null sync state!");
            }
            String val = CursorUtils.getIndexAsString(c, syncStateIndex);
            while (c.moveToNext()) {
                if (c.isNull(syncStateIndex)) {
                    throw new IllegalStateException(t + ": row had a null sync state!");
                }
                String otherVal = CursorUtils.getIndexAsString(c, syncStateIndex);
                if (!val.equals(otherVal)) {
                    throw new IllegalStateException(t + ": row with 2+ conflicts or checkpoints does "
                            + "not have matching sync states!");
                }
            }
            return SyncState.valueOf(val);
        }
        return null;
    } finally {
        if (c != null && !c.isClosed()) {
            c.close();
        }
    }
}

From source file:org.opendatakit.services.database.utilities.ODKDatabaseImplUtils.java

/**
 * Get the table definition entry for a tableId. This specifies the schema
 * ETag, the data-modification ETag, and the date-time of the last successful
 * sync of the table to the server.//ww w . j a v  a  2s  . c  om
 *
 * @param db
 * @param tableId
 * @return
 */
public TableDefinitionEntry getTableDefinitionEntry(OdkConnectionInterface db, String tableId) {

    TableDefinitionEntry e = null;
    Cursor c = null;
    try {
        StringBuilder b = new StringBuilder();
        ArrayList<String> selArgs = new ArrayList<String>();
        b.append(K_KVS_TABLE_ID_EQUALS_PARAM);
        selArgs.add(tableId);

        c = db.query(DatabaseConstants.TABLE_DEFS_TABLE_NAME, null, b.toString(),
                selArgs.toArray(new String[selArgs.size()]), null, null, null, null);
        if (c.moveToFirst()) {
            int idxSchemaETag = c.getColumnIndex(TableDefinitionsColumns.SCHEMA_ETAG);
            int idxLastDataETag = c.getColumnIndex(TableDefinitionsColumns.LAST_DATA_ETAG);
            int idxLastSyncTime = c.getColumnIndex(TableDefinitionsColumns.LAST_SYNC_TIME);
            int idxRevId = c.getColumnIndex(TableDefinitionsColumns.REV_ID);

            if (c.getCount() != 1) {
                throw new IllegalStateException(
                        "Two or more TableDefinitionEntry records found for tableId " + tableId);
            }

            e = new TableDefinitionEntry(tableId);
            e.setSchemaETag(c.getString(idxSchemaETag));
            e.setLastDataETag(c.getString(idxLastDataETag));
            e.setLastSyncTime(c.getString(idxLastSyncTime));
            e.setRevId(c.getString(idxRevId));
        }
    } finally {
        if (c != null && !c.isClosed()) {
            c.close();
        }
    }
    return e;
}

From source file:org.opendatakit.services.database.utilities.ODKDatabaseImplUtils.java

/**
 * Return the health of a data table. The health can be one of
 * <ul>//w w w  .  j  a v a2 s. c om
 * <li>TABLE_HEALTH_IS_CLEAN = 0</li>
 * <li>TABLE_HEALTH_HAS_CONFLICTS = 1</li>
 * <li>TABLE_HEALTH_HAS_CHECKPOINTS = 2</li>
 * <li>TABLE_HEALTH_HAS_CHECKPOINTS_AND_CONFLICTS = 3</li>
 * <ul>
 *
 * @param db
 * @param tableId
 * @return
 */
public int getTableHealth(OdkConnectionInterface db, String tableId) {
    StringBuilder b = new StringBuilder();
    b.append("SELECT SUM(case when _savepoint_type is null then 1 else 0 end) as checkpoints,")
            .append("SUM(case when _conflict_type is not null then 1 else 0 end) as conflicts,")
            .append("SUM(case when _sync_state is 'synced' then 0 when _sync_state is "
                    + "'synced_pending_files' then 0 else 1 end) as changes FROM ")
            .append(tableId);

    Cursor c = null;
    try {
        c = db.rawQuery(b.toString(), null);
        Integer checkpoints = null;
        Integer conflicts = null;
        Integer changes = null;
        if (c != null) {
            if (c.moveToFirst()) {
                int idxCheckpoints = c.getColumnIndex("checkpoints");
                int idxConflicts = c.getColumnIndex("conflicts");
                int idxChanges = c.getColumnIndex("changes");
                checkpoints = CursorUtils.getIndexAsType(c, Integer.class, idxCheckpoints);
                conflicts = CursorUtils.getIndexAsType(c, Integer.class, idxConflicts);
                changes = CursorUtils.getIndexAsType(c, Integer.class, idxChanges);
            }
            c.close();
        }

        int outcome = CursorUtils.TABLE_HEALTH_IS_CLEAN;
        if (checkpoints != null && checkpoints != 0) {
            outcome = CursorUtils.setTableHealthHasCheckpoints(outcome);
        }
        if (conflicts != null && conflicts != 0) {
            outcome = CursorUtils.setTableHealthHasConflicts(outcome);
        }
        if (changes != null && changes != 0) {
            outcome = CursorUtils.setTableHealthHasChanges(outcome);
        }
        return outcome;
    } finally {
        if (c != null && !c.isClosed()) {
            c.close();
        }
    }
}

From source file:org.opendatakit.services.database.utilities.ODKDatabaseImplUtils.java

/**
 * Filters results by all non-null field values.
 *
 * @param db/* w  ww  .  j a v a2s  .  c o m*/
 * @param tableId
 * @param partition
 * @param aspect
 * @param key
 * @return
 */
public TableMetaDataEntries getTableMetadata(OdkConnectionInterface db, String tableId, String partition,
        String aspect, String key) {

    TableMetaDataEntries metadata = new TableMetaDataEntries(tableId, getTableDefinitionRevId(db, tableId));

    Cursor c = null;
    try {
        StringBuilder b = new StringBuilder();
        ArrayList<String> selArgs = new ArrayList<String>();
        if (tableId != null) {
            b.append(K_KVS_TABLE_ID_EQUALS_PARAM);
            selArgs.add(tableId);
        }
        if (partition != null) {
            if (b.length() != 0) {
                b.append(S_AND);
            }
            b.append(K_KVS_PARTITION_EQUALS_PARAM);
            selArgs.add(partition);
        }
        if (aspect != null) {
            if (b.length() != 0) {
                b.append(S_AND);
            }
            b.append(K_KVS_ASPECT_EQUALS_PARAM);
            selArgs.add(aspect);
        }
        if (key != null) {
            if (b.length() != 0) {
                b.append(S_AND);
            }
            b.append(K_KVS_KEY_EQUALS_PARAM);
            selArgs.add(key);
        }

        c = db.query(DatabaseConstants.KEY_VALUE_STORE_ACTIVE_TABLE_NAME, null, b.toString(),
                selArgs.toArray(new String[selArgs.size()]), null, null, null, null);
        if (c.moveToFirst()) {
            int idxTableId = c.getColumnIndex(KeyValueStoreColumns.TABLE_ID);
            int idxPartition = c.getColumnIndex(KeyValueStoreColumns.PARTITION);
            int idxAspect = c.getColumnIndex(KeyValueStoreColumns.ASPECT);
            int idxKey = c.getColumnIndex(KeyValueStoreColumns.KEY);
            int idxType = c.getColumnIndex(KeyValueStoreColumns.VALUE_TYPE);
            int idxValue = c.getColumnIndex(KeyValueStoreColumns.VALUE);

            do {
                KeyValueStoreEntry e = new KeyValueStoreEntry();
                e.tableId = c.getString(idxTableId);
                e.partition = c.getString(idxPartition);
                e.aspect = c.getString(idxAspect);
                e.key = c.getString(idxKey);
                e.type = c.getString(idxType);
                e.value = c.getString(idxValue);
                metadata.addEntry(e);
            } while (c.moveToNext());
        }
    } finally {
        if (c != null && !c.isClosed()) {
            c.close();
        }
    }
    return metadata;
}

From source file:saschpe.birthdays.service.CalendarSyncService.java

/**
 * Syncing work-horse./*www . jav  a2  s . c om*/
 *
 * Simply runs in current thread if invoked directly.
 */
public static void performSync(Context context) {
    Log.d(TAG, "Perform sync...");

    ContentResolver cr = context.getContentResolver();
    if (cr == null) {
        Log.e(TAG, "Unable to get content resolver!");
        return;
    }

    long calendarId = getCalendar(context);
    int deletedRows = cr.delete(getCalendarUri(context, CalendarContract.Events.CONTENT_URI),
            CalendarContract.Events.CALENDAR_ID + " = ?", new String[] { String.valueOf(calendarId) });
    Log.i(TAG, "Removed " + deletedRows + " rows from calendar " + calendarId);
    final long[] reminderMinutes = PreferencesHelper.getReminderMinutes(context);
    ArrayList<ContentProviderOperation> operations = new ArrayList<>();

    Cursor cursor = getContactsEvents(context, cr);
    if (cursor == null) {
        Log.e(TAG, "Failed to parse contacts events");
    }

    try {
        final int eventDateColumn = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE);
        final int displayNameColumn = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
        final int eventTypeColumn = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.TYPE);
        final int eventCustomLabelColumn = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.LABEL);
        final int eventLookupKeyColumn = cursor
                .getColumnIndex(ContactsContract.CommonDataKinds.Event.LOOKUP_KEY);

        int backRef = 0;

        // Loop over all events
        while (cursor != null && cursor.moveToNext()) {
            final String eventDateString = cursor.getString(eventDateColumn);
            final String displayName = cursor.getString(displayNameColumn);
            final int eventType = cursor.getInt(eventTypeColumn);
            final String eventLookupKey = cursor.getString(eventLookupKeyColumn);
            final Date eventDate = parseEventDateString(eventDateString);

            if (eventDate != null) {
                // Get year from event
                Calendar eventCalendar = Calendar.getInstance();
                eventCalendar.setTime(eventDate);
                int eventYear = eventCalendar.get(Calendar.YEAR);
                //Log.debug("Event year: " + eventYear);

                // If year < 1800 don't show brackets with age behind name. When no year is defined
                // parseEventDateString() sets it to 1700. Also iCloud for example sets year to
                // 1604 if no year is defined in their user interface.
                boolean hasYear = false;
                if (eventYear >= 1800) {
                    hasYear = true;
                }

                // Get current year
                Calendar currentCalendar = Calendar.getInstance();
                final int currentYear = currentCalendar.get(Calendar.YEAR);

                // Insert events for the past 2 years and the next 5 years. Events are not inserted
                // as recurring events to have different titles with birthday age in it.
                final int startYear = currentYear - 1;
                final int endYear = currentYear + 3;

                for (int year = startYear; year <= endYear; year++) {
                    // Calculate age
                    final int age = year - eventYear;
                    // If birthday has year and age of this event >= 0, display age in title
                    boolean includeAge = false;
                    if (hasYear && age >= 0) {
                        includeAge = true;
                    }
                    //Log.debug("Year: " + year + " age: " + age + " include age: " + includeAge);

                    String title = null;
                    String description = "";
                    if (displayName != null) {
                        switch (eventType) {
                        case ContactsContract.CommonDataKinds.Event.TYPE_CUSTOM:
                            String eventCustomLabel = cursor.getString(eventCustomLabelColumn);
                            if (eventCustomLabel != null) {
                                title = context.getString(R.string.event_custom_title_template, displayName,
                                        eventCustomLabel);
                            } else {
                                title = context.getString(R.string.event_other_title_template, displayName);
                            }
                            break;
                        case ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY:
                            title = context.getString(R.string.event_anniversary_title_template, displayName);
                            if (age == 1) {
                                description = context.getString(
                                        R.string.event_anniversary_description_singular_template, displayName,
                                        age);
                            } else {
                                description = context.getString(
                                        R.string.event_anniversary_description_plural_template, displayName,
                                        age);
                            }
                            break;
                        case ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY:
                            title = context.getString(R.string.event_birthday_title_template, displayName);
                            if (age == 1) {
                                description = context.getString(
                                        R.string.event_birthday_description_singular_template, displayName,
                                        eventYear, age);
                            } else {
                                description = context.getString(
                                        R.string.event_birthday_description_plural_template, displayName,
                                        eventYear, age);
                            }
                            break;
                        default:
                            // Includes ContactsContract.CommonDataKinds.Event.TYPE_OTHER
                            title = String.format(context.getString(R.string.event_other_title_template),
                                    displayName);
                            break;
                        }
                    }

                    if (title != null) {
                        Log.d(TAG, "Title: " + title + " backref: " + backRef);
                        operations.add(insertEvent(context, calendarId, eventDate, year, title, description,
                                eventLookupKey));

                        // Gets ContentProviderOperation to insert new reminder to the ContentProviderOperation
                        // with the given backRef. This is done using "withValueBackReference"
                        int reminderOperations = 0;
                        for (long reminderMinute : reminderMinutes) {
                            if (reminderMinute >= -1) {
                                ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(
                                        getCalendarUri(context, CalendarContract.Reminders.CONTENT_URI));
                                // Add reminder to last added event identified by backRef
                                // see http://stackoverflow.com/questions/4655291/semantics-of-withvaluebackreference
                                builder.withValueBackReference(CalendarContract.Reminders.EVENT_ID, backRef);
                                builder.withValue(CalendarContract.Reminders.MINUTES, reminderMinute);
                                builder.withValue(CalendarContract.Reminders.METHOD,
                                        CalendarContract.Reminders.METHOD_ALERT);
                                operations.add(builder.build());
                                reminderOperations += 1;
                            }
                        }
                        // Back reference for the next reminders, 1 is for the event
                        backRef += 1 + reminderOperations;
                    } else {
                        Log.d(TAG, "Event title empty, won't insert event and reminder");
                    }

                    // Intermediate commit, otherwise the binder transaction fails on large operation list
                    if (operations.size() > 200) {
                        applyBatchOperation(cr, operations);
                        backRef = 0;
                        operations.clear();
                    }
                }
            }
        }
    } finally {
        if (cursor != null && !cursor.isClosed())
            cursor.close();
    }

    // Create remaining events (that haven't been created by intermediate commits):
    if (operations.size() > 0) {
        applyBatchOperation(cr, operations);
    }

    LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent(ACTION_SYNC_DONE));
    Log.d(TAG, "Done performing sync...");
}

From source file:org.opendatakit.services.database.utilities.ODKDatabaseImplUtils.java

private void rawCheckpointDeleteDataInTable(OdkConnectionInterface db, String tableId, String rowId,
        String whereClause, Object[] whereArgs, String activeUser, String rolesList)
        throws ActionNotAuthorizedException {

    boolean shouldPhysicallyDelete = false;

    boolean dbWithinTransaction = db.inTransaction();
    try {//from  w  w w  .j a va  2  s  . c  o m
        if (!dbWithinTransaction) {
            db.beginTransactionNonExclusive();
        }

        // first need to test whether we can delete all the rows that are selected
        // by the where clause. If we can't, then throw an access violation
        Cursor c = null;
        try {
            c = db.query(tableId,
                    new String[] { DataTableColumns.SYNC_STATE, DataTableColumns.DEFAULT_ACCESS,
                            DataTableColumns.ROW_OWNER, DataTableColumns.GROUP_READ_ONLY,
                            DataTableColumns.GROUP_MODIFY, DataTableColumns.GROUP_PRIVILEGED },
                    whereClause, whereArgs, null, null, null, null);
            boolean hasRow = c.moveToFirst();

            int idxSyncState = c.getColumnIndex(DataTableColumns.SYNC_STATE);
            int idxDefaultAccess = c.getColumnIndex(DataTableColumns.DEFAULT_ACCESS);
            int idxOwner = c.getColumnIndex(DataTableColumns.ROW_OWNER);
            int idxGroupReadOnly = c.getColumnIndex(DataTableColumns.GROUP_READ_ONLY);
            int idxGroupModify = c.getColumnIndex(DataTableColumns.GROUP_MODIFY);
            int idxGroupPrivileged = c.getColumnIndex(DataTableColumns.GROUP_PRIVILEGED);

            List<String> rolesArray = getRolesArray(rolesList);

            TableSecuritySettings tss = getTableSecuritySettings(db, tableId);

            if (hasRow) {
                do {
                    // the row is entirely removed -- delete the attachments
                    String priorSyncState = c.getString(idxSyncState);
                    String priorDefaultAccess = c.isNull(idxDefaultAccess) ? null
                            : c.getString(idxDefaultAccess);
                    String priorOwner = c.isNull(idxOwner) ? null : c.getString(idxOwner);
                    String priorGroupReadOnly = c.isNull(idxGroupReadOnly) ? null
                            : c.getString(idxGroupReadOnly);
                    String priorGroupModify = c.isNull(idxGroupModify) ? null : c.getString(idxGroupModify);
                    String priorGroupPrivileged = c.isNull(idxGroupPrivileged) ? null
                            : c.getString(idxGroupPrivileged);

                    tss.allowRowChange(activeUser, rolesArray, priorSyncState, priorDefaultAccess, priorOwner,
                            priorGroupReadOnly, priorGroupModify, priorGroupPrivileged, RowChange.CHANGE_ROW);
                } while (c.moveToNext());
            }

        } finally {
            if (c != null && !c.isClosed()) {
                c.close();
            }
            c = null;
        }

        db.delete(tableId, whereClause, whereArgs);

        // see how many rows remain.
        // If there are none, then we should delete all the attachments for this row.
        c = null;
        try {
            c = db.query(tableId, new String[] { DataTableColumns.SYNC_STATE }, K_DATATABLE_ID_EQUALS_PARAM,
                    new Object[] { rowId }, null, null, null, null);
            c.moveToFirst();
            // the row is entirely removed -- delete the attachments
            shouldPhysicallyDelete = (c.getCount() == 0);
        } finally {
            if (c != null && !c.isClosed()) {
                c.close();
            }
        }

        if (!dbWithinTransaction) {
            db.setTransactionSuccessful();
        }
    } finally {
        if (!dbWithinTransaction) {
            db.endTransaction();
        }
    }

    if (shouldPhysicallyDelete) {
        File instanceFolder = new File(ODKFileUtils.getInstanceFolder(db.getAppName(), tableId, rowId));
        try {
            ODKFileUtils.deleteDirectory(instanceFolder);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            WebLogger.getLogger(db.getAppName()).e(t,
                    "Unable to delete this directory: " + instanceFolder.getAbsolutePath());
            WebLogger.getLogger(db.getAppName()).printStackTrace(e);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            WebLogger.getLogger(db.getAppName()).e(t,
                    "Unable to delete this directory: " + instanceFolder.getAbsolutePath());
            WebLogger.getLogger(db.getAppName()).printStackTrace(e);
        }
    }
}

From source file:org.opendatakit.services.database.utilities.ODKDatabaseImplUtils.java

/**
 * Delete the specified rowId in this tableId. Deletion respects sync
 * semantics. If the row is in the SyncState.new_row state, then the row and
 * its associated file attachments are immediately deleted. Otherwise, the row
 * is placed into the SyncState.deleted state and will be retained until the
 * device can delete the record on the server.
 * <p/>/*from  w ww  .  j  a  v  a 2  s . c  o m*/
 * If you need to immediately delete a record that would otherwise sync to the
 * server, call updateRowETagAndSyncState(...) to set the row to
 * SyncState.new_row, and then call this method and it will be immediately
 * deleted (in this case, unless the record on the server was already deleted,
 * it will remain and not be deleted during any subsequent synchronizations).
 *
 * @param db
 * @param tableId
 * @param rowId
 * @param activeUser
 * @param rolesList
 * @throws ActionNotAuthorizedException
 */
public void deleteRowWithId(OdkConnectionInterface db, String tableId, String rowId, String activeUser,
        String rolesList) throws ActionNotAuthorizedException {

    // TODO: rolesList of user may impact whether we can delete the record.
    // Particularly with sync'd records, is there anything special to do here?
    // consider sync path vs. tools path.
    // I.e., if the user is super-user or higher, we should take local FilterScope.
    // otherwise, we should take server FilterScope. Or should we allow user to select
    // which to take?

    boolean shouldPhysicallyDelete = false;

    boolean dbWithinTransaction = db.inTransaction();
    try {
        if (!dbWithinTransaction) {
            db.beginTransactionNonExclusive();
        }

        Object[] whereArgs = new Object[] { rowId };
        String whereClause = K_DATATABLE_ID_EQUALS_PARAM;

        // first need to test whether we can delete all the rows under this rowId.
        // If we can't, then throw an access violation
        Cursor c = null;
        try {
            c = db.query(tableId,
                    new String[] { DataTableColumns.SYNC_STATE, DataTableColumns.DEFAULT_ACCESS,
                            DataTableColumns.ROW_OWNER, DataTableColumns.GROUP_READ_ONLY,
                            DataTableColumns.GROUP_MODIFY, DataTableColumns.GROUP_PRIVILEGED },
                    whereClause, whereArgs, null, null, DataTableColumns.SAVEPOINT_TIMESTAMP + " ASC", null);
            boolean hasFirst = c.moveToFirst();

            int idxSyncState = c.getColumnIndex(DataTableColumns.SYNC_STATE);
            int idxDefaultAccess = c.getColumnIndex(DataTableColumns.DEFAULT_ACCESS);
            int idxOwner = c.getColumnIndex(DataTableColumns.ROW_OWNER);
            int idxGroupReadOnly = c.getColumnIndex(DataTableColumns.GROUP_READ_ONLY);
            int idxGroupModify = c.getColumnIndex(DataTableColumns.GROUP_MODIFY);
            int idxGroupPrivileged = c.getColumnIndex(DataTableColumns.GROUP_PRIVILEGED);

            List<String> rolesArray = getRolesArray(rolesList);

            TableSecuritySettings tss = getTableSecuritySettings(db, tableId);

            if (hasFirst) {
                do {
                    // verify each row
                    String priorSyncState = c.getString(idxSyncState);
                    String priorDefaultAccess = c.isNull(idxDefaultAccess) ? null
                            : c.getString(idxDefaultAccess);
                    String priorOwner = c.isNull(idxOwner) ? null : c.getString(idxOwner);
                    String priorGroupReadOnly = c.isNull(idxGroupReadOnly) ? null
                            : c.getString(idxGroupReadOnly);
                    String priorGroupModify = c.isNull(idxGroupModify) ? null : c.getString(idxGroupModify);
                    String priorGroupPrivileged = c.isNull(idxGroupPrivileged) ? null
                            : c.getString(idxGroupPrivileged);

                    tss.allowRowChange(activeUser, rolesArray, priorSyncState, priorDefaultAccess, priorOwner,
                            priorGroupReadOnly, priorGroupModify, priorGroupPrivileged, RowChange.DELETE_ROW);

                } while (c.moveToNext());
            }

        } finally {
            if (c != null && !c.isClosed()) {
                c.close();
            }
            c = null;
        }

        // delete any checkpoints
        whereClause = K_DATATABLE_ID_EQUALS_PARAM + S_AND + DataTableColumns.SAVEPOINT_TYPE + S_IS_NULL;
        db.delete(tableId, whereClause, whereArgs);

        // this will return null if there are no rows.
        SyncState syncState = getSyncState(db, tableId, rowId);

        if (syncState == null) {
            // the rowId no longer exists (we deleted all checkpoints)
            shouldPhysicallyDelete = true;

        } else if (syncState == SyncState.new_row) {
            // we can safely remove this record from the database
            whereClause = K_DATATABLE_ID_EQUALS_PARAM;

            db.delete(tableId, whereClause, whereArgs);
            shouldPhysicallyDelete = true;

        } else if (syncState != SyncState.in_conflict) {

            TreeMap<String, Object> values = new TreeMap<String, Object>();
            values.put(DataTableColumns.SYNC_STATE, SyncState.deleted.name());
            values.put(DataTableColumns.SAVEPOINT_TIMESTAMP,
                    TableConstants.nanoSecondsFromMillis(System.currentTimeMillis()));

            db.update(tableId, values, K_DATATABLE_ID_EQUALS_PARAM, whereArgs);
        }
        // TODO: throw exception if in the SyncState.in_conflict state?

        if (!dbWithinTransaction) {
            db.setTransactionSuccessful();
        }
    } finally {
        if (!dbWithinTransaction) {
            db.endTransaction();
        }
    }

    if (shouldPhysicallyDelete) {
        File instanceFolder = new File(ODKFileUtils.getInstanceFolder(db.getAppName(), tableId, rowId));
        try {
            ODKFileUtils.deleteDirectory(instanceFolder);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            WebLogger.getLogger(db.getAppName()).e(t,
                    "Unable to delete this directory: " + instanceFolder.getAbsolutePath());
            WebLogger.getLogger(db.getAppName()).printStackTrace(e);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            WebLogger.getLogger(db.getAppName()).e(t,
                    "Unable to delete this directory: " + instanceFolder.getAbsolutePath());
            WebLogger.getLogger(db.getAppName()).printStackTrace(e);
        }
    }
}

From source file:org.opendatakit.utilities.test.AbstractODKDatabaseUtilsTest.java

public void testMultipleConnectionsWithTableDeletionAndCreation_ExpectPass()
        throws ActionNotAuthorizedException {
    String tableId = testTable;/*  w ww . java2  s .c o  m*/
    String testCol = "testColumn";
    String testColType = ElementDataType.integer.name();
    List<Column> columns = new ArrayList<Column>();
    columns.add(new Column(testCol, testCol, testColType, "[]"));

    // Create two different db connections
    String uuid1 = LocalizationUtils.genUUID();
    DbHandle uniqueKey1 = new DbHandle(AbstractODKDatabaseUtilsTest.class.getSimpleName() + uuid1
            + AndroidConnectFactory.INTERNAL_TYPE_SUFFIX);
    OdkConnectionInterface db1 = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface()
            .getConnection(getAppName(), uniqueKey1);

    String uuid2 = LocalizationUtils.genUUID();
    DbHandle uniqueKey2 = new DbHandle(AbstractODKDatabaseUtilsTest.class.getSimpleName() + uuid2
            + AndroidConnectFactory.INTERNAL_TYPE_SUFFIX);
    OdkConnectionInterface db2 = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface()
            .getConnection(getAppName(), uniqueKey2);

    // Create a table on db1
    OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db1, tableId,
            columns);

    ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId,
            activeUser, RoleConsts.ADMIN_ROLES_LIST);

    // Insert a row using db1
    int testVal = 5;
    ContentValues cvValues = new ContentValues();
    String rowId = LocalizationUtils.genUUID();
    cvValues.put(testCol, testVal);
    ODKDatabaseImplUtils.get().insertRowWithId(db1, tableId, orderedColumns, cvValues, rowId, activeUser,
            RoleConsts.ADMIN_ROLES_LIST, currentLocale);

    // Have both query the table
    // Query with db1
    String sel = "SELECT * FROM " + tableId;
    String[] selArgs = null;
    Cursor cursor1 = ODKDatabaseImplUtils.get().rawQuery(db1, sel, selArgs, null, accessContext);

    while (cursor1.moveToNext()) {
        int ind1 = cursor1.getColumnIndex(testCol);
        int type1 = cursor1.getType(ind1);
        assertEquals(type1, Cursor.FIELD_TYPE_INTEGER);
        int val1 = cursor1.getInt(ind1);
        assertEquals(val1, testVal);
    }

    // Query with db2
    Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(db2, sel, selArgs, null, accessContext);

    while (cursor2.moveToNext()) {
        int ind2 = cursor2.getColumnIndex(testCol);
        int type2 = cursor2.getType(ind2);
        assertEquals(type2, Cursor.FIELD_TYPE_INTEGER);
        int val2 = cursor2.getInt(ind2);
        assertEquals(val2, testVal);
    }

    // Delete the table and recreate with a different row
    ODKDatabaseImplUtils.get().deleteTableAndAllData(db1, tableId);

    // Create a table on db1
    String newTestCol = "testColumn0";
    List<Column> newColumns = new ArrayList<Column>();
    newColumns.add(new Column(newTestCol, newTestCol, testColType, "[]"));
    orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db1, tableId, newColumns);

    // Re-create the same table with different row
    int newTestVal = 200;
    cvValues = new ContentValues();
    rowId = LocalizationUtils.genUUID();
    cvValues.put(newTestCol, newTestVal);
    ODKDatabaseImplUtils.get().insertRowWithId(db1, tableId, orderedColumns, cvValues, rowId, activeUser,
            RoleConsts.ADMIN_ROLES_LIST, currentLocale);

    // Have both connections re-query the table
    // Query with db1
    cursor1 = ODKDatabaseImplUtils.get().rawQuery(db1, sel, selArgs, null, accessContext);

    while (cursor1.moveToNext()) {
        int ind3 = cursor1.getColumnIndex(newTestCol);
        int type3 = cursor1.getType(ind3);
        assertEquals(type3, Cursor.FIELD_TYPE_INTEGER);
        int val3 = cursor1.getInt(ind3);
        assertEquals(val3, newTestVal);
    }

    // Query with db2
    cursor2 = ODKDatabaseImplUtils.get().rawQuery(db2, sel, selArgs, null, accessContext);

    while (cursor2.moveToNext()) {
        int ind4 = cursor2.getColumnIndex(testCol);
        int type4 = cursor2.getType(ind4);
        assertEquals(type4, Cursor.FIELD_TYPE_INTEGER);
        int val4 = cursor2.getInt(ind4);
        assertEquals(val4, newTestVal);
    }

    // Close the cursor
    if (cursor1 != null && !cursor1.isClosed()) {
        cursor1.close();
    }

    if (cursor2 != null && !cursor2.isClosed()) {
        cursor2.close();
    }

    System.out.println("testMultipleConnectionsWithTableDeletionAndCreation_ExpectPass: after assert");
    OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false);

    // Drop the table now that the test is done
    ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId);
}

From source file:org.opendatakit.utilities.AbstractODKDatabaseUtilsTest.java

@Test
public void testMultipleConnectionsWithTableDeletionAndCreation_ExpectPass()
        throws ActionNotAuthorizedException {
    String tableId = testTable;/*w  w  w . j a v a 2s .com*/
    String testCol = "testColumn";
    String testColType = ElementDataType.integer.name();
    List<Column> columns = new ArrayList<Column>();
    columns.add(new Column(testCol, testCol, testColType, "[]"));

    // Create two different db connections
    String uuid1 = LocalizationUtils.genUUID();
    DbHandle uniqueKey1 = new DbHandle(AbstractODKDatabaseUtilsTest.class.getSimpleName() + uuid1
            + AndroidConnectFactory.INTERNAL_TYPE_SUFFIX);
    OdkConnectionInterface db1 = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface()
            .getConnection(getAppName(), uniqueKey1);

    String uuid2 = LocalizationUtils.genUUID();
    DbHandle uniqueKey2 = new DbHandle(AbstractODKDatabaseUtilsTest.class.getSimpleName() + uuid2
            + AndroidConnectFactory.INTERNAL_TYPE_SUFFIX);
    OdkConnectionInterface db2 = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface()
            .getConnection(getAppName(), uniqueKey2);

    // Create a table on db1
    OrderedColumns orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db1, tableId,
            columns);

    ODKDatabaseImplUtils.AccessContext accessContext = ODKDatabaseImplUtils.get().getAccessContext(db, tableId,
            activeUser, RoleConsts.ADMIN_ROLES_LIST);

    // Insert a row using db1
    int testVal = 5;
    ContentValues cvValues = new ContentValues();
    String rowId = LocalizationUtils.genUUID();
    cvValues.put(testCol, testVal);
    ODKDatabaseImplUtils.get().insertRowWithId(db1, tableId, orderedColumns, cvValues, rowId, activeUser,
            RoleConsts.ADMIN_ROLES_LIST, currentLocale);

    // Have both query the table
    // Query with db1
    String sel = "SELECT * FROM " + tableId;
    String[] selArgs = null;
    Cursor cursor1 = ODKDatabaseImplUtils.get().rawQuery(db1, sel, selArgs, null, accessContext);

    while (cursor1.moveToNext()) {
        int ind1 = cursor1.getColumnIndex(testCol);
        int type1 = cursor1.getType(ind1);
        assertEquals(type1, Cursor.FIELD_TYPE_INTEGER);
        int val1 = cursor1.getInt(ind1);
        assertEquals(val1, testVal);
    }

    // Query with db2
    Cursor cursor2 = ODKDatabaseImplUtils.get().rawQuery(db2, sel, selArgs, null, accessContext);

    while (cursor2.moveToNext()) {
        int ind2 = cursor2.getColumnIndex(testCol);
        int type2 = cursor2.getType(ind2);
        assertEquals(type2, Cursor.FIELD_TYPE_INTEGER);
        int val2 = cursor2.getInt(ind2);
        assertEquals(val2, testVal);
    }

    // Delete the table and recreate with a different row
    ODKDatabaseImplUtils.get().deleteTableAndAllData(db1, tableId);

    // Create a table on db1
    String newTestCol = "testColumn0";
    List<Column> newColumns = new ArrayList<Column>();
    newColumns.add(new Column(newTestCol, newTestCol, testColType, "[]"));
    orderedColumns = ODKDatabaseImplUtils.get().createOrOpenTableWithColumns(db1, tableId, newColumns);

    // Re-create the same table with different row
    int newTestVal = 200;
    cvValues = new ContentValues();
    rowId = LocalizationUtils.genUUID();
    cvValues.put(newTestCol, newTestVal);
    ODKDatabaseImplUtils.get().insertRowWithId(db1, tableId, orderedColumns, cvValues, rowId, activeUser,
            RoleConsts.ADMIN_ROLES_LIST, currentLocale);

    // Have both connections re-query the table
    // Query with db1
    cursor1 = ODKDatabaseImplUtils.get().rawQuery(db1, sel, selArgs, null, accessContext);

    while (cursor1.moveToNext()) {
        int ind3 = cursor1.getColumnIndex(newTestCol);
        int type3 = cursor1.getType(ind3);
        assertEquals(type3, Cursor.FIELD_TYPE_INTEGER);
        int val3 = cursor1.getInt(ind3);
        assertEquals(val3, newTestVal);
    }

    // Query with db2
    cursor2 = ODKDatabaseImplUtils.get().rawQuery(db2, sel, selArgs, null, accessContext);

    while (cursor2.moveToNext()) {
        int ind4 = cursor2.getColumnIndex(testCol);
        int type4 = cursor2.getType(ind4);
        assertEquals(type4, Cursor.FIELD_TYPE_INTEGER);
        int val4 = cursor2.getInt(ind4);
        assertEquals(val4, newTestVal);
    }

    // Close the cursor
    if (cursor1 != null && !cursor1.isClosed()) {
        cursor1.close();
    }

    if (cursor2 != null && !cursor2.isClosed()) {
        cursor2.close();
    }

    System.out.println("testMultipleConnectionsWithTableDeletionAndCreation_ExpectPass: after assert");
    OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().dumpInfo(false);

    // Drop the table now that the test is done
    ODKDatabaseImplUtils.get().deleteTableAndAllData(db, tableId);
}