137 lines
4.3 KiB
Kotlin
137 lines
4.3 KiB
Kotlin
package jp.juggler.subwaytooter.table
|
|
|
|
import android.content.ContentValues
|
|
import android.database.sqlite.SQLiteDatabase
|
|
import android.provider.BaseColumns
|
|
|
|
import java.util.ArrayList
|
|
|
|
import jp.juggler.subwaytooter.App1
|
|
import jp.juggler.util.ColumnMeta
|
|
import jp.juggler.util.LogCategory
|
|
import jp.juggler.util.TableCompanion
|
|
import jp.juggler.util.put
|
|
|
|
object AcctSet : TableCompanion {
|
|
|
|
private val log = LogCategory("AcctSet")
|
|
|
|
override val table = "acct_set"
|
|
|
|
val columnList: ColumnMeta.List = ColumnMeta.List(table, 7).apply {
|
|
ColumnMeta(this, 0, BaseColumns._ID, "INTEGER PRIMARY KEY", primary = true)
|
|
|
|
createExtra = {
|
|
arrayOf(
|
|
"create unique index if not exists ${table}_acct on $table($COL_ACCT)",
|
|
"create index if not exists ${table}_time on $table($COL_TIME_SAVE)",
|
|
)
|
|
}
|
|
}
|
|
private val COL_TIME_SAVE = ColumnMeta(columnList, 0, "time_save", "integer not null")
|
|
|
|
//@who@host ascii文字の大文字小文字は(sqliteにより)同一視される
|
|
private val COL_ACCT = ColumnMeta(columnList, 0, "acct", "text not null")
|
|
|
|
private val prefix_search_where = "$COL_ACCT like ? escape '$'"
|
|
|
|
private val prefix_search_where_arg = object : ThreadLocal<Array<String?>>() {
|
|
override fun initialValue(): Array<String?> {
|
|
return arrayOfNulls(1)
|
|
}
|
|
}
|
|
|
|
override fun onDBCreate(db: SQLiteDatabase) =
|
|
columnList.onDBCreate(db)
|
|
|
|
override fun onDBUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) =
|
|
columnList.onDBUpgrade(db, oldVersion, newVersion)
|
|
|
|
fun deleteOld(now: Long) {
|
|
try {
|
|
// 古いデータを掃除する
|
|
val expire = now - 86400000L * 365
|
|
App1.database.delete(table, "$COL_TIME_SAVE<?", arrayOf(expire.toString()))
|
|
} catch (ex: Throwable) {
|
|
log.e(ex, "deleteOld failed.")
|
|
}
|
|
}
|
|
|
|
fun saveList(now: Long, srcList: ArrayList<String?>, offset: Int, length: Int) {
|
|
|
|
try {
|
|
val cv = ContentValues()
|
|
cv.put(COL_TIME_SAVE, now)
|
|
|
|
var bOK = false
|
|
val db = App1.database
|
|
db.execSQL("BEGIN TRANSACTION")
|
|
try {
|
|
for (i in 0 until length) {
|
|
val acct = srcList[i + offset] ?: continue
|
|
cv.put(COL_ACCT, acct)
|
|
db.replace(table, null, cv)
|
|
}
|
|
bOK = true
|
|
} catch (ex: Throwable) {
|
|
log.trace(ex)
|
|
log.e(ex, "saveList failed.")
|
|
}
|
|
|
|
if (bOK) {
|
|
db.execSQL("COMMIT TRANSACTION")
|
|
} else {
|
|
db.execSQL("ROLLBACK TRANSACTION")
|
|
}
|
|
} catch (ex: Throwable) {
|
|
log.trace(ex)
|
|
log.e(ex, "saveList failed.")
|
|
}
|
|
}
|
|
|
|
private fun makePattern(src: String): String {
|
|
val sb = StringBuilder()
|
|
var i = 0
|
|
val ie = src.length
|
|
while (i < ie) {
|
|
val c = src[i]
|
|
if (c == '%' || c == '_' || c == '$') {
|
|
sb.append('$')
|
|
}
|
|
sb.append(c)
|
|
++i
|
|
}
|
|
// 前方一致検索にするため、末尾に%をつける
|
|
sb.append('%')
|
|
return sb.toString()
|
|
}
|
|
|
|
fun searchPrefix(prefix: String, limit: Int): ArrayList<CharSequence> {
|
|
try {
|
|
val where_arg = prefix_search_where_arg.get() ?: arrayOfNulls<String?>(1)
|
|
where_arg[0] = makePattern(prefix)
|
|
App1.database.query(
|
|
table,
|
|
null,
|
|
prefix_search_where,
|
|
where_arg,
|
|
null,
|
|
null,
|
|
"$COL_ACCT asc limit $limit"
|
|
).use { cursor ->
|
|
val dst = ArrayList<CharSequence>(cursor.count)
|
|
val idx_acct = COL_ACCT.getIndex(cursor)
|
|
while (cursor.moveToNext()) {
|
|
dst.add(cursor.getString(idx_acct))
|
|
}
|
|
return dst
|
|
}
|
|
} catch (ex: Throwable) {
|
|
log.trace(ex)
|
|
log.e(ex, "searchPrefix failed.")
|
|
}
|
|
|
|
return ArrayList()
|
|
}
|
|
}
|