/go/lib/drkey/drkeydbsqlite/base_db.go

https://github.com/netsec-ethz/scion · Go · 85 lines · 49 code · 13 blank · 23 comment · 8 complexity · e92cbdbf7e477ddb2490adb2d7a91304 MD5 · raw file

  1. // Copyright 2019 ETH Zurich
  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. // http://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. package drkeydbsqlite
  15. import (
  16. "database/sql"
  17. _ "github.com/mattn/go-sqlite3"
  18. "github.com/scionproto/scion/go/lib/drkey"
  19. "github.com/scionproto/scion/go/lib/infra/modules/db"
  20. "github.com/scionproto/scion/go/lib/serrors"
  21. )
  22. const (
  23. unableToPrepareStmt = "Unable to prepare stmt"
  24. unableToExecuteStmt = "Unable to execute stmt"
  25. )
  26. var _ drkey.BaseDB = (*dbBaseBackend)(nil)
  27. // dbBaseBackend is the common part of all level backends.
  28. type dbBaseBackend struct {
  29. db *sql.DB
  30. }
  31. // newBaseBackend builds the base backend common for all level backends.
  32. func newBaseBackend(path, schema string, version int) (*dbBaseBackend, error) {
  33. db, err := db.NewSqlite(path, schema, version)
  34. if err != nil {
  35. return nil, err
  36. }
  37. return &dbBaseBackend{
  38. db: db,
  39. }, nil
  40. }
  41. type preparedStmts map[string]**sql.Stmt
  42. // prepareAll will create the prepared statements or return an error as soon as one fails.
  43. func (b *dbBaseBackend) prepareAll(stmts preparedStmts) error {
  44. var err error
  45. // On future errors, close the sql database before exiting
  46. defer func() {
  47. if err != nil {
  48. b.Close()
  49. }
  50. }()
  51. for str, stmt := range stmts {
  52. // FIXME(matzf): the sqlclosecheck linter does not like this pattern.
  53. // Perhapse this should be refactored to just avoid the prepared statements;
  54. // this does not appear to be goroutine safe anyway.
  55. if *stmt, err = b.db.Prepare(str); err != nil { // nolint:sqlclosecheck
  56. return serrors.WrapStr(unableToPrepareStmt, err)
  57. }
  58. }
  59. return nil
  60. }
  61. // Close closes the database connection.
  62. func (b *dbBaseBackend) Close() error {
  63. return b.db.Close()
  64. }
  65. // SetMaxOpenConns sets the maximum number of open connections.
  66. func (b *dbBaseBackend) SetMaxOpenConns(maxOpenConns int) {
  67. b.db.SetMaxOpenConns(maxOpenConns)
  68. }
  69. // SetMaxIdleConns sets the maximum number of idle connections.
  70. func (b *dbBaseBackend) SetMaxIdleConns(maxIdleConns int) {
  71. b.db.SetMaxIdleConns(maxIdleConns)
  72. }