Example usage for android.database Cursor getColumnName

List of usage examples for android.database Cursor getColumnName

Introduction

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

Prototype

String getColumnName(int columnIndex);

Source Link

Document

Returns the column name at the given zero-based column index.

Usage

From source file:org.opendatakit.services.submissions.provider.SubmissionProvider.java

/**
 * The incoming URI is of the form:/* w ww. j av a  2 s. c  o  m*/
 * ..../appName/tableId/instanceId?formId=&formVersion=
 *
 * where instanceId is the DataTableColumns._ID
 */
@SuppressWarnings("unchecked")
@Override
public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException {

    possiblyWaitForContentProviderDebugger();

    final boolean asXml = uri.getAuthority().equalsIgnoreCase(ProviderConsts.XML_SUBMISSION_AUTHORITY);

    if (mode != null && !mode.equals("r")) {
        throw new IllegalArgumentException("Only read access is supported");
    }

    // URI == ..../appName/tableId/instanceId?formId=&formVersion=

    List<String> segments = uri.getPathSegments();

    if (segments.size() != 4) {
        throw new IllegalArgumentException("Unknown URI (incorrect number of path segments!) " + uri);
    }

    PropertyManager propertyManager = new PropertyManager(getContext());

    final String appName = segments.get(0);
    ODKFileUtils.verifyExternalStorageAvailability();
    ODKFileUtils.assertDirectoryStructure(appName);
    WebLoggerIf logger = WebLogger.getLogger(appName);

    final String tableId = segments.get(1);
    final String instanceId = segments.get(2);
    final String submissionInstanceId = segments.get(3);

    PropertiesSingleton props = CommonToolProperties.get(getContext(), appName);
    String userEmail = props.getProperty(CommonToolProperties.KEY_ACCOUNT);
    String username = props.getProperty(CommonToolProperties.KEY_USERNAME);
    String activeUser = props.getActiveUser();
    String rolesList = props.getProperty(CommonToolProperties.KEY_ROLES_LIST);
    String currentLocale = props.getLocale();

    DbHandle dbHandleName = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface()
            .generateInternalUseDbHandle();
    OdkConnectionInterface db = null;
    try {
        // +1 referenceCount if db is returned (non-null)
        db = OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().getConnection(appName,
                dbHandleName);

        boolean success = false;
        try {
            success = ODKDatabaseImplUtils.get().hasTableId(db, tableId);
        } catch (Exception e) {
            logger.printStackTrace(e);
            throw new SQLException("Unknown URI (exception testing for tableId) " + uri);
        }
        if (!success) {
            throw new SQLException("Unknown URI (missing data table for tableId) " + uri);
        }

        // Get the table properties specific to XML submissions

        String xmlInstanceName = null;
        String xmlRootElementName = null;
        String xmlDeviceIdPropertyName = null;
        String xmlUserIdPropertyName = null;
        String xmlBase64RsaPublicKey = null;

        try {

            Cursor c = null;
            try {
                c = db.query(DatabaseConstants.KEY_VALUE_STORE_ACTIVE_TABLE_NAME,
                        new String[] { KeyValueStoreColumns.KEY, KeyValueStoreColumns.VALUE },
                        KeyValueStoreColumns.TABLE_ID + "=? AND " + KeyValueStoreColumns.PARTITION + "=? AND "
                                + KeyValueStoreColumns.ASPECT + "=? AND " + KeyValueStoreColumns.KEY
                                + " IN (?,?,?,?,?)",
                        new String[] { tableId, KeyValueStoreConstants.PARTITION_TABLE,
                                KeyValueStoreConstants.ASPECT_DEFAULT, KeyValueStoreConstants.XML_INSTANCE_NAME,
                                KeyValueStoreConstants.XML_ROOT_ELEMENT_NAME,
                                KeyValueStoreConstants.XML_DEVICE_ID_PROPERTY_NAME,
                                KeyValueStoreConstants.XML_USER_ID_PROPERTY_NAME,
                                KeyValueStoreConstants.XML_BASE64_RSA_PUBLIC_KEY },
                        null, null, null, null);
                c.moveToFirst();

                if (c.getCount() > 0) {
                    int idxKey = c.getColumnIndex(KeyValueStoreColumns.KEY);
                    int idxValue = c.getColumnIndex(KeyValueStoreColumns.VALUE);
                    do {
                        String key = c.getString(idxKey);
                        String value = c.getString(idxValue);
                        if (KeyValueStoreConstants.XML_INSTANCE_NAME.equals(key)) {
                            xmlInstanceName = value;
                        } else if (KeyValueStoreConstants.XML_ROOT_ELEMENT_NAME.equals(key)) {
                            xmlRootElementName = value;
                        } else if (KeyValueStoreConstants.XML_DEVICE_ID_PROPERTY_NAME.equals(key)) {
                            xmlDeviceIdPropertyName = value;
                        } else if (KeyValueStoreConstants.XML_USER_ID_PROPERTY_NAME.equals(key)) {
                            xmlUserIdPropertyName = value;
                        } else if (KeyValueStoreConstants.XML_BASE64_RSA_PUBLIC_KEY.equals(key)) {
                            xmlBase64RsaPublicKey = value;
                        }
                    } while (c.moveToNext());
                }
            } finally {
                c.close();
                c = null;
            }

            OrderedColumns orderedDefns = ODKDatabaseImplUtils.get().getUserDefinedColumns(db, tableId);

            // Retrieve the values of the record to be emitted...

            HashMap<String, Object> values = new HashMap<String, Object>();

            // issue query to retrieve the most recent non-checkpoint data record
            // for the instanceId
            StringBuilder b = new StringBuilder();
            b.append("SELECT * FROM ").append(tableId).append(" as T WHERE ").append(DataTableColumns.ID)
                    .append("=?").append(" AND ").append(DataTableColumns.SAVEPOINT_TYPE)
                    .append(" IS NOT NULL AND ").append(DataTableColumns.SAVEPOINT_TIMESTAMP)
                    .append("=(SELECT max(V.").append(DataTableColumns.SAVEPOINT_TIMESTAMP).append(") FROM ")
                    .append(tableId).append(" as V WHERE V.").append(DataTableColumns.ID).append("=T.")
                    .append(DataTableColumns.ID).append(" AND V.").append(DataTableColumns.SAVEPOINT_TYPE)
                    .append(" IS NOT NULL").append(")");

            String[] selectionArgs = new String[] { instanceId };
            FileSet freturn = new FileSet(appName);

            String datestamp = null;

            try {

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

                c = ODKDatabaseImplUtils.get().rawQuery(db, b.toString(), selectionArgs, null, accessContext);
                b.setLength(0);

                if (c.moveToFirst() && c.getCount() == 1) {
                    String rowETag = null;
                    String filterType = null;
                    String filterValue = null;
                    String formId = null;
                    String locale = null;
                    String savepointType = null;
                    String savepointCreator = null;
                    String savepointTimestamp = null;
                    String instanceName = null;

                    // OK. we have the record -- work through all the terms
                    for (int i = 0; i < c.getColumnCount(); ++i) {
                        ColumnDefinition defn = null;
                        String columnName = c.getColumnName(i);
                        try {
                            defn = orderedDefns.find(columnName);
                        } catch (IllegalArgumentException e) {
                            // ignore...
                        }
                        if (defn != null && !c.isNull(i)) {
                            if (xmlInstanceName != null && defn.getElementName().equals(xmlInstanceName)) {
                                instanceName = CursorUtils.getIndexAsString(c, i);
                            }
                            // user-defined column
                            ElementType type = defn.getType();
                            ElementDataType dataType = type.getDataType();

                            logger.i(t, "element type: " + defn.getElementType());
                            if (dataType == ElementDataType.integer) {
                                Integer value = CursorUtils.getIndexAsType(c, Integer.class, i);
                                putElementValue(values, defn, value);
                            } else if (dataType == ElementDataType.number) {
                                Double value = CursorUtils.getIndexAsType(c, Double.class, i);
                                putElementValue(values, defn, value);
                            } else if (dataType == ElementDataType.bool) {
                                Integer tmp = CursorUtils.getIndexAsType(c, Integer.class, i);
                                Boolean value = tmp == null ? null : (tmp != 0);
                                putElementValue(values, defn, value);
                            } else if (type.getElementType().equals("date")) {
                                String value = CursorUtils.getIndexAsString(c, i);
                                String jrDatestamp = (value == null) ? null
                                        : (new SimpleDateFormat(ISO8601_DATE_ONLY_FORMAT, Locale.US))
                                                .format(new Date(TableConstants.milliSecondsFromNanos(value)));
                                putElementValue(values, defn, jrDatestamp);
                            } else if (type.getElementType().equals("dateTime")) {
                                String value = CursorUtils.getIndexAsString(c, i);
                                String jrDatestamp = (value == null) ? null
                                        : (new SimpleDateFormat(ISO8601_DATE_FORMAT, Locale.US))
                                                .format(new Date(TableConstants.milliSecondsFromNanos(value)));
                                putElementValue(values, defn, jrDatestamp);
                            } else if (type.getElementType().equals("time")) {
                                String value = CursorUtils.getIndexAsString(c, i);
                                putElementValue(values, defn, value);
                            } else if (dataType == ElementDataType.array) {
                                ArrayList<Object> al = CursorUtils.getIndexAsType(c, ArrayList.class, i);
                                putElementValue(values, defn, al);
                            } else if (dataType == ElementDataType.string) {
                                String value = CursorUtils.getIndexAsString(c, i);
                                putElementValue(values, defn, value);
                            } else /* unrecognized */ {
                                throw new IllegalStateException(
                                        "unrecognized data type: " + defn.getElementType());
                            }

                        } else if (columnName.equals(DataTableColumns.SAVEPOINT_TIMESTAMP)) {
                            savepointTimestamp = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.ROW_ETAG)) {
                            rowETag = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.FILTER_TYPE)) {
                            filterType = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.FILTER_VALUE)) {
                            filterValue = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.FORM_ID)) {
                            formId = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.LOCALE)) {
                            locale = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.FORM_ID)) {
                            formId = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.SAVEPOINT_TYPE)) {
                            savepointType = CursorUtils.getIndexAsString(c, i);
                        } else if (columnName.equals(DataTableColumns.SAVEPOINT_CREATOR)) {
                            savepointCreator = CursorUtils.getIndexAsString(c, i);
                        }
                    }

                    // OK got all the values into the values map -- emit
                    // contents
                    b.setLength(0);
                    File submissionXml = new File(ODKFileUtils.getInstanceFolder(appName, tableId, instanceId),
                            (asXml ? "submission.xml" : "submission.json"));
                    File manifest = new File(ODKFileUtils.getInstanceFolder(appName, tableId, instanceId),
                            "manifest.json");
                    submissionXml.delete();
                    manifest.delete();
                    freturn.instanceFile = submissionXml;

                    if (asXml) {
                        // Pre-processing -- collapse all geopoints into a
                        // string-valued representation
                        for (ColumnDefinition defn : orderedDefns.getColumnDefinitions()) {
                            ElementType type = defn.getType();
                            ElementDataType dataType = type.getDataType();
                            if (dataType == ElementDataType.object && (type.getElementType().equals("geopoint")
                                    || type.getElementType().equals("mimeUri"))) {
                                Map<String, Object> parent = null;
                                List<ColumnDefinition> parents = new ArrayList<ColumnDefinition>();
                                ColumnDefinition d = defn.getParent();
                                while (d != null) {
                                    parents.add(d);
                                    d = d.getParent();
                                }
                                parent = values;
                                for (int i = parents.size() - 1; i >= 0; --i) {
                                    Object o = parent.get(parents.get(i).getElementName());
                                    if (o == null) {
                                        parent = null;
                                        break;
                                    }
                                    parent = (Map<String, Object>) o;
                                }
                                if (parent != null) {
                                    Object o = parent.get(defn.getElementName());
                                    if (o != null) {
                                        if (type.getElementType().equals("geopoint")) {
                                            Map<String, Object> geopoint = (Map<String, Object>) o;
                                            // OK. we have geopoint -- get the
                                            // lat, long, alt, etc.
                                            Double latitude = (Double) geopoint.get("latitude");
                                            Double longitude = (Double) geopoint.get("longitude");
                                            Double altitude = (Double) geopoint.get("altitude");
                                            Double accuracy = (Double) geopoint.get("accuracy");
                                            String gpt = "" + latitude + " " + longitude + " " + altitude + " "
                                                    + accuracy;
                                            parent.put(defn.getElementName(), gpt);
                                        } else if (type.getElementType().equals("mimeUri")) {
                                            Map<String, Object> mimeuri = (Map<String, Object>) o;
                                            String uriFragment = (String) mimeuri.get("uriFragment");
                                            String contentType = (String) mimeuri.get("contentType");

                                            if (uriFragment != null) {
                                                File f = ODKFileUtils.getAsFile(appName, uriFragment);
                                                if (f.equals(manifest)) {
                                                    throw new IllegalStateException(
                                                            "Unexpected collision with manifest.json");
                                                }
                                                freturn.addAttachmentFile(f, contentType);
                                                parent.put(defn.getElementName(), f.getName());
                                            }
                                        } else {
                                            throw new IllegalStateException("Unhandled transform case");
                                        }
                                    }
                                }
                            }
                        }

                        datestamp = (new SimpleDateFormat(ISO8601_DATE_FORMAT, Locale.US))
                                .format(new Date(TableConstants.milliSecondsFromNanos(savepointTimestamp)));

                        // For XML, we traverse the map to serialize it
                        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                        DocumentBuilder docBuilder = dbf.newDocumentBuilder();

                        Document d = docBuilder.newDocument();

                        d.setXmlStandalone(true);

                        Element e = d.createElement((xmlRootElementName == null) ? "data" : xmlRootElementName);
                        d.appendChild(e);
                        e.setAttribute("id", tableId);
                        DynamicPropertiesCallback cb = new DynamicPropertiesCallback(appName, tableId,
                                instanceId, activeUser, currentLocale, username, userEmail);

                        int idx = 0;
                        Element meta = d.createElementNS(XML_OPENROSA_NAMESPACE, "meta");
                        meta.setPrefix("jr");

                        Element v = d.createElementNS(XML_OPENROSA_NAMESPACE, "instanceID");
                        Text txtNode = d.createTextNode(submissionInstanceId);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        if (xmlDeviceIdPropertyName != null) {
                            String deviceId = propertyManager.getSingularProperty(xmlDeviceIdPropertyName, cb);
                            if (deviceId != null) {
                                v = d.createElementNS(XML_OPENROSA_NAMESPACE, "deviceID");
                                txtNode = d.createTextNode(deviceId);
                                v.appendChild(txtNode);
                                meta.appendChild(v);
                            }
                        }
                        if (xmlUserIdPropertyName != null) {
                            String userId = propertyManager.getSingularProperty(xmlUserIdPropertyName, cb);
                            if (userId != null) {
                                v = d.createElementNS(XML_OPENROSA_NAMESPACE, "userID");
                                txtNode = d.createTextNode(userId);
                                v.appendChild(txtNode);
                                meta.appendChild(v);
                            }
                        }
                        v = d.createElementNS(XML_OPENROSA_NAMESPACE, "timeEnd");
                        txtNode = d.createTextNode(datestamp);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        // these are extra metadata tags...
                        if (instanceName != null) {
                            v = d.createElement("instanceName");
                            txtNode = d.createTextNode(instanceName);
                            v.appendChild(txtNode);
                            meta.appendChild(v);
                        } else {
                            v = d.createElement("instanceName");
                            txtNode = d.createTextNode(savepointTimestamp);
                            v.appendChild(txtNode);
                            meta.appendChild(v);
                        }

                        // these are extra metadata tags...
                        // rowID
                        v = d.createElement("rowID");
                        txtNode = d.createTextNode(instanceId);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        // rowETag
                        v = d.createElement("rowETag");
                        if (rowETag != null) {
                            txtNode = d.createTextNode(rowETag);
                            v.appendChild(txtNode);
                        }
                        meta.appendChild(v);

                        // filterType
                        v = d.createElement("filterType");
                        if (filterType != null) {
                            txtNode = d.createTextNode(filterType);
                            v.appendChild(txtNode);
                        }
                        meta.appendChild(v);

                        // filterValue
                        v = d.createElement("filterValue");
                        if (filterValue != null) {
                            txtNode = d.createTextNode(filterValue);
                            v.appendChild(txtNode);
                        }
                        meta.appendChild(v);

                        // formID
                        v = d.createElement("formID");
                        txtNode = d.createTextNode(formId);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        // locale
                        v = d.createElement("locale");
                        txtNode = d.createTextNode(locale);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        // savepointType
                        v = d.createElement("savepointType");
                        txtNode = d.createTextNode(savepointType);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        // savepointCreator
                        v = d.createElement("savepointCreator");
                        if (savepointCreator != null) {
                            txtNode = d.createTextNode(savepointCreator);
                            v.appendChild(txtNode);
                        }
                        meta.appendChild(v);

                        // savepointTimestamp
                        v = d.createElement("savepointTimestamp");
                        txtNode = d.createTextNode(savepointTimestamp);
                        v.appendChild(txtNode);
                        meta.appendChild(v);

                        // and insert the meta block into the XML

                        e.appendChild(meta);

                        idx = 3;
                        ArrayList<String> entryNames = new ArrayList<String>();
                        entryNames.addAll(values.keySet());
                        Collections.sort(entryNames);
                        for (String name : entryNames) {
                            idx = generateXmlHelper(d, e, idx, name, values, logger);
                        }

                        TransformerFactory factory = TransformerFactory.newInstance();
                        Transformer transformer = factory.newTransformer();
                        Properties outFormat = new Properties();
                        outFormat.setProperty(OutputKeys.INDENT, "no");
                        outFormat.setProperty(OutputKeys.METHOD, "xml");
                        outFormat.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
                        outFormat.setProperty(OutputKeys.VERSION, "1.0");
                        outFormat.setProperty(OutputKeys.ENCODING, "UTF-8");
                        transformer.setOutputProperties(outFormat);

                        ByteArrayOutputStream out = new ByteArrayOutputStream();

                        DOMSource domSource = new DOMSource(d.getDocumentElement());
                        StreamResult result = new StreamResult(out);
                        transformer.transform(domSource, result);

                        out.flush();
                        out.close();

                        b.append(out.toString(CharEncoding.UTF_8));

                        // OK we have the document in the builder (b).
                        String doc = b.toString();

                        freturn.instanceFile = submissionXml;

                        // see if the form is encrypted and we can
                        // encrypt it...
                        EncryptedFormInformation formInfo = EncryptionUtils.getEncryptedFormInformation(appName,
                                tableId, xmlBase64RsaPublicKey, instanceId);
                        if (formInfo != null) {
                            File submissionXmlEnc = new File(submissionXml.getParentFile(),
                                    submissionXml.getName() + ".enc");
                            submissionXmlEnc.delete();
                            // if we are encrypting, the form cannot be
                            // reopened afterward
                            // and encrypt the submission (this is a
                            // one-way operation)...
                            if (!EncryptionUtils.generateEncryptedSubmission(freturn, doc, submissionXml,
                                    submissionXmlEnc, formInfo)) {
                                return null;
                            }
                            // at this point, the freturn object has
                            // been re-written with the encrypted media
                            // and xml files.
                        } else {
                            exportFile(doc, submissionXml, logger);
                        }

                    } else {
                        // Pre-processing -- collapse all mimeUri into filename
                        for (ColumnDefinition defn : orderedDefns.getColumnDefinitions()) {
                            ElementType type = defn.getType();
                            ElementDataType dataType = type.getDataType();

                            if (dataType == ElementDataType.object && type.getElementType().equals("mimeUri")) {
                                Map<String, Object> parent = null;
                                List<ColumnDefinition> parents = new ArrayList<ColumnDefinition>();
                                ColumnDefinition d = defn.getParent();
                                while (d != null) {
                                    parents.add(d);
                                    d = d.getParent();
                                }
                                parent = values;
                                for (int i = parents.size() - 1; i >= 0; --i) {
                                    Object o = parent.get(parents.get(i).getElementName());
                                    if (o == null) {
                                        parent = null;
                                        break;
                                    }
                                    parent = (Map<String, Object>) o;
                                }
                                if (parent != null) {
                                    Object o = parent.get(defn.getElementName());
                                    if (o != null) {
                                        if (dataType == ElementDataType.object
                                                && type.getElementType().equals("mimeUri")) {
                                            Map<String, Object> mimeuri = (Map<String, Object>) o;
                                            String uriFragment = (String) mimeuri.get("uriFragment");
                                            String contentType = (String) mimeuri.get("contentType");
                                            File f = ODKFileUtils.getAsFile(appName, uriFragment);
                                            if (f.equals(manifest)) {
                                                throw new IllegalStateException(
                                                        "Unexpected collision with manifest.json");
                                            }
                                            freturn.addAttachmentFile(f, contentType);
                                            parent.put(defn.getElementName(), f.getName());
                                        } else {
                                            throw new IllegalStateException("Unhandled transform case");
                                        }
                                    }
                                }
                            }
                        }

                        // For JSON, we construct the model, then emit model +
                        // meta + data
                        HashMap<String, Object> wrapper = new HashMap<String, Object>();
                        wrapper.put("tableId", tableId);
                        wrapper.put("instanceId", instanceId);
                        HashMap<String, Object> formDef = new HashMap<String, Object>();
                        formDef.put("table_id", tableId);
                        formDef.put("model", orderedDefns.getDataModel());
                        wrapper.put("formDef", formDef);
                        wrapper.put("data", values);
                        wrapper.put("metadata", new HashMap<String, Object>());
                        HashMap<String, Object> elem = (HashMap<String, Object>) wrapper.get("metadata");
                        if (instanceName != null) {
                            elem.put("instanceName", instanceName);
                        }
                        elem.put("saved", "COMPLETE");
                        elem.put("timestamp", datestamp);

                        b.append(ODKFileUtils.mapper.writeValueAsString(wrapper));

                        // OK we have the document in the builder (b).
                        String doc = b.toString();
                        exportFile(doc, submissionXml, logger);
                    }
                    exportFile(freturn.serializeUriFragmentList(getContext()), manifest, logger);
                    return ParcelFileDescriptor.open(manifest, ParcelFileDescriptor.MODE_READ_ONLY);

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

        } catch (ParserConfigurationException e) {
            logger.printStackTrace(e);
        } catch (TransformerException e) {
            logger.printStackTrace(e);
        } catch (JsonParseException e) {
            logger.printStackTrace(e);
        } catch (JsonMappingException e) {
            logger.printStackTrace(e);
        } catch (IOException e) {
            logger.printStackTrace(e);
        }

    } finally {
        if (db != null) {
            try {
                // release the reference...
                // this does not necessarily close the db handle
                // or terminate any pending transaction
                db.releaseReference();
            } finally {
                // this will release the final reference and close the database
                OdkConnectionFactorySingleton.getOdkConnectionFactoryInterface().removeConnection(appName,
                        dbHandleName);
            }
        }
    }
    return null;
}

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

