From fc039262d9f19014fd3a788718011ed6a32f804d Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Fri, 30 Oct 2020 10:47:50 +1100 Subject: [PATCH] sqlite storage: Force data to be used as a blob There's a bug in crawshaw.io/sqlite, and some forks where inserting []byte results in a text type instead of blob. To ensure things work correctly, we coerce data to blob wherever we can. See https://github.com/crawshaw/sqlite/issues/94 and the fork that fixes it. --- storage/sqlite/sqlite-storage.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/storage/sqlite/sqlite-storage.go b/storage/sqlite/sqlite-storage.go index 00c56362..fc419c29 100644 --- a/storage/sqlite/sqlite-storage.go +++ b/storage/sqlite/sqlite-storage.go @@ -60,10 +60,10 @@ with recursive excess( blob_rowid, data_length ) as ( - select * from (select (select sum(length(data)) from blob) as usage_with, last_used, rowid, length(data) from blob order by last_used, rowid limit 1) + select * from (select (select sum(length(cast(data as blob))) from blob) as usage_with, last_used, rowid, length(cast(data as blob)) from blob order by last_used, rowid limit 1) where usage_with >= (select value from setting where name='capacity') union all - select usage_with-data_length, blob.last_used, blob.rowid, length(data) from excess join blob + select usage_with-data_length, blob.last_used, blob.rowid, length(cast(data as blob)) from excess join blob on blob.rowid=(select rowid from blob where (last_used, rowid) > (excess.last_used, blob_rowid)) where usage_with >= (select value from setting where name='capacity') ) select * from excess; @@ -262,7 +262,10 @@ func (i instance) Put(reader io.Reader) (err error) { } i.withConn(func(conn conn) { for range iter.N(10) { - err = sqlitex.Exec(conn, "insert or replace into blob(name, data) values(?, ?)", nil, i.location, buf.Bytes()) + err = sqlitex.Exec(conn, + "insert or replace into blob(name, data) values(?, cast(? as blob))", + nil, + i.location, buf.Bytes()) if err, ok := err.(sqlite.Error); ok && err.Code == sqlite.SQLITE_BUSY { log.Print("sqlite busy") time.Sleep(time.Second) @@ -336,7 +339,7 @@ func (i instance) ReadAt(p []byte, off int64) (n int, err error) { gotRow := false err = sqlitex.Exec( conn, - "select substr(data, ?, ?) from blob where name=?", + "select substr(cast(data as blob), ?, ?) from blob where name=?", func(stmt *sqlite.Stmt) error { if gotRow { panic("found multiple matching blobs") -- 2.48.1