refactor source tree organization, switch to meson

This commit is contained in:
Mis012
2022-10-02 23:06:56 +02:00
parent 2f785e2a59
commit 449090143e
296 changed files with 171615 additions and 69 deletions

View File

@@ -0,0 +1,476 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.database;
//import android.content.ContentResolver;
//import android.net.Uri;
import android.os.Bundle;
import java.io.Closeable;
class Uri {}
class ContentResolver {}
class CharArrayBuffer {}
class ContentObserver {}
class DataSetObserver {}
/**
* This interface provides random read-write access to the result set returned
* by a database query.
* <p>
* Cursor implementations are not required to be synchronized so code using a Cursor from multiple
* threads should perform its own synchronization when using the Cursor.
* </p><p>
* Implementations should subclass {@link AbstractCursor}.
* </p>
*/
public interface Cursor extends Closeable {
/*
* Values returned by {@link #getType(int)}.
* These should be consistent with the corresponding types defined in CursorWindow.h
*/
/** Value returned by {@link #getType(int)} if the specified column is null */
static final int FIELD_TYPE_NULL = 0;
/** Value returned by {@link #getType(int)} if the specified column type is integer */
static final int FIELD_TYPE_INTEGER = 1;
/** Value returned by {@link #getType(int)} if the specified column type is float */
static final int FIELD_TYPE_FLOAT = 2;
/** Value returned by {@link #getType(int)} if the specified column type is string */
static final int FIELD_TYPE_STRING = 3;
/** Value returned by {@link #getType(int)} if the specified column type is blob */
static final int FIELD_TYPE_BLOB = 4;
/**
* Returns the numbers of rows in the cursor.
*
* @return the number of rows in the cursor.
*/
int getCount();
/**
* Returns the current position of the cursor in the row set.
* The value is zero-based. When the row set is first returned the cursor
* will be at positon -1, which is before the first row. After the
* last row is returned another call to next() will leave the cursor past
* the last entry, at a position of count().
*
* @return the current cursor position.
*/
// int getPosition();
/**
* Move the cursor by a relative amount, forward or backward, from the
* current position. Positive offsets move forwards, negative offsets move
* backwards. If the final position is outside of the bounds of the result
* set then the resultant position will be pinned to -1 or count() depending
* on whether the value is off the front or end of the set, respectively.
*
* <p>This method will return true if the requested destination was
* reachable, otherwise, it returns false. For example, if the cursor is at
* currently on the second entry in the result set and move(-5) is called,
* the position will be pinned at -1, and false will be returned.
*
* @param offset the offset to be applied from the current position.
* @return whether the requested move fully succeeded.
*/
// boolean move(int offset);
/**
* Move the cursor to an absolute position. The valid
* range of values is -1 &lt;= position &lt;= count.
*
* <p>This method will return true if the request destination was reachable,
* otherwise, it returns false.
*
* @param position the zero-based position to move to.
* @return whether the requested move fully succeeded.
*/
// boolean moveToPosition(int position);
/**
* Move the cursor to the first row.
*
* <p>This method will return false if the cursor is empty.
*
* @return whether the move succeeded.
*/
boolean moveToFirst();
/**
* Move the cursor to the last row.
*
* <p>This method will return false if the cursor is empty.
*
* @return whether the move succeeded.
*/
// boolean moveToLast();
/**
* Move the cursor to the next row.
*
* <p>This method will return false if the cursor is already past the
* last entry in the result set.
*
* @return whether the move succeeded.
*/
boolean moveToNext();
/**
* Move the cursor to the previous row.
*
* <p>This method will return false if the cursor is already before the
* first entry in the result set.
*
* @return whether the move succeeded.
*/
// boolean moveToPrevious();
/**
* Returns whether the cursor is pointing to the first row.
*
* @return whether the cursor is pointing at the first entry.
*/
// boolean isFirst();
/**
* Returns whether the cursor is pointing to the last row.
*
* @return whether the cursor is pointing at the last entry.
*/
// boolean isLast();
/**
* Returns whether the cursor is pointing to the position before the first
* row.
*
* @return whether the cursor is before the first result.
*/
// boolean isBeforeFirst();
/**
* Returns whether the cursor is pointing to the position after the last
* row.
*
* @return whether the cursor is after the last result.
*/
boolean isAfterLast();
/**
* Returns the zero-based index for the given column name, or -1 if the column doesn't exist.
* If you expect the column to exist use {@link #getColumnIndexOrThrow(String)} instead, which
* will make the error more clear.
*
* @param columnName the name of the target column.
* @return the zero-based column index for the given column name, or -1 if
* the column name does not exist.
* @see #getColumnIndexOrThrow(String)
*/
int getColumnIndex(String columnName);
/**
* Returns the zero-based index for the given column name, or throws
* {@link IllegalArgumentException} if the column doesn't exist. If you're not sure if
* a column will exist or not use {@link #getColumnIndex(String)} and check for -1, which
* is more efficient than catching the exceptions.
*
* @param columnName the name of the target column.
* @return the zero-based column index for the given column name
* @see #getColumnIndex(String)
* @throws IllegalArgumentException if the column does not exist
*/
// int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException;
/**
* Returns the column name at the given zero-based column index.
*
* @param columnIndex the zero-based index of the target column.
* @return the column name for the given column index.
*/
// String getColumnName(int columnIndex);
/**
* Returns a string array holding the names of all of the columns in the
* result set in the order in which they were listed in the result.
*
* @return the names of the columns returned in this query.
*/
// String[] getColumnNames();
/**
* Return total number of columns
* @return number of columns
*/
// int getColumnCount();
/**
* Returns the value of the requested column as a byte array.
*
* <p>The result and whether this method throws an exception when the
* column value is null or the column type is not a blob type is
* implementation-defined.
*
* @param columnIndex the zero-based index of the target column.
* @return the value of that column as a byte array.
*/
// byte[] getBlob(int columnIndex);
/**
* Returns the value of the requested column as a String.
*
* <p>The result and whether this method throws an exception when the
* column value is null or the column type is not a string type is
* implementation-defined.
*
* @param columnIndex the zero-based index of the target column.
* @return the value of that column as a String.
*/
String getString(int columnIndex);
/**
* Retrieves the requested column text and stores it in the buffer provided.
* If the buffer size is not sufficient, a new char buffer will be allocated
* and assigned to CharArrayBuffer.data
* @param columnIndex the zero-based index of the target column.
* if the target column is null, return buffer
* @param buffer the buffer to copy the text into.
*/
// void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer);
/**
* Returns the value of the requested column as a short.
*
* <p>The result and whether this method throws an exception when the
* column value is null, the column type is not an integral type, or the
* integer value is outside the range [<code>Short.MIN_VALUE</code>,
* <code>Short.MAX_VALUE</code>] is implementation-defined.
*
* @param columnIndex the zero-based index of the target column.
* @return the value of that column as a short.
*/
// short getShort(int columnIndex);
/**
* Returns the value of the requested column as an int.
*
* <p>The result and whether this method throws an exception when the
* column value is null, the column type is not an integral type, or the
* integer value is outside the range [<code>Integer.MIN_VALUE</code>,
* <code>Integer.MAX_VALUE</code>] is implementation-defined.
*
* @param columnIndex the zero-based index of the target column.
* @return the value of that column as an int.
*/
int getInt(int columnIndex);
/**
* Returns the value of the requested column as a long.
*
* <p>The result and whether this method throws an exception when the
* column value is null, the column type is not an integral type, or the
* integer value is outside the range [<code>Long.MIN_VALUE</code>,
* <code>Long.MAX_VALUE</code>] is implementation-defined.
*
* @param columnIndex the zero-based index of the target column.
* @return the value of that column as a long.
*/
long getLong(int columnIndex);
/**
* Returns the value of the requested column as a float.
*
* <p>The result and whether this method throws an exception when the
* column value is null, the column type is not a floating-point type, or the
* floating-point value is not representable as a <code>float</code> value is
* implementation-defined.
*
* @param columnIndex the zero-based index of the target column.
* @return the value of that column as a float.
*/
// float getFloat(int columnIndex);
/**
* Returns the value of the requested column as a double.
*
* <p>The result and whether this method throws an exception when the
* column value is null, the column type is not a floating-point type, or the
* floating-point value is not representable as a <code>double</code> value is
* implementation-defined.
*
* @param columnIndex the zero-based index of the target column.
* @return the value of that column as a double.
*/
// double getDouble(int columnIndex);
/**
* Returns data type of the given column's value.
* The preferred type of the column is returned but the data may be converted to other types
* as documented in the get-type methods such as {@link #getInt(int)}, {@link #getFloat(int)}
* etc.
*<p>
* Returned column types are
* <ul>
* <li>{@link #FIELD_TYPE_NULL}</li>
* <li>{@link #FIELD_TYPE_INTEGER}</li>
* <li>{@link #FIELD_TYPE_FLOAT}</li>
* <li>{@link #FIELD_TYPE_STRING}</li>
* <li>{@link #FIELD_TYPE_BLOB}</li>
*</ul>
*</p>
*
* @param columnIndex the zero-based index of the target column.
* @return column value type
*/
// int getType(int columnIndex);
/**
* Returns <code>true</code> if the value in the indicated column is null.
*
* @param columnIndex the zero-based index of the target column.
* @return whether the column value is null.
*/
// boolean isNull(int columnIndex);
/**
* Deactivates the Cursor, making all calls on it fail until {@link #requery} is called.
* Inactive Cursors use fewer resources than active Cursors.
* Calling {@link #requery} will make the cursor active again.
* @deprecated Since {@link #requery()} is deprecated, so too is this.
*/
void deactivate();
/**
* Performs the query that created the cursor again, refreshing its
* contents. This may be done at any time, including after a call to {@link
* #deactivate}.
*
* Since this method could execute a query on the database and potentially take
* a while, it could cause ANR if it is called on Main (UI) thread.
* A warning is printed if this method is being executed on Main thread.
*
* @return true if the requery succeeded, false if not, in which case the
* cursor becomes invalid.
* @deprecated Don't use this. Just request a new cursor, so you can do this
* asynchronously and update your list view once the new cursor comes back.
*/
@Deprecated
boolean requery();
/**
* Closes the Cursor, releasing all of its resources and making it completely invalid.
* Unlike {@link #deactivate()} a call to {@link #requery()} will not make the Cursor valid
* again.
*/
void close();
/**
* return true if the cursor is closed
* @return true if the cursor is closed.
*/
// boolean isClosed();
/**
* Register an observer that is called when changes happen to the content backing this cursor.
* Typically the data set won't change until {@link #requery()} is called.
*
* @param observer the object that gets notified when the content backing the cursor changes.
* @see #unregisterContentObserver(ContentObserver)
*/
// void registerContentObserver(ContentObserver observer);
/**
* Unregister an observer that has previously been registered with this
* cursor via {@link #registerContentObserver}.
*
* @param observer the object to unregister.
* @see #registerContentObserver(ContentObserver)
*/
// void unregisterContentObserver(ContentObserver observer);
/**
* Register an observer that is called when changes happen to the contents
* of the this cursors data set, for example, when the data set is changed via
* {@link #requery()}, {@link #deactivate()}, or {@link #close()}.
*
* @param observer the object that gets notified when the cursors data set changes.
* @see #unregisterDataSetObserver(DataSetObserver)
*/
// void registerDataSetObserver(DataSetObserver observer);
/**
* Unregister an observer that has previously been registered with this
* cursor via {@link #registerContentObserver}.
*
* @param observer the object to unregister.
* @see #registerDataSetObserver(DataSetObserver)
*/
// void unregisterDataSetObserver(DataSetObserver observer);
/**
* Register to watch a content URI for changes. This can be the URI of a specific data row (for
* example, "content://my_provider_type/23"), or a a generic URI for a content type.
*
* @param cr The content resolver from the caller's context. The listener attached to
* this resolver will be notified.
* @param uri The content URI to watch.
*/
// void setNotificationUri(ContentResolver cr, Uri uri);
/**
* Return the URI at which notifications of changes in this Cursor's data
* will be delivered, as previously set by {@link #setNotificationUri}.
* @return Returns a URI that can be used with
* {@link ContentResolver#registerContentObserver(android.net.Uri, boolean, ContentObserver)
* ContentResolver.registerContentObserver} to find out about changes to this Cursor's
* data. May be null if no notification URI has been set.
*/
// Uri getNotificationUri();
/**
* onMove() will only be called across processes if this method returns true.
* @return whether all cursor movement should result in a call to onMove().
*/
// boolean getWantsAllOnMoveCalls();
/**
* Returns a bundle of extra values. This is an optional way for cursors to provide out-of-band
* metadata to their users. One use of this is for reporting on the progress of network requests
* that are required to fetch data for the cursor.
*
* <p>These values may only change when requery is called.
* @return cursor-defined values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY} if there
* are no values. Never <code>null</code>.
*/
// Bundle getExtras();
/**
* This is an out-of-band way for the the user of a cursor to communicate with the cursor. The
* structure of each bundle is entirely defined by the cursor.
*
* <p>One use of this is to tell a cursor that it should retry its network request after it
* reported an error.
* @param extras extra values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY}.
* Never <code>null</code>.
* @return extra values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY}.
* Never <code>null</code>.
*/
// Bundle respond(Bundle extras);
}

View File

@@ -0,0 +1,5 @@
package android.database.sqlite;
class DatabaseErrorHandler {
}

View File

@@ -0,0 +1,307 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.database.sqlite;
//import android.database.AbstractWindowedCursor;
//import android.database.CursorWindow;
//import android.database.DatabaseUtils;
//import android.os.StrictMode;
import android.util.Log;
import java.util.HashMap;
import java.util.Map;
import android.database.Cursor;
/**
* A Cursor implementation that exposes results from a query on a
* {@link SQLiteDatabase}.
*
* SQLiteCursor is not internally synchronized so code using a SQLiteCursor from multiple
* threads should perform its own synchronization when using the SQLiteCursor.
*/
public class SQLiteCursor /*extends AbstractWindowedCursor*/ implements Cursor {
static final String TAG = "SQLiteCursor";
static final int NO_COUNT = -1;
/** The name of the table to edit */
private final String mEditTable = "ZZZ";
/** The names of the columns in the rows */
private final String[] mColumns = {"AAA"};
/** The query object for the cursor */
private final SQLiteQuery mQuery = null;
/** The compiled query this cursor came from */
private final SQLiteCursorDriver mDriver = null;
/** The number of rows in the cursor */
private int mCount = NO_COUNT;
/** The number of rows that can fit in the cursor window, 0 if unknown */
private int mCursorWindowCapacity = -1;
/** A mapping of column names to column indices, to speed up lookups */
private Map<String, Integer> mColumnNameMap = null;
/** Used to find out where a cursor was allocated in case it never got released. */
private final Throwable mStackTrace = null;
/**
* Execute a query and provide access to its result set through a Cursor
* interface. For a query such as: {@code SELECT name, birth, phone FROM
* myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth,
* phone) would be in the projection argument and everything from
* {@code FROM} onward would be in the params argument.
*
* @param db a reference to a Database object that is already constructed
* and opened. This param is not used any longer
* @param editTable the name of the table used for this query
* @param query the rest of the query terms
* cursor is finalized
* @deprecated use {@link #SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)} instead
*/
@Deprecated
public SQLiteCursor(SQLiteDatabase db, SQLiteCursorDriver driver,
String editTable, SQLiteQuery query) {
this(driver, editTable, query);
}
/**
* Execute a query and provide access to its result set through a Cursor
* interface. For a query such as: {@code SELECT name, birth, phone FROM
* myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth,
* phone) would be in the projection argument and everything from
* {@code FROM} onward would be in the params argument.
*
* @param editTable the name of the table used for this query
* @param query the {@link SQLiteQuery} object associated with this cursor object.
*/
public SQLiteCursor(SQLiteCursorDriver driver, String editTable, SQLiteQuery query) {/*
if (query == null) {
throw new IllegalArgumentException("query object cannot be null");
}
if (StrictMode.vmSqliteObjectLeaksEnabled()) {
mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
} else {
mStackTrace = null;
}
mDriver = driver;
mEditTable = editTable;
mColumnNameMap = null;
mQuery = query;
mColumns = query.getColumnNames();
mRowIdColumnIndex = DatabaseUtils.findRowIdColumnIndex(mColumns);
*/}
/**
* Get the database that this cursor is associated with.
* @return the SQLiteDatabase that this cursor is associated with.
*/
public SQLiteDatabase getDatabase() {
return mQuery.getDatabase();
}
// @Override
public boolean onMove(int oldPosition, int newPosition) {/*
// Make sure the row at newPosition is present in the window
if (mWindow == null || newPosition < mWindow.getStartPosition() ||
newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) {
fillWindow(newPosition);
}
*/return true;
}
// @Override
public int getCount() {/*
if (mCount == NO_COUNT) {
fillWindow(0);
}
return mCount;*/
return 1;
}
private void fillWindow(int requiredPos) {/*
clearOrCreateWindow(getDatabase().getPath());
try {
if (mCount == NO_COUNT) {
int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, 0);
mCount = mQuery.fillWindow(mWindow, startPos, requiredPos, true);
mCursorWindowCapacity = mWindow.getNumRows();
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "received count(*) from native_fill_window: " + mCount);
}
} else {
int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos,
mCursorWindowCapacity);
mQuery.fillWindow(mWindow, startPos, requiredPos, false);
}
} catch (RuntimeException ex) {
// Close the cursor window if the query failed and therefore will
// not produce any results. This helps to avoid accidentally leaking
// the cursor window if the client does not correctly handle exceptions
// and fails to close the cursor.
closeWindow();
throw ex;
}
*/}
// @Override
public int getColumnIndex(String columnName) {/*
// Create mColumnNameMap on demand
if (mColumnNameMap == null) {
String[] columns = mColumns;
int columnCount = columns.length;
HashMap<String, Integer> map = new HashMap<String, Integer>(columnCount, 1);
for (int i = 0; i < columnCount; i++) {
map.put(columns[i], i);
}
mColumnNameMap = map;
}
// Hack according to bug 903852
final int periodIndex = columnName.lastIndexOf('.');
if (periodIndex != -1) {
Exception e = new Exception();
Log.e(TAG, "requesting column name with table name -- " + columnName, e);
columnName = columnName.substring(periodIndex + 1);
}
Integer i = mColumnNameMap.get(columnName);
if (i != null) {
return i.intValue();
} else {
return -1;
}*/
return -1;
}
// @Override
public String[] getColumnNames() {
return mColumns;
}
// @Override
public void deactivate() {
// super.deactivate();
mDriver.cursorDeactivated();
}
// @Override
public void close() {/*
super.close();
synchronized (this) {
mQuery.close();
mDriver.cursorClosed();
}
*/}
// @Override
public boolean requery() {/*
if (isClosed()) {
return false;
}
synchronized (this) {
if (!mQuery.getDatabase().isOpen()) {
return false;
}
if (mWindow != null) {
mWindow.clear();
}
mPos = -1;
mCount = NO_COUNT;
mDriver.cursorRequeried(this);
}
try {
return super.requery();
} catch (IllegalStateException e) {
// for backwards compatibility, just return false
Log.w(TAG, "requery() failed " + e.getMessage(), e);
return false;
}
*/return false;}
// @Override
public void setWindow(CursorWindow window) {/*
super.setWindow(window);
mCount = NO_COUNT;
*/}
/**
* Changes the selection arguments. The new values take effect after a call to requery().
*/
public void setSelectionArguments(String[] selectionArgs) {
mDriver.setBindArguments(selectionArgs);
}
/**
* Release the native resources, if they haven't been released yet.
*/
// @Override
protected void finalize() {/*
try {
// if the cursor hasn't been closed yet, close it first
if (mWindow != null) {
if (mStackTrace != null) {
String sql = mQuery.getSql();
int len = sql.length();
StrictMode.onSqliteObjectLeaked(
"Finalizing a Cursor that has not been deactivated or closed. " +
"database = " + mQuery.getDatabase().getLabel() +
", table = " + mEditTable +
", query = " + sql.substring(0, (len > 1000) ? 1000 : len),
mStackTrace);
}
close();
}
} finally {
super.finalize();
}
*/}
// ---
public boolean moveToFirst() {
return false;
}
public boolean moveToNext () {
return false;
}
public boolean isAfterLast() {
return true;
}
public long getLong(int columnIndex) {
return 1;
}
public String getString(int columnIndex) {
return "BBB";
}
public int getInt(int columnIndex) {
return 1;
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.database.sqlite;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
/**
* A driver for SQLiteCursors that is used to create them and gets notified
* by the cursors it creates on significant events in their lifetimes.
*/
public interface SQLiteCursorDriver {
/**
* Executes the query returning a Cursor over the result set.
*
* @param factory The CursorFactory to use when creating the Cursors, or
* null if standard SQLiteCursors should be returned.
* @return a Cursor over the result set
*/
Cursor query(CursorFactory factory, String[] bindArgs);
/**
* Called by a SQLiteCursor when it is released.
*/
void cursorDeactivated();
/**
* Called by a SQLiteCursor when it is requeried.
*/
void cursorRequeried(Cursor cursor);
/**
* Called by a SQLiteCursor when it it closed to destroy this object as well.
*/
void cursorClosed();
/**
* Set new bind arguments. These will take effect in cursorRequeried().
* @param bindArgs the new arguments
*/
public void setBindArguments(String[] bindArgs);
}

View File

@@ -0,0 +1,287 @@
package android.database.sqlite;
import android.content.ContentValues;
import android.os.CancellationSignal;
import android.database.Cursor;
public final class SQLiteDatabase /*extends SQLiteClosable*/ {
// --- constants from android source
/**
* When a constraint violation occurs, an immediate ROLLBACK occurs,
* thus ending the current transaction, and the command aborts with a
* return code of SQLITE_CONSTRAINT. If no transaction is active
* (other than the implied transaction that is created on every command)
* then this algorithm works the same as ABORT.
*/
public static final int CONFLICT_ROLLBACK = 1;
/**
* When a constraint violation occurs,no ROLLBACK is executed
* so changes from prior commands within the same transaction
* are preserved. This is the default behavior.
*/
public static final int CONFLICT_ABORT = 2;
/**
* When a constraint violation occurs, the command aborts with a return
* code SQLITE_CONSTRAINT. But any changes to the database that
* the command made prior to encountering the constraint violation
* are preserved and are not backed out.
*/
public static final int CONFLICT_FAIL = 3;
/**
* When a constraint violation occurs, the one row that contains
* the constraint violation is not inserted or changed.
* But the command continues executing normally. Other rows before and
* after the row that contained the constraint violation continue to be
* inserted or updated normally. No error is returned.
*/
public static final int CONFLICT_IGNORE = 4;
/**
* When a UNIQUE constraint violation occurs, the pre-existing rows that
* are causing the constraint violation are removed prior to inserting
* or updating the current row. Thus the insert or update always occurs.
* The command continues executing normally. No error is returned.
* If a NOT NULL constraint violation occurs, the NULL value is replaced
* by the default value for that column. If the column has no default
* value, then the ABORT algorithm is used. If a CHECK constraint
* violation occurs then the IGNORE algorithm is used. When this conflict
* resolution strategy deletes rows in order to satisfy a constraint,
* it does not invoke delete triggers on those rows.
* This behavior might change in a future release.
*/
public static final int CONFLICT_REPLACE = 5;
/**
* Use the following when no conflict action is specified.
*/
public static final int CONFLICT_NONE = 0;
private static final String[] CONFLICT_VALUES = new String[]
{"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "};
/**
* Maximum Length Of A LIKE Or GLOB Pattern
* The pattern matching algorithm used in the default LIKE and GLOB implementation
* of SQLite can exhibit O(N^2) performance (where N is the number of characters in
* the pattern) for certain pathological cases. To avoid denial-of-service attacks
* the length of the LIKE or GLOB pattern is limited to SQLITE_MAX_LIKE_PATTERN_LENGTH bytes.
* The default value of this limit is 50000. A modern workstation can evaluate
* even a pathological LIKE or GLOB pattern of 50000 bytes relatively quickly.
* The denial of service problem only comes into play when the pattern length gets
* into millions of bytes. Nevertheless, since most useful LIKE or GLOB patterns
* are at most a few dozen bytes in length, paranoid application developers may
* want to reduce this parameter to something in the range of a few hundred
* if they know that external users are able to generate arbitrary patterns.
*/
public static final int SQLITE_MAX_LIKE_PATTERN_LENGTH = 50000;
/**
* Open flag: Flag for {@link #openDatabase} to open the database for reading and writing.
* If the disk is full, this may fail even before you actually write anything.
*
* {@more} Note that the value of this flag is 0, so it is the default.
*/
public static final int OPEN_READWRITE = 0x00000000; // update native code if changing
/**
* Open flag: Flag for {@link #openDatabase} to open the database for reading only.
* This is the only reliable way to open a database if the disk may be full.
*/
public static final int OPEN_READONLY = 0x00000001; // update native code if changing
private static final int OPEN_READ_MASK = 0x00000001; // update native code if changing
/**
* Open flag: Flag for {@link #openDatabase} to open the database without support for
* localized collators.
*
* {@more} This causes the collator <code>LOCALIZED</code> not to be created.
* You must be consistent when using this flag to use the setting the database was
* created with. If this is set, {@link #setLocale} will do nothing.
*/
public static final int NO_LOCALIZED_COLLATORS = 0x00000010; // update native code if changing
/**
* Open flag: Flag for {@link #openDatabase} to create the database file if it does not
* already exist.
*/
public static final int CREATE_IF_NECESSARY = 0x10000000; // update native code if changing
/**
* Open flag: Flag for {@link #openDatabase} to open the database file with
* write-ahead logging enabled by default. Using this flag is more efficient
* than calling {@link #enableWriteAheadLogging}.
*
* Write-ahead logging cannot be used with read-only databases so the value of
* this flag is ignored if the database is opened read-only.
*
* @see #enableWriteAheadLogging
*/
public static final int ENABLE_WRITE_AHEAD_LOGGING = 0x20000000;
/**
* Absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}.
*
* Each prepared-statement is between 1K - 6K, depending on the complexity of the
* SQL statement & schema. A large SQL cache may use a significant amount of memory.
*/
public static final int MAX_SQL_CACHE_SIZE = 100;
// ---
private SQLiteDatabase(String path, int openFlags, CursorFactory cursorFactory, DatabaseErrorHandler errorHandler) {
/* mCursorFactory = cursorFactory;
mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler();
mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags);*/
}
public static SQLiteDatabase create(CursorFactory factory) {
// This is a magic string with special meaning for SQLite.
return openDatabase(":memory:", factory, CREATE_IF_NECESSARY);
}
private void open() {/*
try {
try {
openInner();
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
openInner();
}
} catch (SQLiteException ex) {
Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex);
close();
throw ex;
}
*/}
public long insert(String table, String nullColumnHack, ContentValues values) {
/* try {
return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
} catch (SQLException e) {
Log.e(TAG, "Error inserting " + values, e);
return -1;
}*/
return -1;
}
// ---
public Cursor query(boolean distinct, String table, String[] columns,
String selection, String[] selectionArgs, String groupBy,
String having, String orderBy, String limit) {
return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
groupBy, having, orderBy, limit, null);
}
public Cursor query(boolean distinct, String table, String[] columns,
String selection, String[] selectionArgs, String groupBy,
String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
groupBy, having, orderBy, limit, cancellationSignal);
}
public Cursor query(String table, String[] columns, String selection,
String[] selectionArgs, String groupBy, String having,
String orderBy) {
return query(false, table, columns, selection, selectionArgs, groupBy,
having, orderBy, null /* limit */);
}
public Cursor query(String table, String[] columns, String selection,
String[] selectionArgs, String groupBy, String having,
String orderBy, String limit) {
return query(false, table, columns, selection, selectionArgs, groupBy,
having, orderBy, limit);
}
// ---
public Cursor queryWithFactory(CursorFactory cursorFactory,
boolean distinct, String table, String[] columns,
String selection, String[] selectionArgs, String groupBy,
String having, String orderBy, String limit) {
return queryWithFactory(cursorFactory, distinct, table, columns, selection,
selectionArgs, groupBy, having, orderBy, limit, null);
}
public Cursor queryWithFactory(CursorFactory cursorFactory,
boolean distinct, String table, String[] columns,
String selection, String[] selectionArgs, String groupBy,
String having, String orderBy, String limit, CancellationSignal cancellationSignal) {/*
acquireReference();
try {
String sql = SQLiteQueryBuilder.buildQueryString(
distinct, table, columns, selection, groupBy, having, orderBy, limit);
return rawQueryWithFactory(cursorFactory, sql, selectionArgs,
findEditTable(table), cancellationSignal);
} finally {
releaseReference();
}*/
return rawQueryWithFactory(cursorFactory, "XXX", selectionArgs, table, cancellationSignal);
}
// ---
public Cursor rawQueryWithFactory(
CursorFactory cursorFactory, String sql, String[] selectionArgs,
String editTable) {
return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null);
}
public Cursor rawQueryWithFactory(
CursorFactory cursorFactory, String sql, String[] selectionArgs,
String editTable, CancellationSignal cancellationSignal) {
// acquireReference();
try {
SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
cancellationSignal);
return driver.query(cursorFactory/* != null ? cursorFactory : mCursorFactory*/,
selectionArgs);
} finally {
// releaseReference();
}
}
// ---
public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) {
return openDatabase(path, factory, flags, null);
}
public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags, DatabaseErrorHandler errorHandler) {
SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler);
db.open();
return db;
}
// ---
public interface CursorFactory {
/**
* See {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}.
*/
public Cursor newCursor(SQLiteDatabase db,
SQLiteCursorDriver masterQuery, String editTable,
SQLiteQuery query);
}
// ---
public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
return -1;
}
// ---
public int delete(String table, String whereClause, String[] whereArgs) {
return 0;
}
// TODO: this belongs in SQLiteClosable
public void close() {}
public Cursor rawQuery(String sql, String[] selectionArgs, CancellationSignal cancellationSignal) {
return null;
}
public Cursor rawQuery(String sql, String[] selectionArgs) {
return null;
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.database.sqlite;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.os.CancellationSignal;
/**
* A cursor driver that uses the given query directly.
*
* @hide
*/
public final class SQLiteDirectCursorDriver implements SQLiteCursorDriver {
private final SQLiteDatabase mDatabase;
private final String mEditTable;
private final String mSql;
private final CancellationSignal mCancellationSignal;
private SQLiteQuery mQuery;
public SQLiteDirectCursorDriver(SQLiteDatabase db, String sql, String editTable,
CancellationSignal cancellationSignal) {
mDatabase = db;
mEditTable = editTable;
mSql = sql;
mCancellationSignal = cancellationSignal;
}
public Cursor query(CursorFactory factory, String[] selectionArgs) {
final SQLiteQuery query = new SQLiteQuery(mDatabase, mSql, mCancellationSignal);
final Cursor cursor;
try {
query.bindAllArgsAsStrings(selectionArgs);
if (factory == null) {
cursor = new SQLiteCursor(this, mEditTable, query);
} else {
cursor = factory.newCursor(mDatabase, this, mEditTable, query);
}
} catch (RuntimeException ex) {
// query.close();
throw ex;
}
mQuery = query;
return cursor;
}
public void cursorClosed() {
// Do nothing
}
public void setBindArguments(String[] bindArgs) {
mQuery.bindAllArgsAsStrings(bindArgs);
}
public void cursorDeactivated() {
// Do nothing
}
public void cursorRequeried(Cursor cursor) {
// Do nothing
}
@Override
public String toString() {
return "SQLiteDirectCursorDriver: " + mSql;
}
}

View File

@@ -0,0 +1,5 @@
package android.database.sqlite;
public class SQLiteException extends Exception {
}

View File

@@ -0,0 +1,121 @@
package android.database.sqlite;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
public abstract class SQLiteOpenHelper {
public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
this(context, name, factory, version, null);
}
public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);
/* mContext = context;
mName = name;
mFactory = factory;
mNewVersion = version;
mErrorHandler = errorHandler;*/
}
public void close () {}
public SQLiteDatabase getWritableDatabase() {
synchronized (this) {
return getDatabaseLocked(true);
}
}
private SQLiteDatabase getDatabaseLocked(boolean writable) {
return SQLiteDatabase.create(null); // return an empty database, surely the app can handle that
/*
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
// Darn! The user closed the database by calling mDatabase.close().
mDatabase = null;
} else if (!writable || !mDatabase.isReadOnly()) {
// The database is already open for business.
return mDatabase;
}
}
if (mIsInitializing) {
throw new IllegalStateException("getDatabase called recursively");
}
SQLiteDatabase db = mDatabase;
try {
mIsInitializing = true;
if (db != null) {
if (writable && db.isReadOnly()) {
db.reopenReadWrite();
}
} else if (mName == null) {
db = SQLiteDatabase.create(null);
} else {
try {
if (DEBUG_STRICT_READONLY && !writable) {
final String path = mContext.getDatabasePath(mName).getPath();
db = SQLiteDatabase.openDatabase(path, mFactory,
SQLiteDatabase.OPEN_READONLY, mErrorHandler);
} else {
db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?
Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,
mFactory, mErrorHandler);
}
} catch (SQLiteException ex) {
if (writable) {
throw ex;
}
Log.e(TAG, "Couldn't open " + mName
+ " for writing (will try read-only):", ex);
final String path = mContext.getDatabasePath(mName).getPath();
db = SQLiteDatabase.openDatabase(path, mFactory,
SQLiteDatabase.OPEN_READONLY, mErrorHandler);
}
}
onConfigure(db);
final int version = db.getVersion();
if (version != mNewVersion) {
if (db.isReadOnly()) {
throw new SQLiteException("Can't upgrade read-only database from version " +
db.getVersion() + " to " + mNewVersion + ": " + mName);
}
db.beginTransaction();
try {
if (version == 0) {
onCreate(db);
} else {
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
onOpen(db);
if (db.isReadOnly()) {
Log.w(TAG, "Opened " + mName + " in read-only mode");
}
mDatabase = db;
return db;
} finally {
mIsInitializing = false;
if (db != null && db != mDatabase) {
db.close();
}
}
*/}
}

