mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 09:20:19 +01:00
Implement donation receipts.
This commit is contained in:
committed by
Greyson Parrelli
parent
63dab3f4b0
commit
7b499f96be
@@ -0,0 +1,95 @@
|
||||
package org.thoughtcrime.securesms.database
|
||||
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import androidx.core.content.contentValuesOf
|
||||
import org.signal.core.util.money.FiatMoney
|
||||
import org.thoughtcrime.securesms.database.model.DonationReceiptRecord
|
||||
import org.thoughtcrime.securesms.util.CursorUtil
|
||||
import org.thoughtcrime.securesms.util.SqlUtil
|
||||
import java.math.BigDecimal
|
||||
import java.util.Currency
|
||||
|
||||
class DonationReceiptDatabase(context: Context, databaseHelper: SignalDatabase) : Database(context, databaseHelper) {
|
||||
companion object {
|
||||
private const val TABLE_NAME = "donation_receipt"
|
||||
|
||||
private const val ID = "_id"
|
||||
private const val TYPE = "receipt_type"
|
||||
private const val DATE = "receipt_date"
|
||||
private const val AMOUNT = "amount"
|
||||
private const val CURRENCY = "currency"
|
||||
private const val SUBSCRIPTION_LEVEL = "subscription_level"
|
||||
|
||||
@JvmField
|
||||
val CREATE_TABLE = """
|
||||
CREATE TABLE $TABLE_NAME (
|
||||
$ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
$TYPE TEXT NOT NULL,
|
||||
$DATE INTEGER NOT NULL,
|
||||
$AMOUNT TEXT NOT NULL,
|
||||
$CURRENCY TEXT NOT NULL,
|
||||
$SUBSCRIPTION_LEVEL INTEGER NOT NULL
|
||||
)
|
||||
""".trimIndent()
|
||||
|
||||
val CREATE_INDEXS = arrayOf(
|
||||
"CREATE INDEX IF NOT EXISTS donation_receipt_type_index ON $TABLE_NAME ($TYPE)",
|
||||
"CREATE INDEX IF NOT EXISTS donation_receipt_date_index ON $TABLE_NAME ($DATE)"
|
||||
)
|
||||
}
|
||||
|
||||
fun addReceipt(record: DonationReceiptRecord) {
|
||||
require(record.id == -1L)
|
||||
|
||||
val values = contentValuesOf(
|
||||
AMOUNT to record.amount.amount.toString(),
|
||||
CURRENCY to record.amount.currency.currencyCode,
|
||||
DATE to record.timestamp,
|
||||
TYPE to record.type.code,
|
||||
SUBSCRIPTION_LEVEL to record.subscriptionLevel
|
||||
)
|
||||
|
||||
writableDatabase.insert(TABLE_NAME, null, values)
|
||||
}
|
||||
|
||||
fun getReceipt(id: Long): DonationReceiptRecord? {
|
||||
readableDatabase.query(TABLE_NAME, null, ID_WHERE, SqlUtil.buildArgs(id), null, null, null).use { cursor ->
|
||||
return if (cursor.moveToNext()) {
|
||||
readRecord(cursor)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getReceipts(type: DonationReceiptRecord.Type?): List<DonationReceiptRecord> {
|
||||
val (where, whereArgs) = if (type != null) {
|
||||
"$TYPE = ?" to SqlUtil.buildArgs(type.code)
|
||||
} else {
|
||||
null to null
|
||||
}
|
||||
|
||||
readableDatabase.query(TABLE_NAME, null, where, whereArgs, null, null, "$DATE DESC").use { cursor ->
|
||||
val results = ArrayList<DonationReceiptRecord>(cursor.count)
|
||||
while (cursor.moveToNext()) {
|
||||
results.add(readRecord(cursor))
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
}
|
||||
|
||||
private fun readRecord(cursor: Cursor): DonationReceiptRecord {
|
||||
return DonationReceiptRecord(
|
||||
id = CursorUtil.requireLong(cursor, ID),
|
||||
type = DonationReceiptRecord.Type.fromCode(CursorUtil.requireString(cursor, TYPE)),
|
||||
amount = FiatMoney(
|
||||
BigDecimal(CursorUtil.requireString(cursor, AMOUNT)),
|
||||
Currency.getInstance(CursorUtil.requireString(cursor, CURRENCY))
|
||||
),
|
||||
timestamp = CursorUtil.requireLong(cursor, DATE),
|
||||
subscriptionLevel = CursorUtil.requireInt(cursor, SUBSCRIPTION_LEVEL)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -71,6 +71,7 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
|
||||
val groupCallRingDatabase: GroupCallRingDatabase = GroupCallRingDatabase(context, this)
|
||||
val reactionDatabase: ReactionDatabase = ReactionDatabase(context, this)
|
||||
val notificationProfileDatabase: NotificationProfileDatabase = NotificationProfileDatabase(context, this)
|
||||
val donationReceiptDatabase: DonationReceiptDatabase = DonationReceiptDatabase(context, this)
|
||||
|
||||
override fun onOpen(db: net.zetetic.database.sqlcipher.SQLiteDatabase) {
|
||||
db.enableWriteAheadLogging()
|
||||
@@ -103,6 +104,7 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
|
||||
db.execSQL(AvatarPickerDatabase.CREATE_TABLE)
|
||||
db.execSQL(GroupCallRingDatabase.CREATE_TABLE)
|
||||
db.execSQL(ReactionDatabase.CREATE_TABLE)
|
||||
db.execSQL(DonationReceiptDatabase.CREATE_TABLE)
|
||||
executeStatements(db, SearchDatabase.CREATE_TABLE)
|
||||
executeStatements(db, RemappedRecordsDatabase.CREATE_TABLE)
|
||||
executeStatements(db, MessageSendLogDatabase.CREATE_TABLE)
|
||||
@@ -123,6 +125,7 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
|
||||
executeStatements(db, MessageSendLogDatabase.CREATE_INDEXES)
|
||||
executeStatements(db, GroupCallRingDatabase.CREATE_INDEXES)
|
||||
executeStatements(db, NotificationProfileDatabase.CREATE_INDEXES)
|
||||
executeStatements(db, DonationReceiptDatabase.CREATE_INDEXS)
|
||||
|
||||
executeStatements(db, MessageSendLogDatabase.CREATE_TRIGGERS)
|
||||
executeStatements(db, ReactionDatabase.CREATE_TRIGGERS)
|
||||
@@ -466,5 +469,10 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
|
||||
@get:JvmName("notificationProfiles")
|
||||
val notificationProfiles: NotificationProfileDatabase
|
||||
get() = instance!!.notificationProfileDatabase
|
||||
|
||||
@get:JvmStatic
|
||||
@get:JvmName("donationReceipts")
|
||||
val donationReceipts: DonationReceiptDatabase
|
||||
get() = instance!!.donationReceiptDatabase
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,9 +48,6 @@ import java.io.ByteArrayInputStream
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.IOException
|
||||
import java.lang.AssertionError
|
||||
import java.util.ArrayList
|
||||
import java.util.HashSet
|
||||
import java.util.LinkedList
|
||||
import java.util.Locale
|
||||
|
||||
@@ -190,8 +187,9 @@ object SignalDatabaseMigrations {
|
||||
private const val MESSAGE_RANGES = 128
|
||||
private const val REACTION_TRIGGER_FIX = 129
|
||||
private const val PNI_STORES = 130
|
||||
private const val DONATION_RECEIPTS = 131
|
||||
|
||||
const val DATABASE_VERSION = 130
|
||||
const val DATABASE_VERSION = 131
|
||||
|
||||
@JvmStatic
|
||||
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
@@ -2397,6 +2395,25 @@ object SignalDatabaseMigrations {
|
||||
db.execSQL("DROP TABLE sessions")
|
||||
db.execSQL("ALTER TABLE sessions_tmp RENAME TO sessions")
|
||||
}
|
||||
|
||||
if (oldVersion < DONATION_RECEIPTS) {
|
||||
db.execSQL(
|
||||
// language=sql
|
||||
"""
|
||||
CREATE TABLE donation_receipt (
|
||||
_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
receipt_type TEXT NOT NULL,
|
||||
receipt_date INTEGER NOT NULL,
|
||||
amount TEXT NOT NULL,
|
||||
currency TEXT NOT NULL,
|
||||
subscription_level INTEGER NOT NULL
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
db.execSQL("CREATE INDEX IF NOT EXISTS donation_receipt_type_index ON donation_receipt (receipt_type);")
|
||||
db.execSQL("CREATE INDEX IF NOT EXISTS donation_receipt_date_index ON donation_receipt (receipt_date);")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.thoughtcrime.securesms.database.model
|
||||
|
||||
import org.signal.core.util.money.FiatMoney
|
||||
import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription
|
||||
import java.util.Currency
|
||||
|
||||
data class DonationReceiptRecord(
|
||||
val id: Long = -1L,
|
||||
val amount: FiatMoney,
|
||||
val timestamp: Long,
|
||||
val type: Type,
|
||||
val subscriptionLevel: Int
|
||||
) {
|
||||
enum class Type(val code: String) {
|
||||
RECURRING("recurring"),
|
||||
BOOST("boost");
|
||||
|
||||
companion object {
|
||||
fun fromCode(code: String): Type {
|
||||
return values().first { it.code == code }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun createForSubscription(subscription: ActiveSubscription.Subscription): DonationReceiptRecord {
|
||||
val activeCurrency = Currency.getInstance(subscription.currency)
|
||||
val activeAmount = subscription.amount.movePointLeft(activeCurrency.defaultFractionDigits)
|
||||
|
||||
return DonationReceiptRecord(
|
||||
id = -1L,
|
||||
amount = FiatMoney(activeAmount, activeCurrency),
|
||||
timestamp = System.currentTimeMillis(),
|
||||
subscriptionLevel = subscription.level,
|
||||
type = Type.RECURRING
|
||||
)
|
||||
}
|
||||
|
||||
fun createForBoost(amount: FiatMoney): DonationReceiptRecord {
|
||||
return DonationReceiptRecord(
|
||||
id = -1L,
|
||||
amount = amount,
|
||||
timestamp = System.currentTimeMillis(),
|
||||
subscriptionLevel = -1,
|
||||
type = Type.BOOST
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user