| 92 | } |
| 93 | |
| 94 | func dbWriteCacheEntry(ctx context.Context, file *WaveFile, dataEntries map[int]*DataCacheEntry, replace bool) error { |
| 95 | return WithTx(ctx, func(tx *TxWrap) error { |
| 96 | query := `SELECT zoneid FROM db_wave_file WHERE zoneid = ? AND name = ?` |
| 97 | if !tx.Exists(query, file.ZoneId, file.Name) { |
| 98 | // since deletion is synchronous this stops us from writing to a deleted file |
| 99 | return os.ErrNotExist |
| 100 | } |
| 101 | // we don't update CreatedTs or Opts |
| 102 | query = `UPDATE db_wave_file SET size = ?, modts = ?, meta = ? WHERE zoneid = ? AND name = ?` |
| 103 | tx.Exec(query, file.Size, file.ModTs, dbutil.QuickJson(file.Meta), file.ZoneId, file.Name) |
| 104 | if replace { |
| 105 | query = `DELETE FROM db_file_data WHERE zoneid = ? AND name = ?` |
| 106 | tx.Exec(query, file.ZoneId, file.Name) |
| 107 | } |
| 108 | dataPartQuery := `REPLACE INTO db_file_data (zoneid, name, partidx, data) VALUES (?, ?, ?, ?)` |
| 109 | for partIdx, dataEntry := range dataEntries { |
| 110 | if partIdx != dataEntry.PartIdx { |
| 111 | panic(fmt.Sprintf("partIdx:%d and dataEntry.PartIdx:%d do not match", partIdx, dataEntry.PartIdx)) |
| 112 | } |
| 113 | tx.Exec(dataPartQuery, file.ZoneId, file.Name, dataEntry.PartIdx, dataEntry.Data) |
| 114 | } |
| 115 | return nil |
| 116 | }) |
| 117 | } |