mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 727264 - Update Profile Migration to use Cursors. r=blassey
This commit is contained in:
parent
8fc091bd34
commit
9cdd43ae4f
@ -96,6 +96,7 @@ FENNEC_JAVA_FILES = \
|
||||
ProfileMigrator.java \
|
||||
PromptService.java \
|
||||
sqlite/ByteBufferInputStream.java \
|
||||
sqlite/MatrixBlobCursor.java \
|
||||
sqlite/SQLiteBridge.java \
|
||||
sqlite/SQLiteBridgeException.java \
|
||||
SetupScreen.java \
|
||||
|
@ -45,7 +45,6 @@ import org.mozilla.gecko.db.BrowserContract.Images;
|
||||
import org.mozilla.gecko.db.BrowserContract.URLColumns;
|
||||
import org.mozilla.gecko.db.BrowserContract.SyncColumns;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.sqlite.ByteBufferInputStream;
|
||||
import org.mozilla.gecko.sqlite.SQLiteBridge;
|
||||
import org.mozilla.gecko.sqlite.SQLiteBridgeException;
|
||||
|
||||
@ -62,10 +61,11 @@ import android.provider.Browser;
|
||||
import android.util.Log;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -220,17 +220,20 @@ public class ProfileMigrator {
|
||||
mRerootMap = new HashMap<Long, Long>();
|
||||
|
||||
try {
|
||||
ArrayList<Object[]> queryResult = db.query(kRootQuery);
|
||||
final int rootCol = db.getColumnIndex(kRootName);
|
||||
final int folderCol = db.getColumnIndex(kRootFolderId);
|
||||
Cursor cursor = db.rawQuery(kRootQuery, null);
|
||||
final int rootCol = cursor.getColumnIndex(kRootName);
|
||||
final int folderCol = cursor.getColumnIndex(kRootFolderId);
|
||||
|
||||
for (Object[] resultRow: queryResult) {
|
||||
String name = (String)resultRow[rootCol];
|
||||
long placesFolderId = Integer.parseInt((String)resultRow[folderCol]);
|
||||
cursor.moveToFirst();
|
||||
while (!cursor.isAfterLast()) {
|
||||
String name = cursor.getString(rootCol);
|
||||
long placesFolderId = cursor.getLong(folderCol);
|
||||
mRerootMap.put(placesFolderId, getFolderId(name));
|
||||
Log.v(LOGTAG, "Name: " + name + ", pid=" + placesFolderId
|
||||
+ ", nid=" + mRerootMap.get(placesFolderId));
|
||||
cursor.moveToNext();
|
||||
}
|
||||
cursor.close();
|
||||
} catch (SQLiteBridgeException e) {
|
||||
Log.e(LOGTAG, "Failed to get bookmark roots: ", e);
|
||||
return;
|
||||
@ -337,15 +340,15 @@ public class ProfileMigrator {
|
||||
}
|
||||
}
|
||||
|
||||
protected BitmapDrawable decodeImageData(ByteBuffer data) {
|
||||
ByteBufferInputStream byteStream = new ByteBufferInputStream(data);
|
||||
protected BitmapDrawable decodeImageData(byte[] data) {
|
||||
InputStream byteStream = new ByteArrayInputStream(data);
|
||||
BitmapDrawable image =
|
||||
(BitmapDrawable)Drawable.createFromStream(byteStream, "src");
|
||||
return image;
|
||||
}
|
||||
|
||||
protected void addFavicon(String url, String faviconUrl, String faviconGuid,
|
||||
String mime, ByteBuffer data) {
|
||||
String mime, byte[] data) {
|
||||
// Some GIFs can cause us to lock up completely
|
||||
// without exceptions or anything. Not cool.
|
||||
if (mime == null || mime.compareTo("image/gif") == 0) {
|
||||
@ -373,9 +376,7 @@ public class ProfileMigrator {
|
||||
} else {
|
||||
// PNG images can be passed directly. Well, aside
|
||||
// from having to convert them into a byte[].
|
||||
byte[] byteArray = new byte[data.remaining()];
|
||||
data.get(byteArray);
|
||||
values.put(Images.FAVICON, byteArray);
|
||||
values.put(Images.FAVICON, data);
|
||||
}
|
||||
|
||||
values.put(Images.URL, url);
|
||||
@ -412,26 +413,26 @@ public class ProfileMigrator {
|
||||
*/
|
||||
Integer.toString(BrowserDB.getMaxHistoryCount())
|
||||
};
|
||||
ArrayList<Object[]> queryResult =
|
||||
db.query(kHistoryQuery, queryParams);
|
||||
final int urlCol = db.getColumnIndex(kHistoryUrl);
|
||||
final int titleCol = db.getColumnIndex(kHistoryTitle);
|
||||
final int dateCol = db.getColumnIndex(kHistoryDate);
|
||||
final int visitsCol = db.getColumnIndex(kHistoryVisits);
|
||||
final int faviconMimeCol = db.getColumnIndex(kFaviconMime);
|
||||
final int faviconDataCol = db.getColumnIndex(kFaviconData);
|
||||
final int faviconUrlCol = db.getColumnIndex(kFaviconUrl);
|
||||
final int faviconGuidCol = db.getColumnIndex(kFaviconGuid);
|
||||
Cursor cursor = db.rawQuery(kHistoryQuery, queryParams);
|
||||
final int urlCol = cursor.getColumnIndex(kHistoryUrl);
|
||||
final int titleCol = cursor.getColumnIndex(kHistoryTitle);
|
||||
final int dateCol = cursor.getColumnIndex(kHistoryDate);
|
||||
final int visitsCol = cursor.getColumnIndex(kHistoryVisits);
|
||||
final int faviconMimeCol = cursor.getColumnIndex(kFaviconMime);
|
||||
final int faviconDataCol = cursor.getColumnIndex(kFaviconData);
|
||||
final int faviconUrlCol = cursor.getColumnIndex(kFaviconUrl);
|
||||
final int faviconGuidCol = cursor.getColumnIndex(kFaviconGuid);
|
||||
|
||||
for (Object[] resultRow: queryResult) {
|
||||
String url = (String)resultRow[urlCol];
|
||||
String title = (String)resultRow[titleCol];
|
||||
long date = Long.parseLong((String)(resultRow[dateCol])) / (long)1000;
|
||||
int visits = Integer.parseInt((String)(resultRow[visitsCol]));
|
||||
ByteBuffer faviconDataBuff = (ByteBuffer)resultRow[faviconDataCol];
|
||||
String faviconMime = (String)resultRow[faviconMimeCol];
|
||||
String faviconUrl = (String)resultRow[faviconUrlCol];
|
||||
String faviconGuid = (String)resultRow[faviconGuidCol];
|
||||
cursor.moveToFirst();
|
||||
while (!cursor.isAfterLast()) {
|
||||
String url = cursor.getString(urlCol);
|
||||
String title = cursor.getString(titleCol);
|
||||
long date = cursor.getLong(dateCol) / (long)1000;
|
||||
int visits = cursor.getInt(visitsCol);
|
||||
byte[] faviconDataBuff = cursor.getBlob(faviconDataCol);
|
||||
String faviconMime = cursor.getString(faviconMimeCol);
|
||||
String faviconUrl = cursor.getString(faviconUrlCol);
|
||||
String faviconGuid = cursor.getString(faviconGuidCol);
|
||||
|
||||
try {
|
||||
placesHistory.add(url);
|
||||
@ -441,7 +442,9 @@ public class ProfileMigrator {
|
||||
} catch (Exception e) {
|
||||
Log.e(LOGTAG, "Error adding history entry: ", e);
|
||||
}
|
||||
cursor.moveToNext();
|
||||
}
|
||||
cursor.close();
|
||||
} catch (SQLiteBridgeException e) {
|
||||
Log.e(LOGTAG, "Failed to get history: ", e);
|
||||
return;
|
||||
@ -499,20 +502,20 @@ public class ProfileMigrator {
|
||||
|
||||
protected void migrateBookmarks(SQLiteBridge db) {
|
||||
try {
|
||||
ArrayList<Object[]> queryResult = db.query(kBookmarkQuery);
|
||||
final int urlCol = db.getColumnIndex(kBookmarkUrl);
|
||||
final int titleCol = db.getColumnIndex(kBookmarkTitle);
|
||||
final int guidCol = db.getColumnIndex(kBookmarkGuid);
|
||||
final int idCol = db.getColumnIndex(kBookmarkId);
|
||||
final int typeCol = db.getColumnIndex(kBookmarkType);
|
||||
final int parentCol = db.getColumnIndex(kBookmarkParent);
|
||||
final int addedCol = db.getColumnIndex(kBookmarkAdded);
|
||||
final int modifiedCol = db.getColumnIndex(kBookmarkModified);
|
||||
final int positionCol = db.getColumnIndex(kBookmarkPosition);
|
||||
final int faviconMimeCol = db.getColumnIndex(kFaviconMime);
|
||||
final int faviconDataCol = db.getColumnIndex(kFaviconData);
|
||||
final int faviconUrlCol = db.getColumnIndex(kFaviconUrl);
|
||||
final int faviconGuidCol = db.getColumnIndex(kFaviconGuid);
|
||||
Cursor cursor = db.rawQuery(kBookmarkQuery, null);
|
||||
final int urlCol = cursor.getColumnIndex(kBookmarkUrl);
|
||||
final int titleCol = cursor.getColumnIndex(kBookmarkTitle);
|
||||
final int guidCol = cursor.getColumnIndex(kBookmarkGuid);
|
||||
final int idCol = cursor.getColumnIndex(kBookmarkId);
|
||||
final int typeCol = cursor.getColumnIndex(kBookmarkType);
|
||||
final int parentCol = cursor.getColumnIndex(kBookmarkParent);
|
||||
final int addedCol = cursor.getColumnIndex(kBookmarkAdded);
|
||||
final int modifiedCol = cursor.getColumnIndex(kBookmarkModified);
|
||||
final int positionCol = cursor.getColumnIndex(kBookmarkPosition);
|
||||
final int faviconMimeCol = cursor.getColumnIndex(kFaviconMime);
|
||||
final int faviconDataCol = cursor.getColumnIndex(kFaviconData);
|
||||
final int faviconUrlCol = cursor.getColumnIndex(kFaviconUrl);
|
||||
final int faviconGuidCol = cursor.getColumnIndex(kFaviconGuid);
|
||||
|
||||
// The keys are places IDs.
|
||||
Set<Long> openFolders = new HashSet<Long>();
|
||||
@ -535,33 +538,38 @@ public class ProfileMigrator {
|
||||
int added = 0;
|
||||
int skipped = 0;
|
||||
|
||||
for (Object[] resultRow: queryResult) {
|
||||
long id = Long.parseLong((String)resultRow[idCol]);
|
||||
cursor.moveToFirst();
|
||||
while (!cursor.isAfterLast()) {
|
||||
long id = cursor.getLong(idCol);
|
||||
|
||||
// Already processed? if so just skip
|
||||
if (processedBookmarks.contains(id))
|
||||
if (processedBookmarks.contains(id)) {
|
||||
cursor.moveToNext();
|
||||
continue;
|
||||
}
|
||||
|
||||
int type = Integer.parseInt((String)resultRow[typeCol]);
|
||||
long parent = Long.parseLong((String)resultRow[parentCol]);
|
||||
int type = cursor.getInt(typeCol);
|
||||
long parent = cursor.getLong(parentCol);
|
||||
|
||||
// Places has an explicit root folder, id=1 parent=0.
|
||||
// Skip that.
|
||||
if (id == 1 && parent == 0 && type == kPlacesTypeFolder)
|
||||
if (id == 1 && parent == 0 && type == kPlacesTypeFolder) {
|
||||
cursor.moveToNext();
|
||||
continue;
|
||||
}
|
||||
|
||||
String url = (String)resultRow[urlCol];
|
||||
String title = (String)resultRow[titleCol];
|
||||
String guid = (String)resultRow[guidCol];
|
||||
String url = cursor.getString(urlCol);
|
||||
String title = cursor.getString(titleCol);
|
||||
String guid = cursor.getString(guidCol);
|
||||
long dateadded =
|
||||
Long.parseLong((String)resultRow[addedCol]) / (long)1000;
|
||||
cursor.getLong(addedCol) / (long)1000;
|
||||
long datemodified =
|
||||
Long.parseLong((String)resultRow[modifiedCol]) / (long)1000;
|
||||
long position = Long.parseLong((String)resultRow[positionCol]);
|
||||
ByteBuffer faviconDataBuff = (ByteBuffer)resultRow[faviconDataCol];
|
||||
String faviconMime = (String)resultRow[faviconMimeCol];
|
||||
String faviconUrl = (String)resultRow[faviconUrlCol];
|
||||
String faviconGuid = (String)resultRow[faviconGuidCol];
|
||||
cursor.getLong(modifiedCol) / (long)1000;
|
||||
long position = cursor.getLong(positionCol);
|
||||
byte[] faviconDataBuff = cursor.getBlob(faviconDataCol);
|
||||
String faviconMime = cursor.getString(faviconMimeCol);
|
||||
String faviconUrl = cursor.getString(faviconUrlCol);
|
||||
String faviconGuid = cursor.getString(faviconGuidCol);
|
||||
|
||||
// Is the parent for this bookmark already added?
|
||||
// If so, we can add the bookmark itself.
|
||||
@ -590,6 +598,7 @@ public class ProfileMigrator {
|
||||
openFolders.add(parent);
|
||||
skipped++;
|
||||
}
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
// Now check if any of the new folders we added was a folder
|
||||
@ -608,6 +617,8 @@ public class ProfileMigrator {
|
||||
Log.i(LOGTAG, "Iteration = " + iterations + ", added " + added +
|
||||
" bookmark(s), skipped " + skipped + " bookmark(s)");
|
||||
} while (!openFolders.isEmpty());
|
||||
|
||||
cursor.close();
|
||||
} catch (SQLiteBridgeException e) {
|
||||
Log.e(LOGTAG, "Failed to get bookmarks: ", e);
|
||||
return;
|
||||
|
310
mobile/android/base/sqlite/MatrixBlobCursor.java
Normal file
310
mobile/android/base/sqlite/MatrixBlobCursor.java
Normal file
@ -0,0 +1,310 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
/*
|
||||
* 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 org.mozilla.gecko.sqlite;
|
||||
|
||||
import org.mozilla.gecko.sqlite.SQLiteBridgeException;
|
||||
|
||||
import android.database.AbstractCursor;
|
||||
import android.database.CursorIndexOutOfBoundsException;
|
||||
import android.database.DatabaseUtils;
|
||||
import java.lang.UnsupportedOperationException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/*
|
||||
* Android's AbstractCursor throws on getBlob()
|
||||
* and MatrixCursor forgot to override it. This was fixed
|
||||
* at some point but old devices are still SOL.
|
||||
* Oh, and everything in MatrixCursor is private instead of
|
||||
* protected, so we need to entirely duplicate it here,
|
||||
* instad of just being able to add the missing method.
|
||||
*/
|
||||
/**
|
||||
* A mutable cursor implementation backed by an array of {@code Object}s. Use
|
||||
* {@link #newRow()} to add rows. Automatically expands internal capacity
|
||||
* as needed.
|
||||
*/
|
||||
public class MatrixBlobCursor extends AbstractCursor {
|
||||
|
||||
private final String[] columnNames;
|
||||
private Object[] data;
|
||||
private int rowCount = 0;
|
||||
private final int columnCount;
|
||||
|
||||
/**
|
||||
* Constructs a new cursor with the given initial capacity.
|
||||
*
|
||||
* @param columnNames names of the columns, the ordering of which
|
||||
* determines column ordering elsewhere in this cursor
|
||||
* @param initialCapacity in rows
|
||||
*/
|
||||
public MatrixBlobCursor(String[] columnNames, int initialCapacity) {
|
||||
this.columnNames = columnNames;
|
||||
this.columnCount = columnNames.length;
|
||||
|
||||
if (initialCapacity < 1) {
|
||||
initialCapacity = 1;
|
||||
}
|
||||
|
||||
this.data = new Object[columnCount * initialCapacity];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new cursor.
|
||||
*
|
||||
* @param columnNames names of the columns, the ordering of which
|
||||
* determines column ordering elsewhere in this cursor
|
||||
*/
|
||||
public MatrixBlobCursor(String[] columnNames) {
|
||||
this(columnNames, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets value at the given column for the current row.
|
||||
*/
|
||||
protected Object get(int column) {
|
||||
if (column < 0 || column >= columnCount) {
|
||||
throw new CursorIndexOutOfBoundsException("Requested column: "
|
||||
+ column + ", # of columns: " + columnCount);
|
||||
}
|
||||
if (mPos < 0) {
|
||||
throw new CursorIndexOutOfBoundsException("Before first row.");
|
||||
}
|
||||
if (mPos >= rowCount) {
|
||||
throw new CursorIndexOutOfBoundsException("After last row.");
|
||||
}
|
||||
return data[mPos * columnCount + column];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new row to the end and returns a builder for that row. Not safe
|
||||
* for concurrent use.
|
||||
*
|
||||
* @return builder which can be used to set the column values for the new
|
||||
* row
|
||||
*/
|
||||
public RowBuilder newRow() {
|
||||
rowCount++;
|
||||
int endIndex = rowCount * columnCount;
|
||||
ensureCapacity(endIndex);
|
||||
int start = endIndex - columnCount;
|
||||
return new RowBuilder(start, endIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new row to the end with the given column values. Not safe
|
||||
* for concurrent use.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code columnValues.length !=
|
||||
* columnNames.length}
|
||||
* @param columnValues in the same order as the the column names specified
|
||||
* at cursor construction time
|
||||
*/
|
||||
public void addRow(Object[] columnValues) {
|
||||
if (columnValues.length != columnCount) {
|
||||
throw new IllegalArgumentException("columnNames.length = "
|
||||
+ columnCount + ", columnValues.length = "
|
||||
+ columnValues.length);
|
||||
}
|
||||
|
||||
int start = rowCount++ * columnCount;
|
||||
ensureCapacity(start + columnCount);
|
||||
System.arraycopy(columnValues, 0, data, start, columnCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new row to the end with the given column values. Not safe
|
||||
* for concurrent use.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code columnValues.size() !=
|
||||
* columnNames.length}
|
||||
* @param columnValues in the same order as the the column names specified
|
||||
* at cursor construction time
|
||||
*/
|
||||
public void addRow(Iterable<?> columnValues) {
|
||||
int start = rowCount * columnCount;
|
||||
int end = start + columnCount;
|
||||
ensureCapacity(end);
|
||||
|
||||
if (columnValues instanceof ArrayList<?>) {
|
||||
addRow((ArrayList<?>) columnValues, start);
|
||||
return;
|
||||
}
|
||||
|
||||
int current = start;
|
||||
Object[] localData = data;
|
||||
for (Object columnValue : columnValues) {
|
||||
if (current == end) {
|
||||
// TODO: null out row?
|
||||
throw new IllegalArgumentException(
|
||||
"columnValues.size() > columnNames.length");
|
||||
}
|
||||
localData[current++] = columnValue;
|
||||
}
|
||||
|
||||
if (current != end) {
|
||||
// TODO: null out row?
|
||||
throw new IllegalArgumentException(
|
||||
"columnValues.size() < columnNames.length");
|
||||
}
|
||||
|
||||
// Increase row count here in case we encounter an exception.
|
||||
rowCount++;
|
||||
}
|
||||
|
||||
/** Optimization for {@link ArrayList}. */
|
||||
private void addRow(ArrayList<?> columnValues, int start) {
|
||||
int size = columnValues.size();
|
||||
if (size != columnCount) {
|
||||
throw new IllegalArgumentException("columnNames.length = "
|
||||
+ columnCount + ", columnValues.size() = " + size);
|
||||
}
|
||||
|
||||
rowCount++;
|
||||
Object[] localData = data;
|
||||
for (int i = 0; i < size; i++) {
|
||||
localData[start + i] = columnValues.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
/** Ensures that this cursor has enough capacity. */
|
||||
private void ensureCapacity(int size) {
|
||||
if (size > data.length) {
|
||||
Object[] oldData = this.data;
|
||||
int newSize = data.length * 2;
|
||||
if (newSize < size) {
|
||||
newSize = size;
|
||||
}
|
||||
this.data = new Object[newSize];
|
||||
System.arraycopy(oldData, 0, this.data, 0, oldData.length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a row, starting from the left-most column and adding one column
|
||||
* value at a time. Follows the same ordering as the column names specified
|
||||
* at cursor construction time.
|
||||
*/
|
||||
public class RowBuilder {
|
||||
|
||||
private int index;
|
||||
private final int endIndex;
|
||||
|
||||
RowBuilder(int index, int endIndex) {
|
||||
this.index = index;
|
||||
this.endIndex = endIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next column value in this row.
|
||||
*
|
||||
* @throws CursorIndexOutOfBoundsException if you try to add too many
|
||||
* values
|
||||
* @return this builder to support chaining
|
||||
*/
|
||||
public RowBuilder add(Object columnValue) {
|
||||
if (index == endIndex) {
|
||||
throw new CursorIndexOutOfBoundsException(
|
||||
"No more columns left.");
|
||||
}
|
||||
|
||||
data[index++] = columnValue;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
// AbstractCursor implementation.
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getColumnNames() {
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(int column) {
|
||||
Object value = get(column);
|
||||
if (value == null) return null;
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getShort(int column) {
|
||||
Object value = get(column);
|
||||
if (value == null) return 0;
|
||||
if (value instanceof Number) return ((Number) value).shortValue();
|
||||
return Short.parseShort(value.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(int column) {
|
||||
Object value = get(column);
|
||||
if (value == null) return 0;
|
||||
if (value instanceof Number) return ((Number) value).intValue();
|
||||
return Integer.parseInt(value.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(int column) {
|
||||
Object value = get(column);
|
||||
if (value == null) return 0;
|
||||
if (value instanceof Number) return ((Number) value).longValue();
|
||||
return Long.parseLong(value.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat(int column) {
|
||||
Object value = get(column);
|
||||
if (value == null) return 0.0f;
|
||||
if (value instanceof Number) return ((Number) value).floatValue();
|
||||
return Float.parseFloat(value.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(int column) {
|
||||
Object value = get(column);
|
||||
if (value == null) return 0.0d;
|
||||
if (value instanceof Number) return ((Number) value).doubleValue();
|
||||
return Double.parseDouble(value.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBlob(int column) {
|
||||
Object value = get(column);
|
||||
if (value == null) return null;
|
||||
if (value instanceof byte[]) {
|
||||
return (byte[]) value;
|
||||
}
|
||||
if (value instanceof ByteBuffer) {
|
||||
ByteBuffer data = (ByteBuffer)value;
|
||||
byte[] byteArray = new byte[data.remaining()];
|
||||
data.get(byteArray);
|
||||
return byteArray;
|
||||
}
|
||||
throw new UnsupportedOperationException("BLOB Object not of known type");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNull(int column) {
|
||||
return get(column) == null;
|
||||
}
|
||||
}
|
@ -5,9 +5,9 @@
|
||||
package org.mozilla.gecko.sqlite;
|
||||
|
||||
import org.mozilla.gecko.sqlite.SQLiteBridgeException;
|
||||
import org.mozilla.gecko.sqlite.MatrixBlobCursor;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.MatrixCursor;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
@ -54,13 +54,13 @@ public class SQLiteBridge {
|
||||
// Executes a simple line of sql.
|
||||
public void execSQL(String sql)
|
||||
throws SQLiteBridgeException {
|
||||
query(sql, null);
|
||||
internalQuery(sql, null);
|
||||
}
|
||||
|
||||
// Executes a simple line of sql. Allow you to bind arguments
|
||||
public void execSQL(String sql, String[] bindArgs)
|
||||
throws SQLiteBridgeException {
|
||||
query(sql, bindArgs);
|
||||
internalQuery(sql, bindArgs);
|
||||
}
|
||||
|
||||
// Executes a DELETE statement on the database
|
||||
@ -72,7 +72,7 @@ public class SQLiteBridge {
|
||||
sb.append(" WHERE " + whereClause);
|
||||
}
|
||||
|
||||
query(sb.toString(), whereArgs);
|
||||
internalQuery(sb.toString(), whereArgs);
|
||||
return mQueryResults[kResultRowsChanged].intValue();
|
||||
}
|
||||
|
||||
@ -114,10 +114,16 @@ public class SQLiteBridge {
|
||||
sb.append(" " + limit);
|
||||
}
|
||||
|
||||
ArrayList<Object[]> results;
|
||||
results = query(sb.toString(), selectionArgs);
|
||||
return rawQuery(sb.toString(), selectionArgs);
|
||||
}
|
||||
|
||||
MatrixCursor cursor = new MatrixCursor(mColumns.toArray(new String[0]));
|
||||
public Cursor rawQuery(String sql, String[] selectionArgs)
|
||||
throws SQLiteBridgeException {
|
||||
ArrayList<Object[]> results;
|
||||
results = internalQuery(sql, selectionArgs);
|
||||
|
||||
MatrixBlobCursor cursor =
|
||||
new MatrixBlobCursor(mColumns.toArray(new String[0]));
|
||||
try {
|
||||
for (Object resultRow: results) {
|
||||
Object[] resultColumns = (Object[])resultRow;
|
||||
@ -160,7 +166,7 @@ public class SQLiteBridge {
|
||||
|
||||
String[] binds = new String[valueBinds.size()];
|
||||
valueBinds.toArray(binds);
|
||||
query(sb.toString(), binds);
|
||||
internalQuery(sb.toString(), binds);
|
||||
return mQueryResults[kResultInsertRowId];
|
||||
}
|
||||
|
||||
@ -195,14 +201,14 @@ public class SQLiteBridge {
|
||||
String[] binds = new String[valueNames.size()];
|
||||
valueNames.toArray(binds);
|
||||
|
||||
query(sb.toString(), binds);
|
||||
internalQuery(sb.toString(), binds);
|
||||
return mQueryResults[kResultRowsChanged].intValue();
|
||||
}
|
||||
|
||||
public int getVersion()
|
||||
throws SQLiteBridgeException {
|
||||
ArrayList<Object[]> results = null;
|
||||
results = query("PRAGMA user_version");
|
||||
results = internalQuery("PRAGMA user_version", null);
|
||||
int ret = -1;
|
||||
if (results != null) {
|
||||
for (Object resultRow: results) {
|
||||
@ -214,11 +220,6 @@ public class SQLiteBridge {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Do an SQL query without parameters
|
||||
public ArrayList<Object[]> query(String aQuery) throws SQLiteBridgeException {
|
||||
return query(aQuery, null);
|
||||
}
|
||||
|
||||
// Do an SQL query, substituting the parameters in the query with the passed
|
||||
// parameters. The parameters are subsituded in order, so named parameters
|
||||
// are not supported.
|
||||
@ -226,7 +227,7 @@ public class SQLiteBridge {
|
||||
// row being an entry in the ArrayList, and each column being one Object
|
||||
// in the Object[] array. The columns are of type null,
|
||||
// direct ByteBuffer (BLOB), or String (everything else).
|
||||
public ArrayList<Object[]> query(String aQuery, String[] aParams)
|
||||
private ArrayList<Object[]> internalQuery(String aQuery, String[] aParams)
|
||||
throws SQLiteBridgeException {
|
||||
ArrayList<Object[]> result = new ArrayList<Object[]>();
|
||||
mQueryResults = new Long[2];
|
||||
@ -237,12 +238,6 @@ public class SQLiteBridge {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Gets the index in the row Object[] for the given column name.
|
||||
// Returns -1 if not found.
|
||||
public int getColumnIndex(String aColumnName) {
|
||||
return mColumns.lastIndexOf(aColumnName);
|
||||
}
|
||||
|
||||
// nop, provided for API compatibility with SQLiteDatabase.
|
||||
public void close() { }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user