I want to populate a column in a database with a new unique string value generated by UUID.randomUUID() When migrating I get a unique constraint failed codes.id error I understand that '${UUID.randomUUID()}' in the query produces the same value for all rows, but I don't see how this can be fixed. Help me please. My migration code:
class Migration_3_4 : Migration(3, 4) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS $MIGRATION_TABLE_CODES_OLD;")
database.execSQL("ALTER TABLE $MIGRATION_TABLE_CODES RENAME TO $MIGRATION_TABLE_CODES_OLD ")
database.execSQL(
"CREATE TABLE IF NOT EXISTS $MIGRATION_TABLE_CODES " +
"(id TEXT NOT NULL PRIMARY KEY, text TEXT NOT NULL, format INTEGER NOT NULL, " +
"type INTEGER NOT NULL, date INTEGER NOT NULL, note TEXT NOT NULL, " +
"isFavorite INTEGER NOT NULL)"
)
val sql = "INSERT INTO $MIGRATION_TABLE_CODES (id, text, format, type, date, note, isFavorite) " +
"SELECT '${UUID.randomUUID()}', text, format, type, date, note, isFavorite " +
"FROM $MIGRATION_TABLE_CODES_OLD"
database.execSQL(sql)
database.execSQL("DROP TABLE IF EXISTS $MIGRATION_TABLE_CODES_OLD")
}
companion object {
const val MIGRATION_TABLE_CODES_OLD = "codes_old"
const val MIGRATION_TABLE_CODES = "codes"
}
}
IF you wanted a probably unique text value then you could use:-
SELECT hex(randomblob(16)),text,format,type,date,note,isfavorite
the result would be along the lines of:-
You could, again ONLY IF YOU want unique text values, as opposed to generated UUID's, use
SELECT hex(random()),text,format,type,date,note,isfavorite
The following may be more suitable as it generates UUID like values:-
SELECT hex(randomblob(4))||'-'||hex(randomblob(2))||'-'||hex(randomblob(2))||'-'||hex(randomblob(2))||'-'||hex(randomblob(6)),text,format,type,date,note,isfavorite
e.g. :-
The testing itself was undertaken using an SQLite tool (Navicat but there are other tools). The following is the SQL used for the testing:-
/* Just in case the environmet is dirty */
DROP TABLE IF EXISTS migold;
DROP TABLE IF EXISTS mig;
DROP TABLE IF EXISTS mig2;
DROP TABLE IF EXISTS mig3;
/* Create and populate the table as if before migration */
CREATE TABLE IF NOT EXISTS mig (id INTEGER NOT NULL PRIMARY KEY, text TEXT NOT NULL, format INTEGER NOT NULL,type INTEGER NOT NULL, date INTEGER NOT NULL, note TEXT NOT NULL,isFavorite INTEGER NOT NULL);
/* insert rows into the pre-migration table*/
WITH cte(x) AS (
SELECT 1 UNION ALL SELECT x+1 FROM cte LIMIT 100000
)
INSERT INTO mig (text,format,type,date,note,isfavorite) SELECT 'textval',1,2,3,'noteval',4 FROM cte
;
/* show the rows of the pre-migration table */
SELECT * FROM mig;
/* THE MIGRATION */
DROP TABLE IF EXISTS migold;
ALTER TABLE mig RENAME TO migold;
CREATE TABLE IF NOT EXISTS mig (id TEXT NOT NULL PRIMARY KEY, text TEXT NOT NULL, format INTEGER NOT NULL,type INTEGER NOT NULL, date INTEGER NOT NULL, note TEXT NOT NULL,isFavorite INTEGER NOT NULL);
/* Some extra tables for alternative methods of generating the unique text id */
CREATE TABLE IF NOT EXISTS mig2 (id TEXT NOT NULL PRIMARY KEY, text TEXT NOT NULL, format INTEGER NOT NULL,type INTEGER NOT NULL, date INTEGER NOT NULL, note TEXT NOT NULL,isFavorite INTEGER NOT NULL);
CREATE TABLE IF NOT EXISTS mig3 (id TEXT NOT NULL PRIMARY KEY, text TEXT NOT NULL, format INTEGER NOT NULL,type INTEGER NOT NULL, date INTEGER NOT NULL, note TEXT NOT NULL,isFavorite INTEGER NOT NULL);
/* Example 1 */
INSERT INTO mig SELECT hex(randomblob(16)),text,format,type,date,note,isfavorite FROM migold;
SELECT * FROM mig;
/* Example 2 */
INSERT INTO mig2 SELECT hex(random()),text,format,type,date,note,isfavorite FROM migold;
SELECT * FROM mig2;
/* Example 3 */
INSERT INTO mig3 SELECT hex(randomblob(4))||'-'||hex(randomblob(2))||'-'||hex(randomblob(2))||'-'||hex(randomblob(2))||'-'||hex(randomblob(6)),text,format,type,date,note,isfavorite FROM migold;
SELECT * FROM mig3;
/* Cleanup test environment */
DROP TABLE IF EXISTS migold;
DROP TABLE IF EXISTS mig;
DROP TABLE IF EXISTS mig2;
DROP TABLE IF EXISTS mig3;