/** * Execute a statement that returns a 1x1 long result. If you know your result set will only have one row and * column, this is much more efficient than calling {@link #rawQuery(String, Object[])} and parsing the cursor. * <br> * Note: This will throw an exception if the given SQL query returns a result that is not a single column * * @param query a sql query * @return the long result of the query */ public long simpleQueryForLong(Query query) { CompiledStatement compiled = query.compile(getCompileContext()); return simpleQueryForLong(compiled.sql, compiled.sqlArgs); }
/** * Execute a statement that returns a 1x1 String result. If you know your result set will only have one row and * column, this is much more efficient than calling {@link #rawQuery(String, Object[])} and parsing the cursor. * <br> * Note: This will throw an exception if the given SQL query returns a result that is not a single column * * @param query a sql query * @return the String result of the query */ public String simpleQueryForString(Query query) { CompiledStatement compiled = query.compile(getCompileContext()); return simpleQueryForString(compiled.sql, compiled.sqlArgs); }
/** * Directly analogous to {@link #query(Class, Query)}, but instead of returning a result, this method just logs the * output of EXPLAIN QUERY PLAN for the given query. This is method is intended for debugging purposes only. */ public void explainQueryPlan(Class<? extends AbstractModel> modelClass, Query query) { query = inferTableForQuery(modelClass, query); CompiledStatement compiled = query.compile(getCompileContext()); ICursor cursor = rawQuery("EXPLAIN QUERY PLAN " + compiled.sql, compiled.sqlArgs); try { Logger.d(Logger.LOG_TAG, "Query plan for: " + compiled.sql); SquidUtilities.dumpCursor(cursor, -1); } finally { cursor.close(); } }
/** * Query the database * * @param modelClass the type to parameterize the cursor by. If the query does not contain a FROM clause, the table * or view corresponding to this model class will be used. * @param query the query to execute * @return a {@link SquidCursor} containing the query results */ public <TYPE extends AbstractModel> SquidCursor<TYPE> query(Class<TYPE> modelClass, Query query) { query = inferTableForQuery(modelClass, query); CompiledStatement compiled = query.compile(getCompileContext()); if (compiled.needsValidation) { String validateSql = query.sqlForValidation(getCompileContext()); ensureSqlCompiles(validateSql); // throws if the statement fails to compile } ICursor cursor = rawQuery(compiled.sql, compiled.sqlArgs); return new SquidCursor<>(cursor, modelClass, query.getFields()); }
/** * Count the number of rows matching a given {@link Criterion}. Use null to count all rows. * * @param modelClass the model class corresponding to the table * @param criterion the criterion to match * @return the number of rows matching the given criterion */ public int count(Class<? extends AbstractModel> modelClass, Criterion criterion) { Property.IntegerProperty countProperty = Property.IntegerProperty.countProperty(); Query query = Query.select(countProperty); if (criterion != null) { query.where(criterion); } query = inferTableForQuery(modelClass, query); CompiledStatement compiled = query.compile(getCompileContext()); acquireNonExclusiveLock(); try { return (int) getDatabase().simpleQueryForLong(compiled.sql, compiled.sqlArgs); } finally { releaseNonExclusiveLock(); } }
public void testDatabaseProvidedArgumentResolver() { database.useCustomArgumentBinder = true; Query query = Query.select(TestModel.SOME_ENUM).from(TestModel.TABLE) .where(TestModel.SOME_ENUM.eq(TestEnum.APPLE)); CompiledStatement compiledStatement = query.compile(database.getCompileContext()); verifyCompiledSqlArgs(compiledStatement, 1, 0); }
public void testEnumResolvedUsingName() { Query query = Query.select(TestModel.SOME_ENUM).from(TestModel.TABLE) .where(TestModel.SOME_ENUM.eq(TestEnum.APPLE)); CompiledStatement compiledStatement = query.compile(database.getCompileContext()); verifyCompiledSqlArgs(compiledStatement, 1, "APPLE"); }
if (tableOrView instanceof SubqueryTable) { expectedSql.append("("); String compiledSql = ((SubqueryTable) tableOrView).query.compile(database.getCompileContext()).sql; expectedSql.append(compiledSql).append(") AS testModelAlias"); } else { expectedSql.append(tableOrView.getName()).append(" AS testModelAlias"); assertEquals(expectedSql.toString(), query.compile(database.getCompileContext()).sql);
public void testNeedsValidationUpdatedBySubqueryTable() { Query subquery = Query.select(Thing.PROPERTIES).from(Thing.TABLE).where(Criterion.literal(123)); subquery.requestValidation(); assertTrue(subquery.compile(database.getCompileContext()).sql.contains("WHERE (?)")); Query baseTestQuery = Query.select().from(Thing.TABLE).where(Thing.FOO.isNotEmpty()).freeze(); assertFalse(baseTestQuery.needsValidation()); Query testQuery = baseTestQuery.from(subquery.as("t1")); assertTrue(testQuery.compile(database.getCompileContext()).needsValidation); assertTrue(testQuery.sqlForValidation(database.getCompileContext()).contains("WHERE ((?))")); testQuery = baseTestQuery.innerJoin(subquery.as("t2"), (Criterion[]) null); assertTrue(testQuery.compile(database.getCompileContext()).needsValidation); assertTrue(testQuery.sqlForValidation(database.getCompileContext()).contains("WHERE ((?))")); testQuery = baseTestQuery.union(subquery); assertTrue(testQuery.compile(database.getCompileContext()).needsValidation); assertTrue(testQuery.sqlForValidation(database.getCompileContext()).contains("WHERE ((?))")); }
public void testNeedsValidationUpdatedByQueryFunction() { Query subquery = Query.select(Function.max(Thing.ID)).from(Thing.TABLE).where(Criterion.literal(123)); subquery.requestValidation(); assertTrue(subquery.compile(database.getCompileContext()).sql.contains("WHERE (?)")); Query baseTestQuery = Query.select().from(Thing.TABLE).where(Thing.FOO.isNotEmpty()).freeze(); assertFalse(baseTestQuery.needsValidation()); Query testQuery = baseTestQuery.selectMore(subquery.asFunction()); assertTrue(testQuery.compile(database.getCompileContext()).needsValidation); assertTrue(testQuery.sqlForValidation(database.getCompileContext()).contains("WHERE ((?))")); }
public void testSelectionArgsGeneration() { Query query = Query.select(TestModel.PROPERTIES) .where(TestModel.FIRST_NAME.eq("Sam") .and(TestModel.BIRTHDAY.gt(17)) .and(TestModel.LAST_NAME.neq("Smith"))); CompiledStatement compiledQuery = query.compile(database.getCompileContext()); verifyCompiledSqlArgs(compiledQuery, 3, "Sam", 17, "Smith"); }
public void testValidationPropagatesToSubqueryJoinAndCompoundSelect() { Query subquery = Query.select(Thing.FOO).from(Thing.TABLE).where(Thing.BAR.gt(0)); Query joinSubquery = Query.select(Thing.BAR).from(Thing.TABLE).where(Thing.FOO.isNotEmpty()); Query compoundSubquery = Query.select(Thing.BAZ).from(Thing.TABLE).where(Thing.IS_ALIVE.isTrue()); SubqueryTable subqueryTable = subquery.as("t1"); SubqueryTable joinTable = joinSubquery.as("t2"); Query query = Query.select().from(subqueryTable).innerJoin(joinTable, (Criterion[]) null) .union(compoundSubquery); final int queryLength = query.compile(database.getCompileContext()).sql.length(); String withValidation = query.sqlForValidation(database.getCompileContext()); assertEquals(queryLength + 6, withValidation.length()); }
/** * Execute a statement that returns a 1x1 String result. If you know your result set will only have one row and * column, this is much more efficient than calling {@link #rawQuery(String, Object[])} and parsing the cursor. * <br> * Note: This will throw an exception if the given SQL query returns a result that is not a single column * * @param query a sql query * @return the String result of the query */ public String simpleQueryForString(Query query) { CompiledStatement compiled = query.compile(getCompileContext()); return simpleQueryForString(compiled.sql, compiled.sqlArgs); }
public void testRawSelection() { String selection = COL_LUCKY_NUMBER + " > ? AND " + COL_IS_HAPPY + " != ?"; String[] selectionArgs = new String[]{"50", "0"}; ContentProviderQueryBuilder builder = getBuilder(); Query query = builder.setDataSource(TestModel.TABLE).build(null, selection, selectionArgs, null); CompiledStatement compiled = query.compile(database.getCompileContext()); verifyCompiledSqlArgs(compiled, 2, "50", "0"); SquidCursor<TestModel> cursor = null; try { cursor = database.query(TestModel.class, query); assertEquals(1, cursor.getCount()); cursor.moveToFirst(); assertEquals(model2, buildModelFromCursor(cursor)); } finally { if (cursor != null) { cursor.close(); } } }
/** * Execute a statement that returns a 1x1 long result. If you know your result set will only have one row and * column, this is much more efficient than calling {@link #rawQuery(String, Object[])} and parsing the cursor. * <br> * Note: This will throw an exception if the given SQL query returns a result that is not a single column * * @param query a sql query * @return the long result of the query */ public long simpleQueryForLong(Query query) { CompiledStatement compiled = query.compile(getCompileContext()); return simpleQueryForLong(compiled.sql, compiled.sqlArgs); }
public void testRawOrderBy() { String sortOrder = COL_GIVEN_NAME + " ASC"; ContentProviderQueryBuilder builder = getBuilder(); Query query = builder.setDataSource(TestModel.TABLE).build(null, null, null, sortOrder); CompiledStatement compiled = query.compile(database.getCompileContext()); verifyCompiledSqlArgs(compiled, 0); SquidCursor<TestModel> cursor = null; try { cursor = database.query(TestModel.class, query); assertEquals(3, cursor.getCount()); cursor.moveToFirst(); assertEquals(model3, buildModelFromCursor(cursor)); cursor.moveToNext(); assertEquals(model2, buildModelFromCursor(cursor)); cursor.moveToNext(); assertEquals(model1, buildModelFromCursor(cursor)); } finally { if (cursor != null) { cursor.close(); } } }
public void testDefaultOrderBy() { ContentProviderQueryBuilder builder = getBuilder(); builder.setDefaultOrder(TestModel.LUCKY_NUMBER.desc()); Query query = builder.setDataSource(TestModel.TABLE).build(null, null, null, null); CompiledStatement compiled = query.compile(database.getCompileContext()); verifyCompiledSqlArgs(compiled, 0); SquidCursor<TestModel> cursor = null; try { cursor = database.query(TestModel.class, query); assertEquals(3, cursor.getCount()); cursor.moveToFirst(); assertEquals(model2, buildModelFromCursor(cursor)); cursor.moveToNext(); assertEquals(model1, buildModelFromCursor(cursor)); cursor.moveToNext(); assertEquals(model3, buildModelFromCursor(cursor)); } finally { if (cursor != null) { cursor.close(); } } }
/** * Directly analogous to {@link #query(Class, Query)}, but instead of returning a result, this method just logs the * output of EXPLAIN QUERY PLAN for the given query. This is method is intended for debugging purposes only. */ public void explainQueryPlan(Class<? extends AbstractModel> modelClass, Query query) { query = inferTableForQuery(modelClass, query); CompiledStatement compiled = query.compile(getCompileContext()); ICursor cursor = rawQuery("EXPLAIN QUERY PLAN " + compiled.sql, compiled.sqlArgs); try { Logger.d(Logger.LOG_TAG, "Query plan for: " + compiled.sql); SquidUtilities.dumpCursor(cursor, -1); } finally { cursor.close(); } }
/** * Query the database * * @param modelClass the type to parameterize the cursor by. If the query does not contain a FROM clause, the table * or view corresponding to this model class will be used. * @param query the query to execute * @return a {@link SquidCursor} containing the query results */ public <TYPE extends AbstractModel> SquidCursor<TYPE> query(Class<TYPE> modelClass, Query query) { query = inferTableForQuery(modelClass, query); CompiledStatement compiled = query.compile(getCompileContext()); if (compiled.needsValidation) { String validateSql = query.sqlForValidation(getCompileContext()); ensureSqlCompiles(validateSql); // throws if the statement fails to compile } ICursor cursor = rawQuery(compiled.sql, compiled.sqlArgs); return new SquidCursor<>(cursor, modelClass, query.getFields()); }
/** * Count the number of rows matching a given {@link Criterion}. Use null to count all rows. * * @param modelClass the model class corresponding to the table * @param criterion the criterion to match * @return the number of rows matching the given criterion */ public int count(Class<? extends AbstractModel> modelClass, Criterion criterion) { Property.IntegerProperty countProperty = Property.IntegerProperty.countProperty(); Query query = Query.select(countProperty); if (criterion != null) { query.where(criterion); } query = inferTableForQuery(modelClass, query); CompiledStatement compiled = query.compile(getCompileContext()); acquireNonExclusiveLock(); try { return (int) getDatabase().simpleQueryForLong(compiled.sql, compiled.sqlArgs); } finally { releaseNonExclusiveLock(); } }