code cleanup

This commit is contained in:
Mariotaku Lee 2017-04-20 21:32:39 +08:00
parent fd93a03576
commit 9117f5d6d5
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
5 changed files with 149 additions and 164 deletions

View File

@ -1,149 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.util.database;
import org.mariotaku.sqliteqb.library.Columns;
import org.mariotaku.sqliteqb.library.Expression;
import org.mariotaku.sqliteqb.library.Join;
import org.mariotaku.sqliteqb.library.OrderBy;
import org.mariotaku.sqliteqb.library.Selectable;
import org.mariotaku.sqliteqb.library.Table;
import org.mariotaku.sqliteqb.library.Tables;
import org.mariotaku.sqliteqb.library.query.SQLSelectQuery;
import org.mariotaku.twidere.model.UserKey;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships;
import org.mariotaku.twidere.util.TwidereArrayUtils;
import org.mariotaku.twidere.util.Utils;
import java.util.Locale;
import kotlin.Pair;
/**
* Created by mariotaku on 2017/2/17.
*/
public final class CachedUsersQueryBuilder {
private CachedUsersQueryBuilder() {
}
public static Pair<SQLSelectQuery, String[]> withRelationship(final String[] projection,
final String selection,
final String[] selectionArgs,
final String sortOrder,
final UserKey accountKey) {
return withRelationship(Utils.INSTANCE.getColumnsFromProjection(projection), selection,
selectionArgs, sortOrder, accountKey);
}
public static Pair<SQLSelectQuery, String[]> withRelationship(final Selectable select,
final String selection,
final String[] selectionArgs,
final String sortOrder,
final UserKey accountKey) {
final SQLSelectQuery.Builder qb = new SQLSelectQuery.Builder();
qb.select(select).from(new Tables(TwidereDataStore.CachedUsers.TABLE_NAME));
final Columns.Column relationshipsUserKey = new Columns.Column(new Table(CachedRelationships.TABLE_NAME),
CachedRelationships.USER_KEY);
final Columns.Column usersUserKey = new Columns.Column(new Table(TwidereDataStore.CachedUsers.TABLE_NAME),
CachedRelationships.USER_KEY);
final Columns.Column relationshipsAccountKey = new Columns.Column(new Table(CachedRelationships.TABLE_NAME),
CachedRelationships.ACCOUNT_KEY);
final Expression on = Expression.and(
Expression.equals(relationshipsUserKey, usersUserKey),
Expression.equalsArgs(relationshipsAccountKey.getSQL())
);
qb.join(new Join(false, Join.Operation.LEFT, new Table(CachedRelationships.TABLE_NAME), on));
final Expression userTypeExpression;
final String host = accountKey.getHost();
final String[] accountKeyArgs;
if (host == null) {
userTypeExpression = Expression.notLikeRaw(new Columns.Column(new Table(TwidereDataStore.CachedUsers.TABLE_NAME),
TwidereDataStore.CachedUsers.USER_KEY), "'%@%'");
accountKeyArgs = new String[]{accountKey.toString()};
} else {
userTypeExpression = Expression.likeRaw(new Columns.Column(new Table(TwidereDataStore.CachedUsers.TABLE_NAME),
TwidereDataStore.CachedUsers.USER_KEY), "'%@'||?");
accountKeyArgs = new String[]{accountKey.toString(), host};
}
if (selection != null) {
qb.where(Expression.and(userTypeExpression, new Expression(selection)));
} else {
qb.where(userTypeExpression);
}
if (sortOrder != null) {
qb.orderBy(new OrderBy(sortOrder));
}
final String[] mergedArgs = new String[TwidereArrayUtils.arraysLength(accountKeyArgs, selectionArgs)];
TwidereArrayUtils.mergeArray(mergedArgs, accountKeyArgs, selectionArgs);
return new Pair<>(qb.build(), mergedArgs);
}
public static Pair<SQLSelectQuery, String[]> withScore(final String[] projection,
final String selection,
final String[] selectionArgs,
final String sortOrder,
final UserKey accountKey,
final int limit) {
final SQLSelectQuery.Builder qb = new SQLSelectQuery.Builder();
final Selectable select = Utils.INSTANCE.getColumnsFromProjection(projection);
final Columns.Column[] columns = new Columns.Column[TwidereDataStore.CachedUsers.COLUMNS.length + 1];
for (int i = 0, j = columns.length - 1; i < j; i++) {
final String column = TwidereDataStore.CachedUsers.COLUMNS[i];
if (TwidereDataStore.CachedUsers._ID.equals(column) || TwidereDataStore.CachedUsers.USER_KEY.equals(column)) {
columns[i] = new Columns.Column(new Table(TwidereDataStore.CachedUsers.TABLE_NAME), column, column);
} else {
columns[i] = new Columns.Column(column);
}
}
final String expr = String.format(Locale.ROOT, "%s * 100 + %s * 50 + %s * 50 - %s * 100 - %s * 100 - %s * 100",
valueOrZero(CachedRelationships.FOLLOWING, CachedRelationships.NOTIFICATIONS_ENABLED,
CachedRelationships.FOLLOWED_BY, CachedRelationships.BLOCKING,
CachedRelationships.BLOCKED_BY, CachedRelationships.MUTING));
columns[columns.length - 1] = new Columns.Column(expr, "score");
qb.select(select);
final Pair<SQLSelectQuery, String[]> pair = withRelationship(new Columns(columns), null,
null, null, accountKey);
qb.from(pair.getFirst());
final String[] mergedArgs = new String[TwidereArrayUtils.arraysLength(pair.getSecond(), selectionArgs)];
TwidereArrayUtils.mergeArray(mergedArgs, pair.getSecond(), selectionArgs);
if (selection != null) {
qb.where(new Expression(selection));
}
if (sortOrder != null) {
qb.orderBy(new OrderBy(sortOrder));
}
if (limit > 0) {
qb.limit(limit);
}
return new Pair<>(qb.build(), mergedArgs);
}
private static Object[] valueOrZero(String... columns) {
final String[] result = new String[columns.length];
for (int i = 0, j = columns.length; i < j; i++) {
result[i] = String.format(Locale.ROOT, "CASE WHEN %s IS NULL THEN 0 ELSE %s END",
columns[i], columns[i]);
}
return result;
}
}

