• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FIWARE / VCVerifier / 25151574765

30 Apr 2026 06:48AM UTC coverage: 59.25% (+6.5%) from 52.779%
25151574765

push

github

web-flow
Merge pull request #95 from FIWARE/ticket-32/work

Ticket 32/work

709 of 845 new or added lines in 12 files covered. (83.91%)

3683 of 6216 relevant lines covered (59.25%)

0.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.96
/database/database.go
1
// Package database provides connection management for the integrated
2
// Credentials Config Service database. It supports PostgreSQL, MySQL, and
3
// SQLite backends, selected via the config.Database.Type field.
4
package database
5

6
import (
7
        "database/sql"
8
        "fmt"
9

10
        "github.com/fiware/VCVerifier/config"
11
        "github.com/fiware/VCVerifier/logging"
12

13
        // PostgreSQL driver registration
14
        _ "github.com/jackc/pgx/v5/stdlib"
15
        // MySQL driver registration
16
        _ "github.com/go-sql-driver/mysql"
17
        // Pure-Go SQLite driver registration (no CGO required)
18
        _ "modernc.org/sqlite"
19
)
20

21
// Supported database driver type constants.
22
const (
23
        // DriverTypePostgres selects the PostgreSQL driver.
24
        DriverTypePostgres = "postgres"
25
        // DriverTypeMySQL selects the MySQL/MariaDB driver.
26
        DriverTypeMySQL = "mysql"
27
        // DriverTypeSQLite selects the pure-Go SQLite driver.
28
        DriverTypeSQLite = "sqlite"
29
)
30

31
// driverName maps a config database type to the Go sql.Open driver name.
32
func driverName(dbType string) (string, error) {
1✔
33
        switch dbType {
1✔
34
        case DriverTypePostgres:
1✔
35
                return "pgx", nil
1✔
36
        case DriverTypeMySQL:
1✔
37
                return "mysql", nil
1✔
38
        case DriverTypeSQLite:
1✔
39
                return "sqlite", nil
1✔
40
        default:
1✔
41
                return "", fmt.Errorf("unsupported database type: %q (must be %q, %q, or %q)",
1✔
42
                        dbType, DriverTypePostgres, DriverTypeMySQL, DriverTypeSQLite)
1✔
43
        }
44
}
45

46
// buildDSN constructs a data-source name from the provided configuration.
47
// For PostgreSQL it returns a libpq-style connection string; for MySQL it
48
// returns a DSN in go-sql-driver/mysql format; for SQLite it returns the
49
// database file path (use ":memory:" for an in-memory database).
50
func buildDSN(cfg config.Database) (string, error) {
1✔
51
        switch cfg.Type {
1✔
52
        case DriverTypePostgres:
1✔
53
                return fmt.Sprintf(
1✔
54
                        "host=%s port=%d dbname=%s user=%s password=%s sslmode=%s",
1✔
55
                        cfg.Host, cfg.Port, cfg.Name, cfg.User, cfg.Password, cfg.SSLMode,
1✔
56
                ), nil
1✔
57
        case DriverTypeMySQL:
1✔
58
                // Format: user:password@tcp(host:port)/dbname?parseTime=true&tls=<sslMode>
1✔
59
                dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?parseTime=true",
1✔
60
                        cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.Name,
1✔
61
                )
1✔
62
                if cfg.SSLMode != "" {
2✔
63
                        dsn += fmt.Sprintf("&tls=%s", cfg.SSLMode)
1✔
64
                }
1✔
65
                return dsn, nil
1✔
66
        case DriverTypeSQLite:
1✔
67
                // For SQLite, Name is the file path or ":memory:" for in-memory.
1✔
68
                if cfg.Name == "" {
2✔
69
                        return ":memory:", nil
1✔
70
                }
1✔
71
                return cfg.Name, nil
1✔
72
        default:
1✔
73
                return "", fmt.Errorf("unsupported database type: %q", cfg.Type)
1✔
74
        }
75
}
76

77
// NewConnection opens a database connection pool based on the provided
78
// configuration. The returned *sql.DB is ready to use and has been verified
79
// with a ping. Callers are responsible for closing it when done.
80
func NewConnection(cfg config.Database) (*sql.DB, error) {
1✔
81
        driver, err := driverName(cfg.Type)
1✔
82
        if err != nil {
2✔
83
                return nil, err
1✔
84
        }
1✔
85

86
        dsn, err := buildDSN(cfg)
1✔
87
        if err != nil {
1✔
NEW
88
                return nil, err
×
NEW
89
        }
×
90

91
        logging.Log().Infof("Opening %s database connection", cfg.Type)
1✔
92

1✔
93
        db, err := sql.Open(driver, dsn)
1✔
94
        if err != nil {
1✔
NEW
95
                return nil, fmt.Errorf("failed to open %s connection: %w", cfg.Type, err)
×
NEW
96
        }
×
97

98
        // SQLite does not support concurrent writers and in-memory databases are
99
        // per-connection, so restrict the pool to a single connection.
100
        if cfg.Type == DriverTypeSQLite {
2✔
101
                db.SetMaxOpenConns(1)
1✔
102
        }
1✔
103

104
        if err := db.Ping(); err != nil {
1✔
NEW
105
                // Close the handle so we don't leak a half-opened pool.
×
NEW
106
                _ = db.Close()
×
NEW
107
                return nil, fmt.Errorf("failed to ping %s database: %w", cfg.Type, err)
×
NEW
108
        }
×
109

110
        logging.Log().Infof("Database connection established (%s)", cfg.Type)
1✔
111
        return db, nil
1✔
112
}
113

114
// Close gracefully closes the database connection pool. It logs any error
115
// but does not return it, making it convenient for deferred calls.
116
func Close(db *sql.DB) {
1✔
117
        if db == nil {
2✔
118
                return
1✔
119
        }
1✔
120
        if err := db.Close(); err != nil {
1✔
NEW
121
                logging.Log().Warnf("Error closing database connection: %v", err)
×
122
        } else {
1✔
123
                logging.Log().Info("Database connection closed")
1✔
124
        }
1✔
125
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc