add complete java side of sqlite implementation

Mostly taken from https://www.sqlite.org/android which is forked from
AOSPs implementation
This commit is contained in:
Julian Winkler
2023-08-24 12:43:13 +02:00
parent b861c86f0d
commit 2e0c18d755
58 changed files with 12959 additions and 685 deletions

View File

@@ -0,0 +1,484 @@
/*
* 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.Build;
import android.os.Bundle;
import android.util.Log;
import dalvik.system.CloseGuard;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* This is an abstract cursor class that handles a lot of the common code
* that all cursors need to deal with and is provided for convenience reasons.
*/
public abstract class AbstractCursor implements CrossProcessCursor {
private static final String TAG = "Cursor";
/**
* @removed This field should not be used.
*/
protected HashMap<Long, Map<String, Object>> mUpdatedRows;
/**
* @removed This field should not be used.
*/
protected int mRowIdColumnIndex;
/**
* @removed This field should not be used.
*/
protected Long mCurrentRowID;
/**
* @deprecated Use {@link #getPosition()} instead.
*/
@Deprecated
protected int mPos;
/**
* @deprecated Use {@link #isClosed()} instead.
*/
@Deprecated
protected boolean mClosed;
/**
* @deprecated Do not use.
*/
@Deprecated
protected ContentResolver mContentResolver;
private Uri mNotifyUri;
private List<Uri> mNotifyUris;
private final Object mSelfObserverLock = new Object();
private ContentObserver mSelfObserver;
private boolean mSelfObserverRegistered;
private final DataSetObservable mDataSetObservable = new DataSetObservable();
private final ContentObservable mContentObservable = new ContentObservable();
private Bundle mExtras = Bundle.EMPTY;
/** CloseGuard to detect leaked cursor **/
private final CloseGuard mCloseGuard = CloseGuard.get();
/* -------------------------------------------------------- */
/* These need to be implemented by subclasses */
@Override
abstract public int getCount();
@Override
abstract public String[] getColumnNames();
@Override
abstract public String getString(int column);
@Override
abstract public short getShort(int column);
@Override
abstract public int getInt(int column);
@Override
abstract public long getLong(int column);
@Override
abstract public float getFloat(int column);
@Override
abstract public double getDouble(int column);
@Override
abstract public boolean isNull(int column);
@Override
public int getType(int column) {
// Reflects the assumption that all commonly used field types (meaning everything
// but blobs) are convertible to strings so it should be safe to call
// getString to retrieve them.
return FIELD_TYPE_STRING;
}
// TODO implement getBlob in all cursor types
@Override
public byte[] getBlob(int column) {
throw new UnsupportedOperationException("getBlob is not supported");
}
/* -------------------------------------------------------- */
/* Methods that may optionally be implemented by subclasses */
/**
* If the cursor is backed by a {@link CursorWindow}, returns a pre-filled
* window with the contents of the cursor, otherwise null.
*
* @return The pre-filled window that backs this cursor, or null if none.
*/
@Override
public CursorWindow getWindow() {
return null;
}
@Override
public int getColumnCount() {
return getColumnNames().length;
}
@Override
public void deactivate() {
onDeactivateOrClose();
}
/** @hide */
protected void onDeactivateOrClose() {
if (mSelfObserver != null) {
mContentResolver.unregisterContentObserver(mSelfObserver);
mSelfObserverRegistered = false;
}
mDataSetObservable.notifyInvalidated();
}
@Override
public boolean requery() {
if (mSelfObserver != null && mSelfObserverRegistered == false) {
final int size = mNotifyUris.size();
for (int i = 0; i < size; ++i) {
final Uri notifyUri = mNotifyUris.get(i);
mContentResolver.registerContentObserver(notifyUri, true, mSelfObserver);
}
mSelfObserverRegistered = true;
}
mDataSetObservable.notifyChanged();
return true;
}
@Override
public boolean isClosed() {
return mClosed;
}
@Override
public void close() {
mClosed = true;
mContentObservable.unregisterAll();
onDeactivateOrClose();
mCloseGuard.close();
}
/**
* This function is called every time the cursor is successfully scrolled
* to a new position, giving the subclass a chance to update any state it
* may have. If it returns false the move function will also do so and the
* cursor will scroll to the beforeFirst position.
*
* @param oldPosition the position that we're moving from
* @param newPosition the position that we're moving to
* @return true if the move is successful, false otherwise
*/
@Override
public boolean onMove(int oldPosition, int newPosition) {
return true;
}
@Override
public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
// Default implementation, uses getString
String result = getString(columnIndex);
if (result != null) {
char[] data = buffer.data;
if (data == null || data.length < result.length()) {
buffer.data = result.toCharArray();
} else {
result.getChars(0, result.length(), data, 0);
}
buffer.sizeCopied = result.length();
} else {
buffer.sizeCopied = 0;
}
}
/* -------------------------------------------------------- */
/* Implementation */
public AbstractCursor() {
mPos = -1;
mCloseGuard.open("AbstractCursor.close");
}
@Override
public final int getPosition() {
return mPos;
}
@Override
public final boolean moveToPosition(int position) {
// Make sure position isn't past the end of the cursor
final int count = getCount();
if (position >= count) {
mPos = count;
return false;
}
// Make sure position isn't before the beginning of the cursor
if (position < 0) {
mPos = -1;
return false;
}
// Check for no-op moves, and skip the rest of the work for them
if (position == mPos) {
return true;
}
boolean result = onMove(mPos, position);
if (result == false) {
mPos = -1;
} else {
mPos = position;
}
return result;
}
@Override
public void fillWindow(int position, CursorWindow window) {
DatabaseUtils.cursorFillWindow(this, position, window);
}
@Override
public final boolean move(int offset) {
return moveToPosition(mPos + offset);
}
@Override
public final boolean moveToFirst() {
return moveToPosition(0);
}
@Override
public final boolean moveToLast() {
return moveToPosition(getCount() - 1);
}
@Override
public final boolean moveToNext() {
return moveToPosition(mPos + 1);
}
@Override
public final boolean moveToPrevious() {
return moveToPosition(mPos - 1);
}
@Override
public final boolean isFirst() {
return mPos == 0 && getCount() != 0;
}
@Override
public final boolean isLast() {
int cnt = getCount();
return mPos == (cnt - 1) && cnt != 0;
}
@Override
public final boolean isBeforeFirst() {
if (getCount() == 0) {
return true;
}
return mPos == -1;
}
@Override
public final boolean isAfterLast() {
if (getCount() == 0) {
return true;
}
return mPos == getCount();
}
@Override
public int getColumnIndex(String columnName) {
// 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);
}
String columnNames[] = getColumnNames();
int length = columnNames.length;
for (int i = 0; i < length; i++) {
if (columnNames[i].equalsIgnoreCase(columnName)) {
return i;
}
}
if (false) {
if (getCount() > 0) {
Log.w("AbstractCursor", "Unknown column " + columnName);
}
}
return -1;
}
@Override
public int getColumnIndexOrThrow(String columnName) {
final int index = getColumnIndex(columnName);
if (index < 0) {
String availableColumns = "";
try {
availableColumns = Arrays.toString(getColumnNames());
} catch (Exception e) {
Log.d(TAG, "Cannot collect column names for debug purposes", e);
}
throw new IllegalArgumentException("column '" + columnName
+ "' does not exist. Available columns: " + availableColumns);
}
return index;
}
@Override
public String getColumnName(int columnIndex) {
return getColumnNames()[columnIndex];
}
@Override
public void registerContentObserver(ContentObserver observer) {
mContentObservable.registerObserver(observer);
}
@Override
public void unregisterContentObserver(ContentObserver observer) {
// cursor will unregister all observers when it close
if (!mClosed) {
mContentObservable.unregisterObserver(observer);
}
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
/**
* Subclasses must call this method when they finish committing updates to notify all
* observers.
*
* @param selfChange
*/
protected void onChange(boolean selfChange) {
synchronized (mSelfObserverLock) {
mContentObservable.dispatchChange(selfChange, null);
if (mNotifyUris != null && selfChange) {
final int size = mNotifyUris.size();
for (int i = 0; i < size; ++i) {
final Uri notifyUri = mNotifyUris.get(i);
mContentResolver.notifyChange(notifyUri, mSelfObserver);
}
}
}
}
/**
* Specifies a content URI to watch for changes.
*
* @param cr The content resolver from the caller's context.
* @param notifyUri The URI to watch for changes. This can be a
* specific row URI, or a base URI for a whole class of content.
*/
@Override
public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
setNotificationUris(cr, Arrays.asList(notifyUri));
}
// @Override
public void setNotificationUris(ContentResolver cr, List<Uri> notifyUris) {
Objects.requireNonNull(cr);
Objects.requireNonNull(notifyUris);
setNotificationUris(cr, notifyUris, cr.getUserId(), true);
}
/**
* Set the notification uri but with an observer for a particular user's view. Also allows
* disabling the use of a self observer, which is sensible if either
* a) the cursor's owner calls {@link #onChange(boolean)} whenever the content changes, or
* b) the cursor is known not to have any content observers.
* @hide
*/
public void setNotificationUris(ContentResolver cr, List<Uri> notifyUris, int userHandle,
boolean registerSelfObserver) {
synchronized (mSelfObserverLock) {
mNotifyUris = notifyUris;
mNotifyUri = mNotifyUris.get(0);
mContentResolver = cr;
if (mSelfObserver != null) {
mContentResolver.unregisterContentObserver(mSelfObserver);
mSelfObserverRegistered = false;
}
if (registerSelfObserver) {
mSelfObserver = new SelfContentObserver(this);
final int size = mNotifyUris.size();
for (int i = 0; i < size; ++i) {
final Uri notifyUri = mNotifyUris.get(i);
mContentResolver.registerContentObserver(
notifyUri, true, mSelfObserver, userHandle);
}
mSelfObserverRegistered = true;
}
}
}
@Override
public Uri getNotificationUri() {
synchronized (mSelfObserverLock) {
return mNotifyUri;
}
}
// @Override
public List<Uri> getNotificationUris() {
synchronized (mSelfObserverLock) {
return mNotifyUris;
}
}
@Override
public boolean getWantsAllOnMoveCalls() {
return false;
}
// @Override
public void setExtras(Bundle extras) {
mExtras = (extras == null) ? Bundle.EMPTY : extras;
}
@Override
public Bundle getExtras() {
return mExtras;
}
@Override
public Bundle respond(Bundle extras) {
return Bundle.EMPTY;
}
/**
* @deprecated Always returns false since Cursors do not support updating rows
*/
@Deprecated
protected boolean isFieldUpdated(int columnIndex) {
return false;
}
/**
* @deprecated Always returns null since Cursors do not support updating rows
*/
@Deprecated
protected Object getUpdatedField(int columnIndex) {
return null;
}
/**
* This function throws CursorIndexOutOfBoundsException if
* the cursor position is out of bounds. Subclass implementations of
* the get functions should call this before attempting
* to retrieve data.
*
* @throws CursorIndexOutOfBoundsException
*/
protected void checkPosition() {
if (-1 == mPos || getCount() == mPos) {
// throw new CursorIndexOutOfBoundsException(mPos, getCount());
throw new IndexOutOfBoundsException("index = " + mPos + " count = " + getCount());
}
}
@Override
protected void finalize() {
if (mSelfObserver != null && mSelfObserverRegistered == true) {
mContentResolver.unregisterContentObserver(mSelfObserver);
}
try {
if (mCloseGuard != null) mCloseGuard.warnIfOpen();
if (!mClosed) close();
} catch(Exception e) { }
}
/**
* Cursors use this class to track changes others make to their URI.
*/
protected static class SelfContentObserver extends ContentObserver {
WeakReference<AbstractCursor> mCursor;
public SelfContentObserver(AbstractCursor cursor) {
super(null);
mCursor = new WeakReference<AbstractCursor>(cursor);
}
@Override
public boolean deliverSelfNotifications() {
return false;
}
@Override
public void onChange(boolean selfChange) {
AbstractCursor cursor = mCursor.get();
if (cursor != null) {
cursor.onChange(false);
}
}
}
}