View File

@ -1,7 +1,7 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -248,7 +248,7 @@ object Utils {
}
fun getColumnsFromProjection(vararg projection: String): Selectable {
fun getColumnsFromProjection(projection: Array<String>?): Selectable {
if (projection == null) return AllColumns()
val length = projection.size
val columns = arrayOfNulls<Column>(length)

View File

@ -0,0 +1,134 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.util.database
import org.mariotaku.ktextension.mapToArray
import org.mariotaku.sqliteqb.library.*
import org.mariotaku.sqliteqb.library.query.SQLSelectQuery
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
import org.mariotaku.twidere.util.Utils
/**
* Created by mariotaku on 2017/2/17.
*/
object CachedUsersQueryBuilder {
val scoreExpr = "${valueOrZero(CachedRelationships.FOLLOWING)} * 100 + " +
"${valueOrZero(CachedRelationships.NOTIFICATIONS_ENABLED)} * 50 + " +
"${valueOrZero(CachedRelationships.FOLLOWED_BY)} * 50 - " +
"${valueOrZero(CachedRelationships.BLOCKING)} * 100 - " +
"${valueOrZero(CachedRelationships.BLOCKED_BY)} * 100 - " +
"${valueOrZero(CachedRelationships.MUTING)} * 100"
fun withRelationship(projection: Array<String>?,
selection: String?,
selectionArgs: Array<String>?,
sortOrder: String?,
accountKey: UserKey): Pair<SQLSelectQuery, Array<String>> {
return withRelationship(Utils.getColumnsFromProjection(projection), selection,
selectionArgs, sortOrder, accountKey)
}
fun withRelationship(select: Selectable,
selection: String?,
selectionArgs: Array<String>?,
sortOrder: String?,
accountKey: UserKey): Pair<SQLSelectQuery, Array<String>> {
val qb = SQLSelectQuery.Builder()
qb.select(select).from(Tables(CachedUsers.TABLE_NAME))
val relationshipsUserKey = Columns.Column(Table(CachedRelationships.TABLE_NAME),
CachedRelationships.USER_KEY)
val usersUserKey = Columns.Column(Table(CachedUsers.TABLE_NAME),
CachedRelationships.USER_KEY)
val relationshipsAccountKey = Columns.Column(Table(CachedRelationships.TABLE_NAME),
CachedRelationships.ACCOUNT_KEY)
val on = Expression.and(
Expression.equals(relationshipsUserKey, usersUserKey),
Expression.equalsArgs(relationshipsAccountKey.sql)
)
qb.join(Join(false, Join.Operation.LEFT, Table(CachedRelationships.TABLE_NAME), on))
val userTypeExpression: Expression
val host = accountKey.host
val accountKeyArgs: Array<String>
if (host == null) {
userTypeExpression = Expression.notLikeRaw(Columns.Column(Table(CachedUsers.TABLE_NAME),
CachedUsers.USER_KEY), "'%@%'")
accountKeyArgs = arrayOf(accountKey.toString())
} else {
userTypeExpression = Expression.likeRaw(Columns.Column(Table(CachedUsers.TABLE_NAME),
CachedUsers.USER_KEY), "'%@'||?")
accountKeyArgs = arrayOf(accountKey.toString(), host)
}
if (selection != null) {
qb.where(Expression.and(userTypeExpression, Expression(selection)))
} else {
qb.where(userTypeExpression)
}
if (sortOrder != null) {
qb.orderBy(OrderBy(sortOrder))
}
val mergedArgs = if (selectionArgs != null) {
accountKeyArgs + selectionArgs
} else {
accountKeyArgs
}
return Pair<SQLSelectQuery, Array<String>>(qb.build(), mergedArgs)
}
fun withScore(projection: Array<String>?,
selection: String?,
selectionArgs: Array<String>?,
sortOrder: String?,
accountKey: UserKey,
limit: Int): Pair<SQLSelectQuery, Array<String>> {
val qb = SQLSelectQuery.Builder()
val select = Utils.getColumnsFromProjection(projection)
val columns = CachedUsers.COLUMNS.mapToArray { column ->
if (CachedUsers._ID == column || CachedUsers.USER_KEY == column) {
return@mapToArray Columns.Column(Table(CachedUsers.TABLE_NAME), column, column)
} else {
return@mapToArray Columns.Column(column)
}
} + Columns.Column(scoreExpr, "score")
qb.select(select)
val pair = withRelationship(Columns(*columns), null, null, null, accountKey)
qb.from(pair.first)
val mergedArgs = if (selectionArgs != null) {
pair.second + selectionArgs
} else {
pair.second
}
if (selection != null) {
qb.where(Expression(selection))
}
if (sortOrder != null) {
qb.orderBy(OrderBy(sortOrder))
}
if (limit > 0) {
qb.limit(limit)
}
return Pair<SQLSelectQuery, Array<String>>(qb.build(), mergedArgs)
}
private fun valueOrZero(column: String): String = "CASE WHEN $column IS NULL THEN 0 ELSE $column END"
}

View File

@ -134,7 +134,7 @@ object SuggestionsCursorCreator {
val whereArgs = nicknameKeys + queryEscaped + queryEscaped
val orderBy = arrayOf(CachedUsers.SCORE, CachedUsers.LAST_SEEN, CachedUsers.SCREEN_NAME, CachedUsers.NAME)
val ascending = booleanArrayOf(false, false, true, true)
val mappedProjection = nonNullProjection.mapToArray { autoCompleteUsersProjectionMap[it] }
val mappedProjection = nonNullProjection.mapToArray { autoCompleteUsersProjectionMap[it]!! }
val (sql, bindingArgs) = CachedUsersQueryBuilder.withScore(mappedProjection,
where.sql, whereArgs, OrderBy(orderBy, ascending).sql, accountKey, 0)
return db.rawQuery(sql.sql, bindingArgs)
@ -162,7 +162,7 @@ object SuggestionsCursorCreator {
val order = arrayOf(CachedUsers.LAST_SEEN, CachedUsers.SCORE, CachedUsers.SCREEN_NAME, CachedUsers.NAME)
val ascending = booleanArrayOf(false, false, true, true)
val orderBy = OrderBy(order, ascending)
val usersProjection = selection.mapToArray { suggestionUsersProjectionMap[it] }
val usersProjection = selection.mapToArray { suggestionUsersProjectionMap[it]!! }
val usersQuery = CachedUsersQueryBuilder.withScore(usersProjection,
usersSelection.sql, selectionArgs, orderBy.sql, accountKey, 0)
return db.rawQuery(usersQuery.first.sql, usersQuery.second)

View File

@ -1,7 +1,7 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -33,9 +33,9 @@ class SystemHosts {
@Throws(IOException::class)
fun resolve(hostToResolve: String): List<InetAddress> {
File(HOSTS_PATH).bufferedReader().use {
var line: String?
do {
line = it.readLine()
var line: String
while (true) {
line = it.readLine() ?: break
val scanner = Scanner(line)
if (!scanner.hasNext()) continue
val address = scanner.next()
@ -48,7 +48,7 @@ class SystemHosts {
return listOf(resolved)
}
}
} while (line != null)
}
}
throw UnknownHostException(hostToResolve)
}