private BaseTable buildBaseTable(OdkConnectionInterface db, Cursor c, String tableId, boolean canCreateRow) {

    HashMap<String, Integer> mElementKeyToIndex = null;
    String[] mElementKeyForIndex = null;

    if (!c.moveToFirst()) {

        // Attempt to retrieve the columns from the cursor.
        // These may not be available if there were no rows returned.
        // It depends upon the cursor implementation.
        try {/* w ww.j  a va 2  s.c om*/
            int columnCount = c.getColumnCount();
            mElementKeyForIndex = new String[columnCount];
            mElementKeyToIndex = new HashMap<>(columnCount);
            int i;

            for (i = 0; i < columnCount; ++i) {
                String columnName = c.getColumnName(i);
                mElementKeyForIndex[i] = columnName;
                mElementKeyToIndex.put(columnName, i);
            }
        } catch (Exception e) {
            // ignore.
        }

        // if they were not available, declare an empty array.
        if (mElementKeyForIndex == null) {
            mElementKeyForIndex = new String[0];
        }
        c.close();

        // we have no idea what the table should contain because it has no rows...
        BaseTable table = new BaseTable(null, mElementKeyForIndex, mElementKeyToIndex, 0);
        table.setEffectiveAccessCreateRow(canCreateRow);
        return table;
    }

    int rowCount = c.getCount();
    int columnCount = c.getColumnCount();

    BaseTable table = null;

    // These maps will map the element key to the corresponding index in
    // either data or metadata. If the user has defined a column with the
    // element key _my_data, and this column is at index 5 in the data
    // array, dataKeyToIndex would then have a mapping of _my_data:5.
    // The sync_state column, if present at index 7, would have a mapping
    // in metadataKeyToIndex of sync_state:7.
    mElementKeyForIndex = new String[columnCount];
    mElementKeyToIndex = new HashMap<>(columnCount);

    int i;

    for (i = 0; i < columnCount; ++i) {
        String columnName = c.getColumnName(i);
        mElementKeyForIndex[i] = columnName;
        mElementKeyToIndex.put(columnName, i);
    }

    table = new BaseTable(null, mElementKeyForIndex, mElementKeyToIndex, rowCount);

    String[] rowData = new String[columnCount];
    do {
        // First get the user-defined data for this row.
        for (i = 0; i < columnCount; i++) {
            String value = CursorUtils.getIndexAsString(c, i);
            rowData[i] = value;
        }

        Row nextRow = new Row(rowData.clone(), table);
        table.addRow(nextRow);
    } while (c.moveToNext());
    c.close();

    table.setEffectiveAccessCreateRow(canCreateRow);

    return table;
}

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