View File

@@ -0,0 +1,220 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.database.sqlite;
//import android.database.DatabaseUtils;
import android.os.CancellationSignal;
import java.util.Arrays;
class SQLiteSession {}
/**
* A base class for compiled SQLite programs.
* <p>
* This class is not thread-safe.
* </p>
*/
public abstract class SQLiteProgram /*extends SQLiteClosable*/ {
private static final String[] EMPTY_STRING_ARRAY = new String[0];
private final SQLiteDatabase mDatabase;
private final String mSql;
private final boolean mReadOnly = false;
private final String[] mColumnNames = {"YYY"};
private final int mNumParameters = -1;
private final Object[] mBindArgs = {};
SQLiteProgram(SQLiteDatabase db, String sql, Object[] bindArgs,
CancellationSignal cancellationSignalForPrepare) {
mDatabase = db;
mSql = sql.trim();
/*
int n = DatabaseUtils.getSqlStatementType(mSql);
switch (n) {
case DatabaseUtils.STATEMENT_BEGIN:
case DatabaseUtils.STATEMENT_COMMIT:
case DatabaseUtils.STATEMENT_ABORT:
mReadOnly = false;
mColumnNames = EMPTY_STRING_ARRAY;
mNumParameters = 0;
break;
default:
boolean assumeReadOnly = (n == DatabaseUtils.STATEMENT_SELECT);
SQLiteStatementInfo info = new SQLiteStatementInfo();
db.getThreadSession().prepare(mSql,
db.getThreadDefaultConnectionFlags(assumeReadOnly),
cancellationSignalForPrepare, info);
mReadOnly = info.readOnly;
mColumnNames = info.columnNames;
mNumParameters = info.numParameters;
break;
}
if (bindArgs != null && bindArgs.length > mNumParameters) {
throw new IllegalArgumentException("Too many bind arguments. "
+ bindArgs.length + " arguments were provided but the statement needs "
+ mNumParameters + " arguments.");
}
if (mNumParameters != 0) {
mBindArgs = new Object[mNumParameters];
if (bindArgs != null) {
System.arraycopy(bindArgs, 0, mBindArgs, 0, bindArgs.length);
}
} else {
mBindArgs = null;
}
*/}
final SQLiteDatabase getDatabase() {
return mDatabase;
}
final String getSql() {
return mSql;
}
final Object[] getBindArgs() {
return mBindArgs;
}
final String[] getColumnNames() {
return mColumnNames;
}
/** @hide */
protected final SQLiteSession getSession() {
return null;/*mDatabase.getThreadSession();*/
}
/** @hide */
protected final int getConnectionFlags() {
return -1;/*mDatabase.getThreadDefaultConnectionFlags(mReadOnly);*/
}
/** @hide */
protected final void onCorruption() {
// mDatabase.onCorruption();
}
/**
* Unimplemented.
* @deprecated This method is deprecated and must not be used.
*/
@Deprecated
public final int getUniqueId() {
return -1;
}
/**
* Bind a NULL value to this statement. The value remains bound until
* {@link #clearBindings} is called.
*
* @param index The 1-based index to the parameter to bind null to
*/
public void bindNull(int index) {
bind(index, null);
}
/**
* Bind a long value to this statement. The value remains bound until
* {@link #clearBindings} is called.
*addToBindArgs
* @param index The 1-based index to the parameter to bind
* @param value The value to bind
*/
public void bindLong(int index, long value) {
bind(index, value);
}
/**
* Bind a double value to this statement. The value remains bound until
* {@link #clearBindings} is called.
*
* @param index The 1-based index to the parameter to bind
* @param value The value to bind
*/
public void bindDouble(int index, double value) {
bind(index, value);
}
/**
* Bind a String value to this statement. The value remains bound until
* {@link #clearBindings} is called.
*
* @param index The 1-based index to the parameter to bind
* @param value The value to bind, must not be null
*/
public void bindString(int index, String value) {
if (value == null) {
throw new IllegalArgumentException("the bind value at index " + index + " is null");
}
bind(index, value);
}
/**
* Bind a byte array value to this statement. The value remains bound until
* {@link #clearBindings} is called.
*
* @param index The 1-based index to the parameter to bind
* @param value The value to bind, must not be null
*/
public void bindBlob(int index, byte[] value) {
if (value == null) {
throw new IllegalArgumentException("the bind value at index " + index + " is null");
}
bind(index, value);
}
/**
* Clears all existing bindings. Unset bindings are treated as NULL.
*/
public void clearBindings() {
if (mBindArgs != null) {
Arrays.fill(mBindArgs, null);
}
}
/**
* Given an array of String bindArgs, this method binds all of them in one single call.
*
* @param bindArgs the String array of bind args, none of which must be null.
*/
public void bindAllArgsAsStrings(String[] bindArgs) {
if (bindArgs != null) {
for (int i = bindArgs.length; i != 0; i--) {
bindString(i, bindArgs[i - 1]);
}
}
}
// @Override
protected void onAllReferencesReleased() {
clearBindings();
}
private void bind(int index, Object value) {
if (index < 1 || index > mNumParameters) {
throw new IllegalArgumentException("Cannot bind argument at index "
+ index + " because the index is out of range. "
+ "The statement has " + mNumParameters + " parameters.");
}
mBindArgs[index - 1] = value;
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.database.sqlite;
//import android.database.CursorWindow;
import android.os.CancellationSignal;
//import android.os.OperationCanceledException;
import android.util.Log;
class CursorWindow {}
/**
* Represents a query that reads the resulting rows into a {@link SQLiteQuery}.
* This class is used by {@link SQLiteCursor} and isn't useful itself.
* <p>
* This class is not thread-safe.
* </p>
*/
public final class SQLiteQuery extends SQLiteProgram {
private static final String TAG = "SQLiteQuery";
private final CancellationSignal mCancellationSignal;
SQLiteQuery(SQLiteDatabase db, String query, CancellationSignal cancellationSignal) {
super(db, query, null, cancellationSignal);
mCancellationSignal = cancellationSignal;
}
/**
* Reads rows into a buffer.
*
* @param window The window to fill into
* @param startPos The start position for filling the window.
* @param requiredPos The position of a row that MUST be in the window.
* If it won't fit, then the query should discard part of what it filled.
* @param countAllRows True to count all rows that the query would
* return regardless of whether they fit in the window.
* @return Number of rows that were enumerated. Might not be all rows
* unless countAllRows is true.
*
* @throws SQLiteException if an error occurs.
* @throws OperationCanceledException if the operation was canceled.
*/
int fillWindow(CursorWindow window, int startPos, int requiredPos, boolean countAllRows) {/*
acquireReference();
try {
window.acquireReference();
try {
int numRows = getSession().executeForCursorWindow(getSql(), getBindArgs(),
window, startPos, requiredPos, countAllRows, getConnectionFlags(),
mCancellationSignal);
return numRows;
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
} catch (SQLiteException ex) {
Log.e(TAG, "exception: " + ex.getMessage() + "; query: " + getSql());
throw ex;
} finally {
window.releaseReference();
}
} finally {
releaseReference();
}
*/return -1;}
@Override
public String toString() {
return "SQLiteQuery: "/* + getSql()*/;
}
}