View File

@@ -0,0 +1,209 @@
/*
* 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;
/**
* A base class for Cursors that store their data in {@link CursorWindow}s.
* <p>
* The cursor owns the cursor window it uses. When the cursor is closed,
* its window is also closed. Likewise, when the window used by the cursor is
* changed, its old window is closed. This policy of strict ownership ensures
* that cursor windows are not leaked.
* </p><p>
* Subclasses are responsible for filling the cursor window with data during
* {@link #onMove(int, int)}, allocating a new cursor window if necessary.
* During {@link #requery()}, the existing cursor window should be cleared and
* filled with new data.
* </p><p>
* If the contents of the cursor change or become invalid, the old window must be closed
* (because it is owned by the cursor) and set to null.
* </p>
*/
public abstract class AbstractWindowedCursor extends AbstractCursor {
/**
* The cursor window owned by this cursor.
*/
protected CursorWindow mWindow;
@Override
public byte[] getBlob(int columnIndex) {
checkPosition();
return mWindow.getBlob(mPos, columnIndex);
}
@Override
public String getString(int columnIndex) {
checkPosition();
return mWindow.getString(mPos, columnIndex);
}
@Override
public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
checkPosition();
mWindow.copyStringToBuffer(mPos, columnIndex, buffer);
}
@Override
public short getShort(int columnIndex) {
checkPosition();
return mWindow.getShort(mPos, columnIndex);
}
@Override
public int getInt(int columnIndex) {
checkPosition();
return mWindow.getInt(mPos, columnIndex);
}
@Override
public long getLong(int columnIndex) {
checkPosition();
return mWindow.getLong(mPos, columnIndex);
}
@Override
public float getFloat(int columnIndex) {
checkPosition();
return mWindow.getFloat(mPos, columnIndex);
}
@Override
public double getDouble(int columnIndex) {
checkPosition();
return mWindow.getDouble(mPos, columnIndex);
}
@Override
public boolean isNull(int columnIndex) {
checkPosition();
return mWindow.getType(mPos, columnIndex) == Cursor.FIELD_TYPE_NULL;
}
/**
* @deprecated Use {@link #getType}
*/
@Deprecated
public boolean isBlob(int columnIndex) {
return getType(columnIndex) == Cursor.FIELD_TYPE_BLOB;
}
/**
* @deprecated Use {@link #getType}
*/
@Deprecated
public boolean isString(int columnIndex) {
return getType(columnIndex) == Cursor.FIELD_TYPE_STRING;
}
/**
* @deprecated Use {@link #getType}
*/
@Deprecated
public boolean isLong(int columnIndex) {
return getType(columnIndex) == Cursor.FIELD_TYPE_INTEGER;
}
/**
* @deprecated Use {@link #getType}
*/
@Deprecated
public boolean isFloat(int columnIndex) {
return getType(columnIndex) == Cursor.FIELD_TYPE_FLOAT;
}
@Override
public int getType(int columnIndex) {
checkPosition();
return mWindow.getType(mPos, columnIndex);
}
@Override
protected void checkPosition() {
super.checkPosition();
if (mWindow == null) {
throw new /*StaleDataException*/RuntimeException("Attempting to access a closed CursorWindow." +
"Most probable cause: cursor is deactivated prior to calling this method.");
}
}
@Override
public CursorWindow getWindow() {
return mWindow;
}
/**
* Sets a new cursor window for the cursor to use.
* <p>
* The cursor takes ownership of the provided cursor window; the cursor window
* will be closed when the cursor is closed or when the cursor adopts a new
* cursor window.
* </p><p>
* If the cursor previously had a cursor window, then it is closed when the
* new cursor window is assigned.
* </p>
*
* @param window The new cursor window, typically a remote cursor window.
*/
public void setWindow(CursorWindow window) {
if (window != mWindow) {
closeWindow();
mWindow = window;
}
}
/**
* Returns true if the cursor has an associated cursor window.
*
* @return True if the cursor has an associated cursor window.
*/
public boolean hasWindow() {
return mWindow != null;
}
/**
* Closes the cursor window and sets {@link #mWindow} to null.
* @hide
*/
protected void closeWindow() {
if (mWindow != null) {
mWindow.close();
mWindow = null;
}
}
/**
* If there is a window, clear it.
* Otherwise, creates a new window.
*
* @param name The window name.
* @hide
*/
protected void clearOrCreateWindow(String name) {
if (mWindow == null) {
mWindow = new CursorWindow(name);
} else {
mWindow.clear();
}
}
/** @hide */
@Override
protected void onDeactivateOrClose() {
super.onDeactivateOrClose();
closeWindow();
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2008 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;
/**
* This is used for {@link Cursor#copyStringToBuffer}
*/
public final class CharArrayBuffer {
public CharArrayBuffer(int size) {
data = new char[size];
}
public CharArrayBuffer(char[] buf) {
data = buf;
}
public char[] data; // In and out parameter
public int sizeCopied; // Out parameter
}

View File

@@ -0,0 +1,91 @@
/*
* 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;
import android.net.Uri;
/**
* A specialization of {@link Observable} for {@link ContentObserver}
* that provides methods for sending notifications to a list of
* {@link ContentObserver} objects.
*/
public class ContentObservable extends Observable<ContentObserver> {
// Even though the generic method defined in Observable would be perfectly
// fine on its own, we can't delete this overridden method because it would
// potentially break binary compatibility with existing applications.
@Override
public void registerObserver(ContentObserver observer) {
super.registerObserver(observer);
}
/**
* Invokes {@link ContentObserver#dispatchChange(boolean)} on each observer.
* <p>
* If <code>selfChange</code> is true, only delivers the notification
* to the observer if it has indicated that it wants to receive self-change
* notifications by implementing {@link ContentObserver#deliverSelfNotifications}
* to return true.
* </p>
*
* @param selfChange True if this is a self-change notification.
*
* @deprecated Use {@link #dispatchChange(boolean, Uri)} instead.
*/
@Deprecated
public void dispatchChange(boolean selfChange) {
dispatchChange(selfChange, null);
}
/**
* Invokes {@link ContentObserver#dispatchChange(boolean, Uri)} on each observer.
* Includes the changed content Uri when available.
* <p>
* If <code>selfChange</code> is true, only delivers the notification
* to the observer if it has indicated that it wants to receive self-change
* notifications by implementing {@link ContentObserver#deliverSelfNotifications}
* to return true.
* </p>
*
* @param selfChange True if this is a self-change notification.
* @param uri The Uri of the changed content, or null if unknown.
*/
public void dispatchChange(boolean selfChange, Uri uri) {
synchronized(mObservers) {
for (ContentObserver observer : mObservers) {
if (!selfChange || observer.deliverSelfNotifications()) {
observer.dispatchChange(selfChange, uri);
}
}
}
}
/**
* Invokes {@link ContentObserver#onChange} on each observer.
*
* @param selfChange True if this is a self-change notification.
*
* @deprecated Use {@link #dispatchChange} instead.
*/
@Deprecated
public void notifyChange(boolean selfChange) {
synchronized(mObservers) {
for (ContentObserver observer : mObservers) {
observer.onChange(selfChange, null);
}
}
}
}

View File

@@ -1,11 +1,251 @@
/*
* 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;
import android.net.Uri;
import android.os.Handler;
import android.os.UserHandle;
import java.util.Arrays;
import java.util.Collection;
/**
* Receives call backs for changes to content.
* Must be implemented by objects which are added to a {@link ContentObservable}.
*/
public abstract class ContentObserver {
/**
* Starting in {@link android.os.Build.VERSION_CODES#R}, there is a new
* public API overload {@link #onChange(boolean, Uri, int)} that delivers a
* {@code int flags} argument.
* <p>
* Some apps may be relying on a previous hidden API that delivered a
* {@code int userId} argument, and this change is used to control delivery
* of the new {@code int flags} argument in its place.
*/
private static final long ADD_CONTENT_OBSERVER_FLAGS = 150939131L;
private final Object mLock = new Object();
Handler mHandler;
public class ContentObserver {
public ContentObserver() {
}
/**
* Creates a content observer.
*
* @param handler The handler to run {@link #onChange} on, or null if none.
*/
public ContentObserver(Handler handler) {
mHandler = handler;
}
}
/**
* Returns true if this observer is interested receiving self-change notifications.
*
* Subclasses should override this method to indicate whether the observer
* is interested in receiving notifications for changes that it made to the
* content itself.
*
* @return True if self-change notifications should be delivered to the observer.
*/
public boolean deliverSelfNotifications() {
return false;
}
/**
* This method is called when a content change occurs.
* <p>
* Subclasses should override this method to handle content changes.
* </p>
*
* @param selfChange True if this is a self-change notification.
*/
public void onChange(boolean selfChange) {
// Do nothing. Subclass should override.
}
/**
* This method is called when a content change occurs.
* Includes the changed content Uri when available.
* <p>
* Subclasses should override this method to handle content changes. To
* ensure correct operation on older versions of the framework that did not
* provide richer arguments, applications should implement all overloads.
* <p>
* Example implementation:
* <pre><code>
* // Implement the onChange(boolean) method to delegate the change notification to
* // the onChange(boolean, Uri) method to ensure correct operation on older versions
* // of the framework that did not have the onChange(boolean, Uri) method.
* {@literal @Override}
* public void onChange(boolean selfChange) {
* onChange(selfChange, null);
* }
*
* // Implement the onChange(boolean, Uri) method to take advantage of the new Uri argument.
* {@literal @Override}
* public void onChange(boolean selfChange, Uri uri) {
* // Handle change.
* }
* </code></pre>
* </p>
*
* @param selfChange True if this is a self-change notification.
* @param uri The Uri of the changed content.
*/
public void onChange(boolean selfChange, Uri uri) {
onChange(selfChange);
}
/**
* This method is called when a content change occurs. Includes the changed
* content Uri when available.
* <p>
* Subclasses should override this method to handle content changes. To
* ensure correct operation on older versions of the framework that did not
* provide richer arguments, applications should implement all overloads.
*
* @param selfChange True if this is a self-change notification.
* @param uri The Uri of the changed content.
* @param flags Flags indicating details about this change.
*/
public void onChange(boolean selfChange, Uri uri, int flags) {
onChange(selfChange, uri);
}
/**
* This method is called when a content change occurs. Includes the changed
* content Uris when available.
* <p>
* Subclasses should override this method to handle content changes. To
* ensure correct operation on older versions of the framework that did not
* provide richer arguments, applications should implement all overloads.
*
* @param selfChange True if this is a self-change notification.
* @param uris The Uris of the changed content.
* @param flags Flags indicating details about this change.
*/
public void onChange(boolean selfChange, Collection<Uri> uris,
int flags) {
for (Uri uri : uris) {
onChange(selfChange, uri, flags);
}
}
/**
* This method is called when a content change occurs. Includes the changed
* content Uris when available.
* <p>
* Subclasses should override this method to handle content changes. To
* ensure correct operation on older versions of the framework that did not
* provide richer arguments, applications should implement all overloads.
*
* @param selfChange True if this is a self-change notification.
* @param uris The Uris of the changed content.
* @param flags Flags indicating details about this change.
* @param user The corresponding {@link UserHandle} for the current notification.
*
* @hide
*/
public void onChange(boolean selfChange, Collection<Uri> uris,
int flags, UserHandle user) {
onChange(selfChange, uris, user.getIdentifier());
}
/** @hide */
public void onChange(boolean selfChange, Collection<Uri> uris,
int flags, int userId) {
// There are dozens of people relying on the hidden API inside the
// system UID, so hard-code the old behavior for all of them; for
// everyone else we gate based on a specific change
// if (!CompatChanges.isChangeEnabled(ADD_CONTENT_OBSERVER_FLAGS)
// || android.os.Process.myUid() == android.os.Process.SYSTEM_UID) {
// // Deliver userId through argument to preserve hidden API behavior
// onChange(selfChange, uris, flags, UserHandle.of(userId));
// } else {
onChange(selfChange, uris, flags);
// }
}
/**
* Dispatches a change notification to the observer.
* <p>
* If a {@link Handler} was supplied to the {@link ContentObserver}
* constructor, then a call to the {@link #onChange} method is posted to the
* handler's message queue. Otherwise, the {@link #onChange} method is
* invoked immediately on this thread.
*
* @deprecated Callers should migrate towards using a richer overload that
* provides more details about the change, such as
* {@link #dispatchChange(boolean, Collection, int)}.
*/
@Deprecated
public final void dispatchChange(boolean selfChange) {
dispatchChange(selfChange, null);
}
/**
* Dispatches a change notification to the observer. Includes the changed
* content Uri when available.
* <p>
* If a {@link Handler} was supplied to the {@link ContentObserver}
* constructor, then a call to the {@link #onChange} method is posted to the
* handler's message queue. Otherwise, the {@link #onChange} method is
* invoked immediately on this thread.
*
* @param selfChange True if this is a self-change notification.
* @param uri The Uri of the changed content.
*/
public final void dispatchChange(boolean selfChange, Uri uri) {
dispatchChange(selfChange, uri, 0);
}
/**
* Dispatches a change notification to the observer. Includes the changed
* content Uri when available.
* <p>
* If a {@link Handler} was supplied to the {@link ContentObserver}
* constructor, then a call to the {@link #onChange} method is posted to the
* handler's message queue. Otherwise, the {@link #onChange} method is
* invoked immediately on this thread.
*
* @param selfChange True if this is a self-change notification.
* @param uri The Uri of the changed content.
* @param flags Flags indicating details about this change.
*/
public final void dispatchChange(boolean selfChange, Uri uri,
int flags) {
dispatchChange(selfChange, Arrays.asList(uri), flags);
}
/**
* Dispatches a change notification to the observer. Includes the changed
* content Uris when available.
* <p>
* If a {@link Handler} was supplied to the {@link ContentObserver}
* constructor, then a call to the {@link #onChange} method is posted to the
* handler's message queue. Otherwise, the {@link #onChange} method is
* invoked immediately on this thread.
*
* @param selfChange True if this is a self-change notification.
* @param uris The Uri of the changed content.
* @param flags Flags indicating details about this change.
*/
public final void dispatchChange(boolean selfChange, Collection<Uri> uris,
int flags) {
dispatchChange(selfChange, uris, flags, UserHandle.getCallingUserId());
}
/** @hide */
public final void dispatchChange(final boolean selfChange, final Collection<Uri> uris,
final int flags, final int userId) {
if (mHandler == null) {
onChange(selfChange, uris, flags, userId);
} else {
mHandler.post(new Runnable(){
@Override
public void run() {
onChange(selfChange, uris, flags, userId);
}
});
}
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2008 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;
/**
* A cross process cursor is an extension of a {@link Cursor} that also supports
* usage from remote processes.
* <p>
* The contents of a cross process cursor are marshalled to the remote process by
* filling {@link CursorWindow} objects using {@link #fillWindow}. As an optimization,
* the cursor can provide a pre-filled window to use via {@link #getWindow} thereby
* obviating the need to copy the data to yet another cursor window.
*/
public interface CrossProcessCursor extends Cursor {
/**
* Returns a pre-filled window that contains the data within this cursor.
* <p>
* In particular, the window contains the row indicated by {@link Cursor#getPosition}.
* The window's contents are automatically scrolled whenever the current
* row moved outside the range covered by the window.
* </p>
*
* @return The pre-filled window, or null if none.
*/
CursorWindow getWindow();
/**
* Copies cursor data into the window.
* <p>
* Clears the window and fills it with data beginning at the requested
* row position until all of the data in the cursor is exhausted
* or the window runs out of space.
* </p><p>
* The filled window uses the same row indices as the original cursor.
* For example, if you fill a window starting from row 5 from the cursor,
* you can query the contents of row 5 from the window just by asking it
* for row 5 because there is a direct correspondence between the row indices
* used by the cursor and the window.
* </p><p>
* The current position of the cursor, as returned by {@link #getPosition},
* is not changed by this method.
* </p>
*
* @param position The zero-based index of the first row to copy into the window.
* @param window The window to fill.
*/
void fillWindow(int position, CursorWindow window);
/**
* This function is called every time the cursor is successfully scrolled
* to a new position, giving the subclass a chance to update any state it
* may have. If it returns false the move function will also do so and the
* cursor will scroll to the beforeFirst position.
* <p>
* This function should be called by methods such as {@link #moveToPosition(int)},
* so it will typically not be called from outside of the cursor class itself.
* </p>
*
* @param oldPosition The position that we're moving from.
* @param newPosition The position that we're moving to.
* @return True if the move is successful, false otherwise.
*/
boolean onMove(int oldPosition, int newPosition);
}

View File

@@ -17,13 +17,10 @@
package android.database;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import java.io.Closeable;
class CharArrayBuffer {}
/**
* This interface provides random read-write access to the result set returned
* by a database query.
@@ -80,7 +77,7 @@ public interface Cursor extends Closeable {
*
* @return the current cursor position.
*/
// int getPosition();
int getPosition();
/**
* Move the cursor by a relative amount, forward or backward, from the
@@ -97,7 +94,7 @@ public interface Cursor extends Closeable {
* @param offset the offset to be applied from the current position.
* @return whether the requested move fully succeeded.
*/
// boolean move(int offset);
boolean move(int offset);
/**
* Move the cursor to an absolute position. The valid
@@ -109,7 +106,7 @@ public interface Cursor extends Closeable {
* @param position the zero-based position to move to.
* @return whether the requested move fully succeeded.
*/
// boolean moveToPosition(int position);
boolean moveToPosition(int position);
/**
* Move the cursor to the first row.
@@ -127,7 +124,7 @@ public interface Cursor extends Closeable {
*
* @return whether the move succeeded.
*/
// boolean moveToLast();
boolean moveToLast();
/**
* Move the cursor to the next row.
@@ -147,21 +144,21 @@ public interface Cursor extends Closeable {
*
* @return whether the move succeeded.
*/
// boolean moveToPrevious();
boolean moveToPrevious();
/**
* Returns whether the cursor is pointing to the first row.
*
* @return whether the cursor is pointing at the first entry.
*/
// boolean isFirst();
boolean isFirst();
/**
* Returns whether the cursor is pointing to the last row.
*
* @return whether the cursor is pointing at the last entry.
*/
// boolean isLast();
boolean isLast();
/**
* Returns whether the cursor is pointing to the position before the first
@@ -169,7 +166,7 @@ public interface Cursor extends Closeable {
*
* @return whether the cursor is before the first result.
*/
// boolean isBeforeFirst();
boolean isBeforeFirst();
/**
* Returns whether the cursor is pointing to the position after the last
@@ -202,7 +199,7 @@ public interface Cursor extends Closeable {
* @see #getColumnIndex(String)
* @throws IllegalArgumentException if the column does not exist
*/
// int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException;
int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException;
/**
* Returns the column name at the given zero-based column index.
@@ -210,7 +207,7 @@ public interface Cursor extends Closeable {
* @param columnIndex the zero-based index of the target column.
* @return the column name for the given column index.
*/
// String getColumnName(int columnIndex);
String getColumnName(int columnIndex);
/**
* Returns a string array holding the names of all of the columns in the
@@ -218,13 +215,13 @@ public interface Cursor extends Closeable {
*
* @return the names of the columns returned in this query.
*/
// String[] getColumnNames();
String[] getColumnNames();
/**
* Return total number of columns
* @return number of columns
*/
// int getColumnCount();
int getColumnCount();
/**
* Returns the value of the requested column as a byte array.
@@ -236,7 +233,7 @@ public interface Cursor extends Closeable {
* @param columnIndex the zero-based index of the target column.
* @return the value of that column as a byte array.
*/
// byte[] getBlob(int columnIndex);
byte[] getBlob(int columnIndex);
/**
* Returns the value of the requested column as a String.
@@ -258,7 +255,7 @@ public interface Cursor extends Closeable {
* if the target column is null, return buffer
* @param buffer the buffer to copy the text into.
*/
// void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer);
void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer);
/**
* Returns the value of the requested column as a short.
@@ -271,7 +268,7 @@ public interface Cursor extends Closeable {
* @param columnIndex the zero-based index of the target column.
* @return the value of that column as a short.
*/
// short getShort(int columnIndex);
short getShort(int columnIndex);
/**
* Returns the value of the requested column as an int.
@@ -310,7 +307,7 @@ public interface Cursor extends Closeable {
* @param columnIndex the zero-based index of the target column.
* @return the value of that column as a float.
*/
// float getFloat(int columnIndex);
float getFloat(int columnIndex);
/**
* Returns the value of the requested column as a double.
@@ -323,7 +320,7 @@ public interface Cursor extends Closeable {
* @param columnIndex the zero-based index of the target column.
* @return the value of that column as a double.
*/
// double getDouble(int columnIndex);
double getDouble(int columnIndex);
/**
* Returns data type of the given column's value.
@@ -344,7 +341,7 @@ public interface Cursor extends Closeable {
* @param columnIndex the zero-based index of the target column.
* @return column value type
*/
// int getType(int columnIndex);
int getType(int columnIndex);
/**
* Returns <code>true</code> if the value in the indicated column is null.
@@ -352,7 +349,7 @@ public interface Cursor extends Closeable {
* @param columnIndex the zero-based index of the target column.
* @return whether the column value is null.
*/
// boolean isNull(int columnIndex);
boolean isNull(int columnIndex);
/**
* Deactivates the Cursor, making all calls on it fail until {@link #requery} is called.
@@ -390,7 +387,7 @@ public interface Cursor extends Closeable {
* return true if the cursor is closed
* @return true if the cursor is closed.
*/
// boolean isClosed();
boolean isClosed();
/**
* Register an observer that is called when changes happen to the content backing this cursor.
@@ -399,7 +396,7 @@ public interface Cursor extends Closeable {
* @param observer the object that gets notified when the content backing the cursor changes.
* @see #unregisterContentObserver(ContentObserver)
*/
// void registerContentObserver(ContentObserver observer);
void registerContentObserver(ContentObserver observer);
/**
* Unregister an observer that has previously been registered with this
@@ -408,7 +405,7 @@ public interface Cursor extends Closeable {
* @param observer the object to unregister.
* @see #registerContentObserver(ContentObserver)
*/
// void unregisterContentObserver(ContentObserver observer);
void unregisterContentObserver(ContentObserver observer);
/**
* Register an observer that is called when changes happen to the contents
@@ -418,7 +415,7 @@ public interface Cursor extends Closeable {
* @param observer the object that gets notified when the cursors data set changes.
* @see #unregisterDataSetObserver(DataSetObserver)
*/
// void registerDataSetObserver(DataSetObserver observer);
void registerDataSetObserver(DataSetObserver observer);
/**
* Unregister an observer that has previously been registered with this
@@ -427,7 +424,7 @@ public interface Cursor extends Closeable {
* @param observer the object to unregister.
* @see #registerDataSetObserver(DataSetObserver)
*/
// void unregisterDataSetObserver(DataSetObserver observer);
void unregisterDataSetObserver(DataSetObserver observer);
/**
* Register to watch a content URI for changes. This can be the URI of a specific data row (for
@@ -437,7 +434,7 @@ public interface Cursor extends Closeable {
* this resolver will be notified.
* @param uri The content URI to watch.
*/
// void setNotificationUri(ContentResolver cr, Uri uri);
void setNotificationUri(ContentResolver cr, Uri uri);
/**
* Return the URI at which notifications of changes in this Cursor's data
@@ -447,13 +444,13 @@ public interface Cursor extends Closeable {
* ContentResolver.registerContentObserver} to find out about changes to this Cursor's
* data. May be null if no notification URI has been set.
*/
// Uri getNotificationUri();
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();
boolean getWantsAllOnMoveCalls();
/**
* Returns a bundle of extra values. This is an optional way for cursors to provide out-of-band
@@ -464,7 +461,7 @@ public interface Cursor extends Closeable {
* @return cursor-defined values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY} if there
* are no values. Never <code>null</code>.
*/
// Bundle getExtras();
Bundle getExtras();
/**
* This is an out-of-band way for the the user of a cursor to communicate with the cursor. The
@@ -477,5 +474,5 @@ public interface Cursor extends Closeable {
* @return extra values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY}.
* Never <code>null</code>.
*/
// Bundle respond(Bundle extras);
Bundle respond(Bundle extras);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,117 @@
/*
* Copyright (C) 2010 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.
*/
/*
** Modified to support SQLite extensions by the SQLite developers:
** sqlite-dev@sqlite.org.
*/
package android.database;
import java.io.File;
import java.util.List;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.util.Log;
import android.util.Pair;
/**
* Default class used to define the action to take when database corruption is reported
* by sqlite.
* <p>
* An application can specify an implementation of {@link DatabaseErrorHandler} on the
* following:
* <ul>
* <li>{@link SQLiteDatabase#openOrCreateDatabase(String,
* android.database.sqlite.SQLiteDatabase.CursorFactory, DatabaseErrorHandler)}</li>
* <li>{@link SQLiteDatabase#openDatabase(String,
* android.database.sqlite.SQLiteDatabase.CursorFactory, int, DatabaseErrorHandler)}</li>
* </ul>
* The specified {@link DatabaseErrorHandler} is used to handle database corruption errors, if they
* occur.
* <p>
* If null is specified for the DatabaseErrorHandler param in the above calls, this class is used
* as the default {@link DatabaseErrorHandler}.
*/
public final class DefaultDatabaseErrorHandler implements DatabaseErrorHandler {
private static final String TAG = "DefaultDatabaseErrorHandler";
/**
* defines the default method to be invoked when database corruption is detected.
* @param dbObj the {@link SQLiteDatabase} object representing the database on which corruption
* is detected.
*/
public void onCorruption(SQLiteDatabase dbObj) {
Log.e(TAG, "Corruption reported by sqlite on database: " + dbObj.getPath());
// If this is a SEE build, do not delete any database files.
// It may be that the user has specified an incorrect password.
if( SQLiteDatabase.hasCodec() ) return;
// is the corruption detected even before database could be 'opened'?
if (!dbObj.isOpen()) {
// database files are not even openable. delete this database file.
// NOTE if the database has attached databases, then any of them could be corrupt.
// and not deleting all of them could cause corrupted database file to remain and
// make the application crash on database open operation. To avoid this problem,
// the application should provide its own {@link DatabaseErrorHandler} impl class
// to delete ALL files of the database (including the attached databases).
deleteDatabaseFile(dbObj.getPath());
return;
}
List<Pair<String, String>> attachedDbs = null;
try {
// Close the database, which will cause subsequent operations to fail.
// before that, get the attached database list first.
try {
attachedDbs = dbObj.getAttachedDbs();
} catch (SQLiteException e) {
/* ignore */
}
try {
dbObj.close();
} catch (SQLiteException e) {
/* ignore */
}
} finally {
// Delete all files of this corrupt database and/or attached databases
if (attachedDbs != null) {
for (Pair<String, String> p : attachedDbs) {
deleteDatabaseFile(p.second);
}
} else {
// attachedDbs = null is possible when the database is so corrupt that even
// "PRAGMA database_list;" also fails. delete the main database file
deleteDatabaseFile(dbObj.getPath());
}
}
}
private void deleteDatabaseFile(String fileName) {
if (fileName.equalsIgnoreCase(":memory:") || fileName.trim().length() == 0) {
return;
}
Log.e(TAG, "deleting the database file: " + fileName);
try {
SQLiteDatabase.deleteDatabase(new File(fileName));
} catch (Exception e) {
/* print warning and ignore exception */
Log.w(TAG, "delete failed: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.
*/
/*
** Modified to support SQLite extensions by the SQLite developers:
** sqlite-dev@sqlite.org.
*/
package android.database;
/**
* An exception that indicates there was an error with SQL parsing or execution.
*/
public class SQLException extends RuntimeException {
public SQLException() {
}
public SQLException(String error) {
super(error);
}
public SQLException(String error, Throwable cause) {
super(error, cause);
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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.
*/
/*
** Modified to support SQLite extensions by the SQLite developers:
** sqlite-dev@sqlite.org.
*/
package android.database.sqlite;
/**
* An exception that indicates that garbage-collector is finalizing a database object
* that is not explicitly closed
* @hide
*/
public class DatabaseObjectNotClosedException extends RuntimeException {
private static final String s = "Application did not close the cursor or database object " +
"that was opened here";
public DatabaseObjectNotClosedException() {
super(s);
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2008 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.
*/
/*
** Modified to support SQLite extensions by the SQLite developers:
** sqlite-dev@sqlite.org.
*/
package android.database.sqlite;
/**
* An exception that indicates that the SQLite program was aborted.
* This can happen either through a call to ABORT in a trigger,
* or as the result of using the ABORT conflict clause.
*/
public class SQLiteAbortException extends SQLiteException {
public SQLiteAbortException() {}
public SQLiteAbortException(String error) {
super(error);
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2010 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.
*/
/*
** Modified to support SQLite extensions by the SQLite developers:
** sqlite-dev@sqlite.org.
*/
package android.database.sqlite;
/**
* This exception class is used when sqlite can't access the database file
* due to lack of permissions on the file.
*/
public class SQLiteAccessPermException extends SQLiteException {
public SQLiteAccessPermException() {}
public SQLiteAccessPermException(String error) {
super(error);
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2010 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.
*/
/*
** Modified to support SQLite extensions by the SQLite developers:
** sqlite-dev@sqlite.org.
*/
package android.database.sqlite;
/**
* Thrown if the the bind or column parameter index is out of range
*/
public class SQLiteBindOrColumnIndexOutOfRangeException extends SQLiteException {
public SQLiteBindOrColumnIndexOutOfRangeException() {}
public SQLiteBindOrColumnIndexOutOfRangeException(String error) {
super(error);
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2010 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.
*/
/*
** Modified to support SQLite extensions by the SQLite developers:
** sqlite-dev@sqlite.org.
*/
package android.database.sqlite;
public class SQLiteBlobTooBigException extends SQLiteException {
public SQLiteBlobTooBigException() {}
public SQLiteBlobTooBigException(String error) {
super(error);
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2010 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.
*/
/*
** Modified to support SQLite extensions by the SQLite developers:
** sqlite-dev@sqlite.org.
*/
package android.database.sqlite;
public class SQLiteCantOpenDatabaseException extends SQLiteException {
public SQLiteCantOpenDatabaseException() {}
public SQLiteCantOpenDatabaseException(String error) {
super(error);
}
}

View File

@@ -0,0 +1,112 @@
/*
* 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.
*/
/*
** Modified to support SQLite extensions by the SQLite developers:
** sqlite-dev@sqlite.org.
*/
package android.database.sqlite;
import java.io.Closeable;
/**
* An object created from a SQLiteDatabase that can be closed.
*
* This class implements a primitive reference counting scheme for database objects.
*/
public abstract class SQLiteClosable implements Closeable {
private int mReferenceCount = 1;
/**
* Called when the last reference to the object was released by
* a call to {@link #releaseReference()} or {@link #close()}.
*/
protected abstract void onAllReferencesReleased();
/**
* Called when the last reference to the object was released by
* a call to {@link #releaseReferenceFromContainer()}.
*
* @deprecated Do not use.
*/
@Deprecated
protected void onAllReferencesReleasedFromContainer() {
onAllReferencesReleased();
}
/**
* Acquires a reference to the object.
*
* @throws IllegalStateException if the last reference to the object has already
* been released.
*/
public void acquireReference() {
synchronized(this) {
if (mReferenceCount <= 0) {
throw new IllegalStateException(
"attempt to re-open an already-closed object: " + this);
}
mReferenceCount++;
}
}
/**
* Releases a reference to the object, closing the object if the last reference
* was released.
*
* @see #onAllReferencesReleased()
*/
public void releaseReference() {
boolean refCountIsZero = false;
synchronized(this) {
refCountIsZero = --mReferenceCount == 0;
}
if (refCountIsZero) {
onAllReferencesReleased();
}
}
/**
* Releases a reference to the object that was owned by the container of the object,
* closing the object if the last reference was released.
*
* @see #onAllReferencesReleasedFromContainer()
* @deprecated Do not use.
*/
@Deprecated
public void releaseReferenceFromContainer() {
boolean refCountIsZero = false;
synchronized(this) {
refCountIsZero = --mReferenceCount == 0;
}
if (refCountIsZero) {
onAllReferencesReleasedFromContainer();
}
}
/**
* Releases a reference to the object, closing the object if the last reference
* was released.
*
* Calling this method is equivalent to calling {@link #releaseReference}.
*
* @see #releaseReference()
* @see #onAllReferencesReleased()
*/
public void close() {
releaseReference();
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More