/**
 * Inserts a checkpoint row for the given rowId in the tableId. Checkpoint
 * rows are created by ODK Survey to hold intermediate values during the
 * filling-in of the form. They act as restore points in the Survey, should
 * the application die.//www .ja  v  a2 s  . c  o  m
 *
 * @param db
 * @param tableId
 * @param orderedColumns
 * @param cvValues
 * @param rowId
 * @param activeUser
 * @param rolesList
 * @param locale
 */
public void insertCheckpointRowWithId(OdkConnectionInterface db, String tableId, OrderedColumns orderedColumns,
        ContentValues cvValues, String rowId, String activeUser, String rolesList, String locale)
        throws ActionNotAuthorizedException {

    if (cvValues.size() <= 0) {
        throw new IllegalArgumentException(t + ": No values to add into table for checkpoint" + tableId);
    }

    // these are all managed in the database layer...
    // the user should NOT set them...

    if (cvValues.containsKey(DataTableColumns.SAVEPOINT_TIMESTAMP)) {
        throw new IllegalArgumentException(
                t + ": No user supplied savepoint timestamp can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.SAVEPOINT_TYPE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied savepoint type can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.ROW_ETAG)) {
        throw new IllegalArgumentException(t + ": No user supplied row ETag can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.SYNC_STATE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied sync state can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.CONFLICT_TYPE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied conflict type can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.FILTER_VALUE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied filter value can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.FILTER_TYPE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied filter type can be included for a checkpoint");
    }

    // If a rowId is specified, a cursor will be needed to
    // get the current row to create a checkpoint with the relevant data
    Cursor c = null;
    try {
        // Allow the user to pass in no rowId if this is the first
        // checkpoint row that the user is adding
        if (rowId == null) {

            // TODO: is this even valid any more? I think we disallow this in the AIDL flow.

            String rowIdToUse = LocalizationUtils.genUUID();
            HashMap<String, Object> currValues = new HashMap<String, Object>();
            for (String key : cvValues.keySet()) {
                currValues.put(key, cvValues.get(key));
            }
            currValues.put(DataTableColumns._ID, rowIdToUse);
            currValues.put(DataTableColumns.SYNC_STATE, SyncState.new_row.name());
            insertCheckpointIntoExistingTable(db, tableId, orderedColumns, currValues, activeUser, rolesList,
                    locale, true, null, null);
            return;
        }

        StringBuilder b = new StringBuilder();
        b.append(K_DATATABLE_ID_EQUALS_PARAM).append(S_AND).append(DataTableColumns.SAVEPOINT_TIMESTAMP)
                .append(" IN (SELECT MAX(").append(DataTableColumns.SAVEPOINT_TIMESTAMP).append(") FROM ")
                .append(tableId).append(K_WHERE).append(K_DATATABLE_ID_EQUALS_PARAM).append(")");
        c = db.query(tableId, null, b.toString(), new Object[] { rowId, rowId }, null, null, null, null);
        c.moveToFirst();

        if (c.getCount() > 1) {
            throw new IllegalStateException(t + ": More than one checkpoint at a timestamp");
        }

        // Inserting a checkpoint for the first time
        if (c.getCount() <= 0) {
            HashMap<String, Object> currValues = new HashMap<String, Object>();
            for (String key : cvValues.keySet()) {
                currValues.put(key, cvValues.get(key));
            }
            currValues.put(DataTableColumns._ID, rowId);
            currValues.put(DataTableColumns.SYNC_STATE, SyncState.new_row.name());
            insertCheckpointIntoExistingTable(db, tableId, orderedColumns, currValues, activeUser, rolesList,
                    locale, true, null, null);
            return;
        } else {
            // Make sure that the conflict_type of any existing row
            // is null, otherwise throw an exception
            int conflictIndex = c.getColumnIndex(DataTableColumns.CONFLICT_TYPE);
            if (!c.isNull(conflictIndex)) {
                throw new IllegalStateException(
                        t + ":  A checkpoint cannot be added for a row that is in conflict");
            }

            HashMap<String, Object> currValues = new HashMap<String, Object>();
            for (String key : cvValues.keySet()) {
                currValues.put(key, cvValues.get(key));
            }

            // This is unnecessary
            // We should only have one row at this point
            //c.moveToFirst();

            String priorFilterType = null;
            String priorFilterValue = null;

            // Get the number of columns to iterate over and add
            // those values to the content values
            for (int i = 0; i < c.getColumnCount(); i++) {
                String name = c.getColumnName(i);

                if (currValues.containsKey(name)) {
                    continue;
                }

                // omitting savepoint timestamp will generate a new timestamp.
                if (name.equals(DataTableColumns.SAVEPOINT_TIMESTAMP)) {
                    continue;
                }

                // set savepoint type to null to mark this as a checkpoint
                if (name.equals(DataTableColumns.SAVEPOINT_TYPE)) {
                    currValues.put(name, null);
                    continue;
                }

                // sync state (a non-null field) should either remain 'new_row'
                // or be set to 'changed' for all other existing values.
                if (name.equals(DataTableColumns.SYNC_STATE)) {
                    String priorState = c.getString(i);
                    if (priorState.equals(SyncState.new_row.name())) {
                        currValues.put(name, SyncState.new_row.name());
                    } else {
                        currValues.put(name, SyncState.changed.name());
                    }
                    continue;
                }

                if (c.isNull(i)) {
                    currValues.put(name, null);
                    continue;
                }

                // otherwise, just copy the values over...
                Class<?> theClass = CursorUtils.getIndexDataType(c, i);
                Object object = CursorUtils.getIndexAsType(c, theClass, i);
                insertValueIntoContentValues(currValues, theClass, name, object);

                if (name.equals(DataTableColumns.FILTER_TYPE)) {
                    priorFilterType = c.getString(i);
                }

                if (name.equals(DataTableColumns.FILTER_VALUE)) {
                    priorFilterValue = c.getString(i);
                }
            }

            insertCheckpointIntoExistingTable(db, tableId, orderedColumns, currValues, activeUser, rolesList,
                    locale, false, priorFilterType, priorFilterValue);
        }
    } finally {
        if (c != null && !c.isClosed()) {
            c.close();
        }
    }
}

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

/**
 * Inserts a checkpoint row for the given rowId in the tableId. Checkpoint
 * rows are created by ODK Survey to hold intermediate values during the
 * filling-in of the form. They act as restore points in the Survey, should
 * the application die./*from  ww  w . j a v  a  2  s. c om*/
 *
 * @param db
 * @param tableId
 * @param orderedColumns
 * @param cvValues
 * @param rowId
 * @param activeUser
 * @param rolesList
 * @param locale
 */
public void insertCheckpointRowWithId(OdkConnectionInterface db, String tableId, OrderedColumns orderedColumns,
        ContentValues cvValues, String rowId, String activeUser, String rolesList, String locale)
        throws ActionNotAuthorizedException {

    if (cvValues.size() <= 0) {
        throw new IllegalArgumentException(t + ": No values to add into table for checkpoint" + tableId);
    }

    // these are all managed in the database layer...
    // the user should NOT set them...

    if (cvValues.containsKey(DataTableColumns.SAVEPOINT_TIMESTAMP)) {
        throw new IllegalArgumentException(
                t + ": No user supplied savepoint timestamp can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.SAVEPOINT_TYPE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied savepoint type can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.ROW_ETAG)) {
        throw new IllegalArgumentException(t + ": No user supplied row ETag can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.SYNC_STATE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied sync state can be included for a checkpoint");
    }

    if (cvValues.containsKey(DataTableColumns.CONFLICT_TYPE)) {
        throw new IllegalArgumentException(
                t + ": No user supplied conflict type can be included for a checkpoint");
    }

    // If a rowId is specified, a cursor will be needed to
    // get the current row to create a checkpoint with the relevant data
    Cursor c = null;
    try {
        // Allow the user to pass in no rowId if this is the first
        // checkpoint row that the user is adding
        if (rowId == null) {

            // TODO: is this even valid any more? I think we disallow this in the AIDL flow.

            String rowIdToUse = LocalizationUtils.genUUID();
            HashMap<String, Object> currValues = new HashMap<String, Object>();
            for (String key : cvValues.keySet()) {
                currValues.put(key, cvValues.get(key));
            }
            currValues.put(DataTableColumns._ID, rowIdToUse);
            currValues.put(DataTableColumns.SYNC_STATE, SyncState.new_row.name());
            insertCheckpointIntoExistingTable(db, tableId, orderedColumns, currValues, activeUser, rolesList,
                    locale, true, null, null, null, null, null);
            return;
        }

        StringBuilder b = new StringBuilder();
        b.append(K_DATATABLE_ID_EQUALS_PARAM).append(S_AND).append(DataTableColumns.SAVEPOINT_TIMESTAMP)
                .append(" IN (SELECT MAX(").append(DataTableColumns.SAVEPOINT_TIMESTAMP).append(") FROM ")
                .append(tableId).append(K_WHERE).append(K_DATATABLE_ID_EQUALS_PARAM).append(")");
        c = db.query(tableId, null, b.toString(), new Object[] { rowId, rowId }, null, null, null, null);
        c.moveToFirst();

        if (c.getCount() > 1) {
            throw new IllegalStateException(t + ": More than one checkpoint at a timestamp");
        }

        // Inserting a checkpoint for the first time
        if (c.getCount() <= 0) {
            HashMap<String, Object> currValues = new HashMap<String, Object>();
            for (String key : cvValues.keySet()) {
                currValues.put(key, cvValues.get(key));
            }
            currValues.put(DataTableColumns._ID, rowId);
            currValues.put(DataTableColumns.SYNC_STATE, SyncState.new_row.name());
            insertCheckpointIntoExistingTable(db, tableId, orderedColumns, currValues, activeUser, rolesList,
                    locale, true, null, null, null, null, null);
            return;
        } else {
            // Make sure that the conflict_type of any existing row
            // is null, otherwise throw an exception
            int conflictIndex = c.getColumnIndex(DataTableColumns.CONFLICT_TYPE);
            if (!c.isNull(conflictIndex)) {
                throw new IllegalStateException(
                        t + ":  A checkpoint cannot be added for a row that is in conflict");
            }

            // these are all managed in the database layer...
            // the user should NOT set them...

            if (cvValues.containsKey(DataTableColumns.DEFAULT_ACCESS)) {
                throw new IllegalArgumentException(
                        t + ": No user supplied default access can be included for a checkpoint");
            }

            if (cvValues.containsKey(DataTableColumns.ROW_OWNER)) {
                throw new IllegalArgumentException(
                        t + ": No user supplied row owner can be included for a checkpoint");
            }

            if (cvValues.containsKey(DataTableColumns.GROUP_READ_ONLY)) {
                throw new IllegalArgumentException(
                        t + ": No user supplied group read only can be included for a checkpoint");
            }

            if (cvValues.containsKey(DataTableColumns.GROUP_MODIFY)) {
                throw new IllegalArgumentException(
                        t + ": No user supplied group modify can be included for a checkpoint");
            }

            if (cvValues.containsKey(DataTableColumns.GROUP_PRIVILEGED)) {
                throw new IllegalArgumentException(
                        t + ": No user supplied group privileged can be included for a checkpoint");
            }

            HashMap<String, Object> currValues = new HashMap<String, Object>();
            for (String key : cvValues.keySet()) {
                currValues.put(key, cvValues.get(key));
            }

            // This is unnecessary
            // We should only have one row at this point
            //c.moveToFirst();

            String priorDefaultAccess = null;
            String priorOwner = null;
            String priorGroupReadOnly = null;
            String priorGroupModify = null;
            String priorGroupPrivileged = null;

            // Get the number of columns to iterate over and add
            // those values to the content values
            for (int i = 0; i < c.getColumnCount(); i++) {
                String name = c.getColumnName(i);

                if (name.equals(DataTableColumns.DEFAULT_ACCESS)) {
                    priorDefaultAccess = c.getString(i);
                }

                if (name.equals(DataTableColumns.ROW_OWNER)) {
                    priorOwner = c.getString(i);
                }

                if (name.equals(DataTableColumns.GROUP_READ_ONLY)) {
                    priorGroupReadOnly = c.getString(i);
                }

                if (name.equals(DataTableColumns.GROUP_MODIFY)) {
                    priorGroupModify = c.getString(i);
                }

                if (name.equals(DataTableColumns.GROUP_PRIVILEGED)) {
                    priorGroupPrivileged = c.getString(i);
                }

                if (currValues.containsKey(name)) {
                    continue;
                }

                // omitting savepoint timestamp will generate a new timestamp.
                if (name.equals(DataTableColumns.SAVEPOINT_TIMESTAMP)) {
                    continue;
                }

                // set savepoint type to null to mark this as a checkpoint
                if (name.equals(DataTableColumns.SAVEPOINT_TYPE)) {
                    currValues.put(name, null);
                    continue;
                }

                // sync state (a non-null field) should either remain 'new_row'
                // or be set to 'changed' for all other existing values.
                if (name.equals(DataTableColumns.SYNC_STATE)) {
                    String priorState = c.getString(i);
                    if (priorState.equals(SyncState.new_row.name())) {
                        currValues.put(name, SyncState.new_row.name());
                    } else {
                        currValues.put(name, SyncState.changed.name());
                    }
                    continue;
                }

                if (c.isNull(i)) {
                    currValues.put(name, null);
                    continue;
                }

                // otherwise, just copy the values over...
                Class<?> theClass = CursorUtils.getIndexDataType(c, i);
                Object object = CursorUtils.getIndexAsType(c, theClass, i);
                insertValueIntoContentValues(currValues, theClass, name, object);
            }

            insertCheckpointIntoExistingTable(db, tableId, orderedColumns, currValues, activeUser, rolesList,
                    locale, false, priorDefaultAccess, priorOwner, priorGroupReadOnly, priorGroupModify,
                    priorGroupPrivileged);
        }
    } finally {
        if (c != null && !c.isClosed()) {
            c.close();
        }
    }
}