github.com/google/fleetspeak@v0.1.15-0.20240426164851-4f31f62c1aea/fleetspeak/src/server/sqlite/filestore.go (about) 1 // Copyright 2017 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package sqlite 16 17 import ( 18 "bytes" 19 "context" 20 "database/sql" 21 "io" 22 "time" 23 24 "github.com/google/fleetspeak/fleetspeak/src/server/db" 25 ) 26 27 func (d *Datastore) StoreFile(ctx context.Context, service, name string, data io.Reader) error { 28 b, err := io.ReadAll(data) 29 if err != nil { 30 return err 31 } 32 d.l.Lock() 33 defer d.l.Unlock() 34 return d.runInTx(func(tx *sql.Tx) error { 35 _, err := tx.ExecContext(ctx, "INSERT OR REPLACE INTO files (service, name, modified_time_nanos, data) VALUES(?, ?, ?, ?)", 36 service, name, db.Now().UnixNano(), b) 37 return err 38 }) 39 } 40 41 func (d *Datastore) StatFile(ctx context.Context, service, name string) (time.Time, error) { 42 d.l.Lock() 43 defer d.l.Unlock() 44 45 var ts int64 46 47 err := d.runInTx(func(tx *sql.Tx) error { 48 row := tx.QueryRowContext(ctx, "SELECT modified_time_nanos FROM files WHERE service = ? AND name = ?", service, name) 49 return row.Scan(&ts) 50 }) 51 52 return time.Unix(0, ts).UTC(), err 53 } 54 55 func (d *Datastore) ReadFile(ctx context.Context, service, name string) (data db.ReadSeekerCloser, modtime time.Time, err error) { 56 d.l.Lock() 57 defer d.l.Unlock() 58 59 var b []byte 60 var ts int64 61 62 err = d.runInTx(func(tx *sql.Tx) error { 63 row := tx.QueryRowContext(ctx, "SELECT modified_time_nanos, data FROM files WHERE service = ? AND name = ?", service, name) 64 if err := row.Scan(&ts, &b); err != nil { 65 b = nil 66 return err 67 } 68 return nil 69 }) 70 71 if err != nil { 72 return nil, time.Time{}, err 73 } 74 if b == nil { 75 b = []byte{} 76 } 77 return db.NOOPCloser{ReadSeeker: bytes.NewReader(b)}, time.Unix(0, ts).UTC(), nil 78 }