Skip to content

Commit

Permalink
chore: (release-v2)2.3.0 #322
Browse files Browse the repository at this point in the history
chore: (release-v2)2.3.0
  • Loading branch information
itsdebs authored Oct 3, 2023
2 parents 5b6547f + edea37f commit edbf4bf
Show file tree
Hide file tree
Showing 30 changed files with 396 additions and 95 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rudderstack/rudder-sdk-android-monorepo",
"version": "2.2.0",
"version": "2.3.0",
"description": "Rudder Android SDK monorepo",
"keywords": [
"android",
Expand Down
15 changes: 9 additions & 6 deletions repository/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).

## 0.1.0 (2023-09-19)
## 0.2.1 (2023-10-04)

### Bug Fixes
* table not found in database. added locks ([#326](https://github.com/rudderlabs/rudder-sdk-android/issues/326)) ([1b5e670](https://github.com/rudderlabs/rudder-sdk-android/commit/1b5e670d5b10fe640099dc11353ae746ea6035b0))


## 0.2.0 (2023-09-19)


### Features
Expand All @@ -15,10 +21,7 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/s

* manual release + last minute fixes ([#275](https://github.com/rudderlabs/rudder-sdk-android/issues/275)) ([a52e9f7](https://github.com/rudderlabs/rudder-sdk-android/commit/a52e9f7567eb494a83ed6f57f6bd36017afaf39b)), closes [#256](https://github.com/rudderlabs/rudder-sdk-android/issues/256)

## 0.2.0 (2023-09-19)


### Features
## 0.1.0 (2023-08-01)

* error stats library implementation ([#307](https://github.com/rudderlabs/rudder-sdk-android/issues/307)) ([abc5a41](https://github.com/rudderlabs/rudder-sdk-android/commit/abc5a410affda77d99b731e645d38e18e6d05037)), closes [#271](https://github.com/rudderlabs/rudder-sdk-android/issues/271)
* metrics v2 ([#256](https://github.com/rudderlabs/rudder-sdk-android/issues/256)) ([c0b9639](https://github.com/rudderlabs/rudder-sdk-android/commit/c0b96397a14c5ff5baa3900804fd3b5b02d21304))
* Initial Repository
7 changes: 4 additions & 3 deletions repository/CHANGELOG_LATEST.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## 0.1.0 (2023-08-01)
## 0.2.1 (2023-10-03)


### Features
### Bug Fixes

* manual release + last minute fixes ([#275](https://github.com/rudderlabs/rudder-sdk-android/issues/275)) ([a52e9f7](https://github.com/rudderlabs/rudder-sdk-android/commit/a52e9f7567eb494a83ed6f57f6bd36017afaf39b)), closes [#256](https://github.com/rudderlabs/rudder-sdk-android/issues/256)

* metrics v2 ([#256](https://github.com/rudderlabs/rudder-sdk-android/issues/256)) ([c0b9639](https://github.com/rudderlabs/rudder-sdk-android/commit/c0b96397a14c5ff5baa3900804fd3b5b02d21304))
4 changes: 2 additions & 2 deletions repository/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ GROUP=com.rudderstack.android.sdk
POM_PACKAGING=aar
android.enableJetifier=true
android.useAndroidX=true
VERSION_CODE=2
VERSION_NAME=0.2.0
VERSION_CODE=3
VERSION_NAME=0.2.1
POM_NAME=ORM library by RudderStack for android
POM_DESCRIPTION=ORM library used in Rudderstack SDK Version 2 for android
4 changes: 2 additions & 2 deletions repository/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion repository/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "repository",
"version": "0.2.0",
"version": "0.2.1",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
Expand Down
2 changes: 1 addition & 1 deletion repository/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"github": {
"executor": "@jscutlery/semver:github",
"options": {
"tag": "[email protected].0",
"tag": "[email protected].1",
"notesFile": "./repository/CHANGELOG_LATEST.md"
}
},
Expand Down
104 changes: 65 additions & 39 deletions repository/src/main/java/com/rudderstack/android/repository/Dao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ import android.database.sqlite.SQLiteDatabase
import com.rudderstack.android.repository.annotation.RudderEntity
import com.rudderstack.android.repository.annotation.RudderField
import com.rudderstack.android.repository.utils.getInsertedRowIdForConflictIgnore
import java.util.concurrent.BlockingQueue
import java.util.concurrent.ExecutorService
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.ReentrantLock

/**
* Dao for accessing entities
Expand All @@ -33,7 +37,7 @@ import java.util.concurrent.ExecutorService
* @property executorService An executor service to run the database queries.
* TODO create separate objects for database and content provider
*/
class Dao<T : Entity> internal constructor(
class Dao<T : Entity>(
internal val entityClass: Class<T>,
private val useContentProvider: Boolean,
private val context: Context,
Expand All @@ -45,6 +49,9 @@ class Dao<T : Entity> internal constructor(
private val DB_LOCK = Any();
}

private val todoLock = ReentrantLock(true)
private val insertionLock = ReentrantLock(true)

private //create fields statement
val fields =
entityClass.getAnnotation(RudderEntity::class.java)?.fields?.takeIf { it.isNotEmpty() }
Expand All @@ -58,7 +65,7 @@ class Dao<T : Entity> internal constructor(

private var _db: SQLiteDatabase? = null
get() = if (field?.isOpen == true) field else null
private var todoTransactions: MutableList<Runnable> = ArrayList(5)
private var todoTransactions: BlockingQueue<Runnable> = LinkedBlockingQueue()
private val _dataChangeListeners = HashSet<DataChangeListener<T>>()

private val entityContentProviderUri by lazy {
Expand Down Expand Up @@ -111,10 +118,10 @@ class Dao<T : Entity> internal constructor(
fun List<T>.insertSync(
conflictResolutionStrategy: ConflictResolutionStrategy = ConflictResolutionStrategy.CONFLICT_NONE
): List<Long>? {
return _db?.let { db ->
awaitDbInitialization()
return (_db?.let { db ->
insertData(db, this, conflictResolutionStrategy).first
}

})
}


Expand Down Expand Up @@ -265,7 +272,13 @@ class Dao<T : Entity> internal constructor(
* @return all data and null if database is not ready yet
*/
fun getAllSync(): List<T>? {
return _db?.let { getItems(it) }
awaitDbInitialization()
return (_db?.let { getItems(it) })
}

private fun awaitDbInitialization() {
todoLock.lock()
todoLock.unlock()
}

fun runGetQuery(
Expand Down Expand Up @@ -297,6 +310,7 @@ class Dao<T : Entity> internal constructor(
limit: String? = null,
offset: String? = null
): List<T>? {
awaitDbInitialization()
return getItems(
_db ?: return null,
columns,
Expand All @@ -323,6 +337,7 @@ class Dao<T : Entity> internal constructor(
selection: String? = null,
selectionArgs: Array<String>? = null
): Long {
awaitDbInitialization()
return if (useContentProvider) (context.contentResolver.query(
entityContentProviderUri.build(),
arrayOf("count(*)"), selection, selectionArgs, null
Expand Down Expand Up @@ -351,20 +366,18 @@ class Dao<T : Entity> internal constructor(
synchronized(DB_LOCK) {
if (!db.isOpen) return emptyList<Long>() to emptyList()
}
insertionLock.lock()
val rowIdsToInsertedItems = processEntityInsertion(db, conflictResolutionStrategy, items)
insertionLock.unlock()
return rowIdsToInsertedItems
}

//we consider one key which is auto increment but not primary.
//These are special cases that needs to be handled here
//consider only one auto increment key
var (autoIncrementFieldName: String?, nextValue: Long) = fields.firstOrNull {
it.type == RudderField.Type.INTEGER &&
it.isAutoInc /*&& !it.primaryKey*/
}?.let { autoIncField ->
autoIncField.fieldName to getMaxIntValueForColumn(
db,
tableName,
autoIncField.fieldName
) + 1L
} ?: (null to 0L)
private fun processEntityInsertion(
db: SQLiteDatabase,
conflictResolutionStrategy: ConflictResolutionStrategy,
items: List<T>
): Pair<List<Long>, List<T?>> {
var (autoIncrementFieldName: String?, nextValue: Long) = getAutoIncrementFieldToNextValue(db)
var dbCount =
if (conflictResolutionStrategy == ConflictResolutionStrategy.CONFLICT_IGNORE) getCountSync(
db
Expand All @@ -373,13 +386,11 @@ class Dao<T : Entity> internal constructor(
var returnedItems = listOf<T?>()
if (!useContentProvider)
synchronized(DB_LOCK) {
// beginTransaction()
items.forEach {
val contentValues = it.generateContentValues()
if (autoIncrementFieldName != null) {
contentValues.put(autoIncrementFieldName, nextValue)
}
// contentValues.

val insertedRowId = insertContentValues(
db,
Expand Down Expand Up @@ -414,6 +425,19 @@ class Dao<T : Entity> internal constructor(
return rowIds to returnedItems
}

//we consider one key which is auto increment.
//consider only one auto increment key
private fun getAutoIncrementFieldToNextValue(db: SQLiteDatabase) = fields.firstOrNull {
it.type == RudderField.Type.INTEGER &&
it.isAutoInc /*&& !it.primaryKey*/
}?.let { autoIncField ->
autoIncField.fieldName to getMaxIntValueForColumn(
db,
tableName,
autoIncField.fieldName
) + 1L
} ?: (null to 0L)

private fun <T : Entity> ContentValues.toEntity(classOfT: Class<T>): T? {
return entityFactory.getEntity(classOfT, this.toMap())
}
Expand Down Expand Up @@ -464,13 +488,14 @@ class Dao<T : Entity> internal constructor(
)?.let {
it.lastPathSegment?.toLongOrNull()
} ?: -1)
else
else {
(database.openDatabase?.insertWithOnConflict(
tableName,
nullHackColumn,
contentValues,
conflictAlgorithm
) ?: -1)
}

}

Expand Down Expand Up @@ -529,6 +554,7 @@ class Dao<T : Entity> internal constructor(

private fun runTransactionOrDeferToCreation(queryTransaction: (SQLiteDatabase) -> Unit) {
_db?.let { db ->
awaitDbInitialization()
executorService.takeUnless { it.isShutdown }?.execute {
queryTransaction.invoke(db)
}
Expand All @@ -538,16 +564,14 @@ class Dao<T : Entity> internal constructor(
queryTransaction.invoke(it)
}
}.also {
todoTransactions.add(it)
todoTransactions.put(it)
}
}
}

internal fun setDatabase(sqLiteDatabase: SQLiteDatabase?) {
_db = sqLiteDatabase
fun setDatabase(sqLiteDatabase: SQLiteDatabase?) {
if (sqLiteDatabase == null) return


//run all pending tasks
executorService.execute {
synchronized(DB_LOCK) {
Expand All @@ -556,20 +580,33 @@ class Dao<T : Entity> internal constructor(
createIndexStmt(tableName, fields)?.apply {
sqLiteDatabase.openDatabase?.execSQL(this)
}
_db = sqLiteDatabase
todoLock.lock()
}
todoTransactions.forEach {
executorService.takeUnless { it.isShutdown }?.submit(it)
while (todoTransactions.isNotEmpty()){
try {
executorService.takeUnless { it.isShutdown }?.submit(
todoTransactions.poll(
50, TimeUnit.MILLISECONDS
)
)
}catch (ex: InterruptedException){
ex.printStackTrace()
}
}
todoLock.unlock()
}
}

fun execSqlSync(command: String) {
awaitDbInitialization()
synchronized(DB_LOCK) {
_db?.openDatabase?.execSQL(command)
}
}

private fun beginTransaction() {
awaitDbInitialization()
_db?.openDatabase?.beginTransaction()
}

Expand Down Expand Up @@ -604,36 +641,26 @@ class Dao<T : Entity> internal constructor(

private fun createTableStmt(tableName: String, fields: Array<RudderField>): String? {

// var isAutoIncKeyPresent = false
// var isAutoIncrementedKeyPrimaryKeySame = false
val fieldsStmt = fields.map {
// if (it.isAutoInc) {
//// isAutoIncKeyPresent = true
// isAutoIncrementedKeyPrimaryKeySame = it.primaryKey
// }
"'${it.fieldName}' ${it.type.notation}" + //field name and type
// if primary and auto increment
/*if (it.primaryKey && it.isAutoInc && it.type == RudderField.Type.INTEGER) " PRIMARY KEY AUTOINCREMENT" else "" +*/
if (!it.isNullable || it.primaryKey) " NOT NULL" else "" //specifying nullability, primary key cannot be null
}.reduce { acc, s -> "$acc, $s" }
val primaryKeyStmt =
/*if (isAutoIncrementedKeyPrimaryKeySame) "" else {*/
//auto increment is only available for one primary key
fields.filter { it.primaryKey }.takeIf { !it.isNullOrEmpty() }?.map {
it.fieldName
}?.reduce { acc, s -> "$acc,$s" }?.let {
"PRIMARY KEY ($it)"
} ?: ""
// }
val uniqueKeyStmt =
fields.filter { it.isUnique }.takeIf { it.isNotEmpty() }?.joinToString(",") {
it.fieldName
}?.let {
"UNIQUE($it)"
}



return ("CREATE TABLE IF NOT EXISTS '$tableName' ($fieldsStmt ${if (primaryKeyStmt.isNotEmpty()) ", $primaryKeyStmt" else ""}" +
"${if (!uniqueKeyStmt.isNullOrEmpty()) ", $uniqueKeyStmt" else ""})")
}
Expand All @@ -645,7 +672,6 @@ class Dao<T : Entity> internal constructor(
it.isNotEmpty()
} ?: return null
val indexFieldsStmt = indexedFields.map {
// it.indexName.takeIf { it.isNotEmpty() }?:"${it.fieldName}_idx"
it.fieldName
}.reduce { acc, s ->
"$acc,$s"
Expand Down
Loading

0 comments on commit edbf4bf

Please sign in to comment.