Почему Anko не может игнорировать переданное значение _id, когда _id имеет значение INTEGER + PRIMARY_KEY+ AUTOINCREMENT?

Я разработал поле _id INTEGER + PRIMARY_KEY+ AUTOINCREMENTЯ использую код SettingManage().addSetting(MSetting(10L,"My Settings",2000L,"This is description!")) вставить запись в таблицу.

Я думаю, что Anko проигнорирует переданное значение 10 _id и автоматически передаст новое значение _id, но на самом деле значение 10 _id вставлено в таблицу.

Как заставить Anko игнорировать переданное значение _id, когда _id INTEGER + PRIMARY_KEY+ AUTOINCREMENT?

Вставить данные

SettingManage().addSetting(MSetting(10L,"My Settings",2000L,"This is description!"))

Дизайн таблицы

    class DBSettingHelper(mContext: Context = UIApp.instance) : ManagedSQLiteOpenHelper(
            mContext,
            DB_NAME,
            null,
            DB_VERSION) {

        companion object {
            val DB_NAME = "setting.db"
            val DB_VERSION = 5
            val instance by lazy { DBSettingHelper() }
        }

        override fun onCreate(db: SQLiteDatabase) {
            db.createTable( DBSettingTable.TableNAME , true,
                    DBSettingTable._ID to INTEGER + PRIMARY_KEY+ AUTOINCREMENT ,
                    DBSettingTable.Name to TEXT,
                    DBSettingTable.CreatedDate to INTEGER,
                    DBSettingTable.Description to TEXT
            )
        }

        override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
            db.dropTable(DBSettingTable.TableNAME, true)
            onCreate(db)
        }

    }



    class DBSetting(val mMutableMap: MutableMap<String, Any?>) {
        var _id: Long by mMutableMap
        var name: String by mMutableMap
        var createdDate: Long by mMutableMap
        var description: String by mMutableMap

        constructor(_id: Long, name: String, createdDate: Long, description: String)
                : this(HashMap()) {
            this._id = _id
            this.name = name
            this.createdDate = createdDate
            this.description=description
        }
    }


    object DBSettingTable {
        val TableNAME = "SettingTable"

        val _ID = "_id"
        val Name = "name"
        val CreatedDate = "createdDate"
        val Description="description"
    }


   data class MSetting (
        val _id: Long,  
        val name: String,
        val createdDate: Long,
        val description: String
   )

Бизнес Логика

class SettingManage {
    fun addSetting(mMSetting:MSetting){
        DBSettingManage().addDBSetting(DbDataMapper().convertMSetting_To_DBSetting(mMSetting))
    }
}

class DBSettingManage(private val mDBSettingHelper: DBSettingHelper =DBSettingHelper.instance) {
    fun addDBSetting(mDBSetting: DBSetting)=mDBSettingHelper.use{
        insert(DBSettingTable.TableNAME,*mDBSetting.mMutableMap.toVarargArray())
    }
}

class DbDataMapper {
    fun convertMSetting_To_DBSetting(mMSetting: MSetting) =with(mMSetting){
        DBSetting(_id,name,createdDate,description)
    }
    fun convertDBSetting_To_MSetting(mDBSetting: DBSetting)=with(mDBSetting){
        MSetting(_id,name,createdDate,description )
    }
}


fun <T : Any> SelectQueryBuilder.parseList(parser: (Map<String, Any?>) -> T): List<T> =
        parseList(object : MapRowParser<T> {
            override fun parseRow(columns: Map<String, Any?>): T = parser(columns)
        })

1 ответ

Решение

Anko, по вашему мнению, является оболочкой для SQLite. Сам SQL переопределяет автоинкремент, когда передается пользовательское значение. Если значение не передано -> Автоматическое значение. В противном случае -> ручной. Предполагается, что он уникален из-за PRIMARY_KEY, но это другая проблема.

Насколько я знаю, в Anko нет встроенной функции, которая позволяла бы переопределять это вручную. Вместо этого единственное, что вы можете сделать, это не передать значение. Любой неправильный SQL-запрос будет перехвачен не самой Anko, а необработанным SQL-запросом. Это SQL, который выдает любые исключения, означающие, что Anko не будет проверять пропущенные данные.

Просто не передавайте удостоверение личности. Вы можете написать функцию, которая все еще принимает идентификатор, но отбрасывает его, если для строки заданы значения PRIMARY_KEY и AUTO_INCREMENT.


Я сделал больше копания в исходном коде и не поддерживается игнорирование переданных значений, если для него установлено автоматическое увеличение.

Это означает, что единственный способ, с помощью которого вы можете получить его на самом деле автоматически, - это не передавать никакие значения. Если вы используете ручные запросы любого рода, вы просто не передаете никакого значения. Так что не давайте базе данных идентификатор. Поскольку это автоинкремент, он автоматически добавит его, и это на базовом уровне SQL.

Ank не игнорирует это по умолчанию, потому что по сути это оболочка для SQLite. Это означает, что он должен быть в состоянии пройти, если идентификатор должен быть переопределен (см. Ссылку во втором предложении этого ответа). Таким образом, игнорирование Анко вызовет больше проблем, чем принесет пользу. Вы должны убедиться, что это не передано вместо

Другие вопросы по тегам