Skip to content
This repository has been archived by the owner on Aug 17, 2020. It is now read-only.

Commit

Permalink
Merge pull request #68 from square/jw/raw
Browse files Browse the repository at this point in the history
Add APIs for executing raw SQL in both trigger and no-trigger forms.
  • Loading branch information
JakeWharton committed Oct 18, 2015
2 parents fed28af + 791b8d1 commit 02b66a1
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.support.test.InstrumentationRegistry;
Expand Down Expand Up @@ -476,6 +477,86 @@ public final class BriteDatabaseTest {
.isExhausted();
}

@Test public void executeSqlNoTrigger() {
db.createQuery(TABLE_EMPLOYEE, SELECT_EMPLOYEES)
.skip(1) // Skip initial
.subscribe(o);

db.execute("UPDATE " + TABLE_EMPLOYEE + " SET " + TestDb.EmployeeTable.NAME + " = 'Zach'");
o.assertNoMoreEvents();
}

@Test public void executeSqlWithArgsNoTrigger() {
db.createQuery(TABLE_EMPLOYEE, SELECT_EMPLOYEES)
.skip(1) // Skip initial
.subscribe(o);

db.execute("UPDATE " + TABLE_EMPLOYEE + " SET " + TestDb.EmployeeTable.NAME + " = ?", "Zach");
o.assertNoMoreEvents();
}

@Test public void executeSqlAndTrigger() {
db.createQuery(TABLE_EMPLOYEE, SELECT_EMPLOYEES).subscribe(o);
o.assertCursor()
.hasRow("alice", "Alice Allison")
.hasRow("bob", "Bob Bobberson")
.hasRow("eve", "Eve Evenson")
.isExhausted();

db.executeAndTrigger(TABLE_EMPLOYEE,
"UPDATE " + TABLE_EMPLOYEE + " SET " + TestDb.EmployeeTable.NAME + " = 'Zach'");
o.assertCursor()
.hasRow("alice", "Zach")
.hasRow("bob", "Zach")
.hasRow("eve", "Zach")
.isExhausted();
}

@Test public void executeSqlThrowsAndDoesNotTrigger() {
db.createQuery(TABLE_EMPLOYEE, SELECT_EMPLOYEES)
.skip(1) // Skip initial
.subscribe(o);

try {
db.executeAndTrigger(TABLE_EMPLOYEE,
"UPDATE not_a_table SET " + TestDb.EmployeeTable.NAME + " = 'Zach'");
fail();
} catch (SQLException ignored) {
}
o.assertNoMoreEvents();
}

@Test public void executeSqlWithArgsAndTrigger() {
db.createQuery(TABLE_EMPLOYEE, SELECT_EMPLOYEES).subscribe(o);
o.assertCursor()
.hasRow("alice", "Alice Allison")
.hasRow("bob", "Bob Bobberson")
.hasRow("eve", "Eve Evenson")
.isExhausted();

db.executeAndTrigger(TABLE_EMPLOYEE,
"UPDATE " + TABLE_EMPLOYEE + " SET " + TestDb.EmployeeTable.NAME + " = ?", "Zach");
o.assertCursor()
.hasRow("alice", "Zach")
.hasRow("bob", "Zach")
.hasRow("eve", "Zach")
.isExhausted();
}

@Test public void executeSqlWithArgsThrowsAndDoesNotTrigger() {
db.createQuery(TABLE_EMPLOYEE, SELECT_EMPLOYEES)
.skip(1) // Skip initial
.subscribe(o);

try {
db.executeAndTrigger(TABLE_EMPLOYEE,
"UPDATE not_a_table SET " + TestDb.EmployeeTable.NAME + " = ?", "Zach");
fail();
} catch (SQLException ignored) {
}
o.assertNoMoreEvents();
}

@Test public void transactionOnlyNotifiesOnce() {
db.createQuery(TABLE_EMPLOYEE, SELECT_EMPLOYEES).subscribe(o);
o.assertCursor()
Expand Down
60 changes: 60 additions & 0 deletions sqlbrite/src/main/java/com/squareup/sqlbrite/BriteDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,66 @@ public int update(@NonNull String table, @NonNull ContentValues values,
return rows;
}

/**
* Execute {@code sql} provided it is NOT a {@code SELECT} or any other SQL statement that
* returns data. No data can be returned (such as the number of affected rows). Instead, use
* {@link #insert}, {@link #update}, et al, when possible.
* <p>
* No notifications will be sent to queries if {@code sql} affects the data of a table.
*
* @see SQLiteDatabase#execSQL(String)
*/
public void execute(String sql) {
SQLiteDatabase db = getWriteableDatabase();
db.execSQL(sql);
}

/**
* Execute {@code sql} provided it is NOT a {@code SELECT} or any other SQL statement that
* returns data. No data can be returned (such as the number of affected rows). Instead, use
* {@link #insert}, {@link #update}, et al, when possible.
* <p>
* No notifications will be sent to queries if {@code sql} affects the data of a table.
*
* @see SQLiteDatabase#execSQL(String, Object[])
*/
public void execute(String sql, Object... args) {
SQLiteDatabase db = getWriteableDatabase();
db.execSQL(sql, args);
}

/**
* Execute {@code sql} provided it is NOT a {@code SELECT} or any other SQL statement that
* returns data. No data can be returned (such as the number of affected rows). Instead, use
* {@link #insert}, {@link #update}, et al, when possible.
* <p>
* A notification to queries for {@code table} will be sent after the statement is executed.
*
* @see SQLiteDatabase#execSQL(String)
*/
public void executeAndTrigger(String table, String sql) {
SQLiteDatabase db = getWriteableDatabase();
db.execSQL(sql);

sendTableTrigger(Collections.singleton(table));
}

/**
* Execute {@code sql} provided it is NOT a {@code SELECT} or any other SQL statement that
* returns data. No data can be returned (such as the number of affected rows). Instead, use
* {@link #insert}, {@link #update}, et al, when possible.
* <p>
* A notification to queries for {@code table} will be sent after the statement is executed.
*
* @see SQLiteDatabase#execSQL(String, Object[])
*/
public void executeAndTrigger(String table, String sql, Object... args) {
SQLiteDatabase db = getWriteableDatabase();
db.execSQL(sql, args);

sendTableTrigger(Collections.singleton(table));
}

/** An in-progress database transaction. */
public interface Transaction extends Closeable {
/**
Expand Down

0 comments on commit 02b66a1

Please sign in to comment.