Skip to content

Instantly share code, notes, and snippets.

@tai2
Created March 26, 2012 01:22
Show Gist options
  • Save tai2/2202062 to your computer and use it in GitHub Desktop.
Save tai2/2202062 to your computer and use it in GitHub Desktop.
Merge cursors horizontally. Combining cursor A which has column (a1, a2) and B which has column (b1, b2) results a new cursor which has column (a1, a2, b1, b2).
import android.database.AbstractCursor;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.DataSetObserver;
public class ZipCursor extends AbstractCursor {
private DataSetObserver default_observer = new DataSetObserver() {
@Override
public void onChanged() {
// Reset our position so the optimizations in move-related code
// don't screw us over
mPos = -1;
}
@Override
public void onInvalidated() {
mPos = -1;
}
};
private Cursor[] cursors;
private String[] new_columns;
private int[] indeces;
private int[] offsets;
public ZipCursor(Cursor[] cursors, String[] new_columns) {
this.cursors = cursors;
this.new_columns = new_columns;
indeces = new int[new_columns.length];
offsets = new int[new_columns.length];
if (cursors.length == 0) {
throw new IllegalArgumentException("At least one cursor required");
}
if (totalColumns(cursors) != new_columns.length) {
throw new IllegalArgumentException("Total column count dosen't match");
}
if (0 < cursors.length) {
int index = 0;
int offset = 0;
for (int i = 0; i < new_columns.length; i++) {
if (cursors[index].getColumnCount() <= i - offset) {
offset += cursors[index].getColumnCount();
index++;
}
indeces[i] = index;
offsets[i] = i - offset;
}
}
for (int i = 0; i < cursors.length; i++) {
cursors[i].registerDataSetObserver(default_observer);
}
}
public ZipCursor(Cursor[] cursors) {
this(cursors, getColumnNames(cursors));
}
private static int totalColumns(Cursor[] cursors) {
int result = 0;
for (int i = 0; i < cursors.length; i++) {
result += cursors[i].getColumnCount();
}
return result;
}
private static String[] getColumnNames(Cursor[] cursors) {
String[] result = new String[totalColumns(cursors)];
int index = 0;
for (int i = 0; i < cursors.length; i++) {
for (int j = 0; j < cursors[i].getColumnCount(); j++) {
result[index++] = cursors[i].getColumnName(j);
}
}
return result;
}
@Override
public String[] getColumnNames() {
return new_columns;
}
@Override
public void close() {
for (int i = 0; i < cursors.length; i++) {
cursors[i].close();
}
super.close();
}
@Override
public void deactivate() {
for (int i = 0; i < cursors.length; i++) {
cursors[i].deactivate();
}
super.deactivate();
}
@Override
public byte[] getBlob(int column) {
return cursors[indeces[column]].getBlob(offsets[column]);
}
@Override
public int getCount() {
int max = 0;
for (int i = 0; i < cursors.length; i++) {
max = Math.max(cursors[i].getCount(), max);
}
return max;
}
@Override
public boolean onMove(int old_position, int new_position) {
boolean result = false;
for (int i = 0; i < cursors.length; i++) {
result = result | cursors[i].moveToPosition(new_position);
}
return result;
}
@Override
public double getDouble(int column) {
return cursors[indeces[column]].getDouble(offsets[column]);
}
@Override
public float getFloat(int column) {
return cursors[indeces[column]].getFloat(offsets[column]);
}
@Override
public int getInt(int column) {
return cursors[indeces[column]].getInt(offsets[column]);
}
@Override
public long getLong(int column) {
return cursors[indeces[column]].getLong(offsets[column]);
}
@Override
public short getShort(int column) {
return cursors[indeces[column]].getShort(offsets[column]);
}
@Override
public String getString(int column) {
return cursors[indeces[column]].getString(offsets[column]);
}
@Override
public int getType(int column) {
return cursors[indeces[column]].getType(offsets[column]);
}
@Override
public boolean isClosed() {
boolean result = true;
for (int i = 0; i < cursors.length; i++) {
result = result && cursors[i].isClosed();
}
return result;
}
@Override
public boolean isNull(int column) {
return cursors[indeces[column]].isNull(offsets[column]);
}
@Override
public boolean requery() {
boolean result = true;
for (int i = 0; i < cursors.length; i++) {
result = result && cursors[i].requery();
}
return result;
}
@Override
public void registerContentObserver(ContentObserver observer) {
for (int i = 0 ; i < cursors.length ; i++) {
cursors[i].registerContentObserver(observer);
}
}
@Override
public void unregisterContentObserver(ContentObserver observer) {
for (int i = 0; i < cursors.length; i++) {
cursors[i].unregisterContentObserver(observer);
}
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
for (int i = 0 ; i < cursors.length ; i++) {
cursors[i].registerDataSetObserver(observer);
}
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
for (int i = 0; i < cursors.length; i++) {
cursors[i].unregisterDataSetObserver(observer);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment