19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.database;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A mutable cursor implementation backed by an array of {@code Object}s. Use
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #newRow()} to add rows. Automatically expands internal capacity
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as needed.
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class MatrixCursor extends AbstractCursor {
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final String[] columnNames;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Object[] data;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int rowCount = 0;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int columnCount;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Constructs a new cursor with the given initial capacity.
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param columnNames names of the columns, the ordering of which
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  determines column ordering elsewhere in this cursor
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param initialCapacity in rows
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public MatrixCursor(String[] columnNames, int initialCapacity) {
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.columnNames = columnNames;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.columnCount = columnNames.length;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (initialCapacity < 1) {
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            initialCapacity = 1;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.data = new Object[columnCount * initialCapacity];
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Constructs a new cursor.
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param columnNames names of the columns, the ordering of which
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  determines column ordering elsewhere in this cursor
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public MatrixCursor(String[] columnNames) {
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(columnNames, 16);
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Gets value at the given column for the current row.
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Object get(int column) {
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (column < 0 || column >= columnCount) {
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CursorIndexOutOfBoundsException("Requested column: "
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + column + ", # of columns: " +  columnCount);
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mPos < 0) {
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CursorIndexOutOfBoundsException("Before first row.");
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mPos >= rowCount) {
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new CursorIndexOutOfBoundsException("After last row.");
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return data[mPos * columnCount + column];
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adds a new row to the end and returns a builder for that row. Not safe
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for concurrent use.
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return builder which can be used to set the column values for the new
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  row
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public RowBuilder newRow() {
869d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey        final int row = rowCount++;
879d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey        final int endIndex = rowCount * columnCount;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ensureCapacity(endIndex);
899d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey        return new RowBuilder(row);
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adds a new row to the end with the given column values. Not safe
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for concurrent use.
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if {@code columnValues.length !=
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  columnNames.length}
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param columnValues in the same order as the the column names specified
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  at cursor construction time
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addRow(Object[] columnValues) {
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (columnValues.length != columnCount) {
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("columnNames.length = "
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + columnCount + ", columnValues.length = "
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + columnValues.length);
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int start = rowCount++ * columnCount;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ensureCapacity(start + columnCount);
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        System.arraycopy(columnValues, 0, data, start, columnCount);
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adds a new row to the end with the given column values. Not safe
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for concurrent use.
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if {@code columnValues.size() !=
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  columnNames.length}
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param columnValues in the same order as the the column names specified
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  at cursor construction time
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addRow(Iterable<?> columnValues) {
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int start = rowCount * columnCount;
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int end = start + columnCount;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ensureCapacity(end);
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (columnValues instanceof ArrayList<?>) {
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            addRow((ArrayList<?>) columnValues, start);
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int current = start;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object[] localData = data;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (Object columnValue : columnValues) {
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (current == end) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // TODO: null out row?
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalArgumentException(
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "columnValues.size() > columnNames.length");
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            localData[current++] = columnValue;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (current != end) {
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // TODO: null out row?
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException(
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "columnValues.size() < columnNames.length");
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Increase row count here in case we encounter an exception.
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rowCount++;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Optimization for {@link ArrayList}. */
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void addRow(ArrayList<?> columnValues, int start) {
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int size = columnValues.size();
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (size != columnCount) {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("columnNames.length = "
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + columnCount + ", columnValues.size() = " + size);
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rowCount++;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object[] localData = data;
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < size; i++) {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            localData[start + i] = columnValues.get(i);
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Ensures that this cursor has enough capacity. */
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void ensureCapacity(int size) {
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (size > data.length) {
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Object[] oldData = this.data;
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int newSize = data.length * 2;
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (newSize < size) {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                newSize = size;
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.data = new Object[newSize];
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.arraycopy(oldData, 0, this.data, 0, oldData.length);
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1829d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey     * Builds a row of values using either of these approaches:
1839d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey     * <ul>
1849d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey     * <li>Values can be added with explicit column ordering using
1859d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey     * {@link #add(Object)}, which starts from the left-most column and adds one
1869d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey     * column value at a time. This follows the same ordering as the column
1879d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey     * names specified at cursor construction time.
1889d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey     * <li>Column and value pairs can be offered for possible inclusion using
189b7757a6b32edea62a1a9a803ad83579220f26100Jeff Sharkey     * {@link #add(String, Object)}. If the cursor includes the given column,
1909d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey     * the value will be set for that column, otherwise the value is ignored.
1919d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey     * This approach is useful when matching data to a custom projection.
1929d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey     * </ul>
1939d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey     * Undefined values are left as {@code null}.
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public class RowBuilder {
1969d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey        private final int row;
1979d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey        private final int endIndex;
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private int index;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2019d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey        RowBuilder(int row) {
2029d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey            this.row = row;
2039d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey            this.index = row * columnCount;
2049d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey            this.endIndex = index + columnCount;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Sets the next column value in this row.
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @throws CursorIndexOutOfBoundsException if you try to add too many
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *  values
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @return this builder to support chaining
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public RowBuilder add(Object columnValue) {
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (index == endIndex) {
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new CursorIndexOutOfBoundsException(
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "No more columns left.");
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            data[index++] = columnValue;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this;
2229d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey        }
2239d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey
2249d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey        /**
2259d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey         * Offer value for possible inclusion if this cursor defines the given
2269d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey         * column. Columns not defined by the cursor are silently ignored.
2279d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey         *
2289d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey         * @return this builder to support chaining
2299d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey         */
230b7757a6b32edea62a1a9a803ad83579220f26100Jeff Sharkey        public RowBuilder add(String columnName, Object value) {
2319d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey            for (int i = 0; i < columnNames.length; i++) {
2329d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey                if (columnName.equals(columnNames[i])) {
2339d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey                    data[(row * columnCount) + i] = value;
2349d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey                }
2359d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey            }
2369d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey            return this;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // AbstractCursor implementation.
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
242f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert    @Override
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getCount() {
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return rowCount;
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
247f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert    @Override
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String[] getColumnNames() {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return columnNames;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
252f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert    @Override
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getString(int column) {
254f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        Object value = get(column);
255f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        if (value == null) return null;
256f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        return value.toString();
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
259f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert    @Override
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public short getShort(int column) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object value = get(column);
262f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        if (value == null) return 0;
263f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        if (value instanceof Number) return ((Number) value).shortValue();
264f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        return Short.parseShort(value.toString());
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
267f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert    @Override
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getInt(int column) {
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object value = get(column);
270f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        if (value == null) return 0;
271f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        if (value instanceof Number) return ((Number) value).intValue();
272f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        return Integer.parseInt(value.toString());
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
275f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert    @Override
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public long getLong(int column) {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object value = get(column);
278f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        if (value == null) return 0;
279f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        if (value instanceof Number) return ((Number) value).longValue();
280f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        return Long.parseLong(value.toString());
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
283f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert    @Override
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public float getFloat(int column) {
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object value = get(column);
286f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        if (value == null) return 0.0f;
287f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        if (value instanceof Number) return ((Number) value).floatValue();
288f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        return Float.parseFloat(value.toString());
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
291f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert    @Override
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public double getDouble(int column) {
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object value = get(column);
294f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        if (value == null) return 0.0d;
295f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        if (value instanceof Number) return ((Number) value).doubleValue();
296f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert        return Double.parseDouble(value.toString());
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299f2cec58d90381c05033f26add5693252e68f48f9Bjorn Bringert    @Override
300783123f79de3210d27ef2aab103bac7737b64cafTodd Kennedy    public byte[] getBlob(int column) {
301783123f79de3210d27ef2aab103bac7737b64cafTodd Kennedy        Object value = get(column);
302783123f79de3210d27ef2aab103bac7737b64cafTodd Kennedy        return (byte[]) value;
303783123f79de3210d27ef2aab103bac7737b64cafTodd Kennedy    }
304783123f79de3210d27ef2aab103bac7737b64cafTodd Kennedy
305783123f79de3210d27ef2aab103bac7737b64cafTodd Kennedy    @Override
3068b0dd7da360d70920a37802eb455ba41500d3b45Vasu Nori    public int getType(int column) {
3078b0dd7da360d70920a37802eb455ba41500d3b45Vasu Nori        return DatabaseUtils.getTypeOfObject(get(column));
3088b0dd7da360d70920a37802eb455ba41500d3b45Vasu Nori    }
3098b0dd7da360d70920a37802eb455ba41500d3b45Vasu Nori
3108b0dd7da360d70920a37802eb455ba41500d3b45Vasu Nori    @Override
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isNull(int column) {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return get(column) == null;
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
315