Passed
Pull Request — master (#1258)
by Tolga
02:36
created

factories.DatabaseFactory   C

Complexity

Conditions 9

Size

Total Lines 47
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 36
nop 1
dl 0
loc 47
rs 6.6666
c 0
b 0
f 0
1
package factories
2
3
import (
4
	"fmt"
5
6
	"github.com/Permify/permify/internal/config"
7
	"github.com/Permify/permify/internal/storage/memory/migrations"
8
	"github.com/Permify/permify/internal/storage/postgres/utils"
9
	"github.com/Permify/permify/pkg/database"
10
	IMDatabase "github.com/Permify/permify/pkg/database/memory"
11
	PQDatabase "github.com/Permify/permify/pkg/database/postgres"
12
)
13
14
// DatabaseFactory is a factory function that creates a database instance according to the given configuration.
15
// It supports different types of databases, such as PostgreSQL and in-memory databases.
16
//
17
// conf: the configuration object containing the necessary information to create a database connection.
18
//
19
//	It should have the following properties:
20
//	- Engine: the type of the database, e.g., POSTGRES or MEMORY
21
//	- URI: the connection string for the database (only required for some database engines, e.g., POSTGRES)
22
//	- MaxOpenConnections: the maximum number of open connections to the database
23
//	- MaxIdleConnections: the maximum number of idle connections in the connection pool
24
//	- MaxConnectionIdleTime: the maximum amount of time a connection can be idle before being closed
25
//	- MaxConnectionLifetime: the maximum amount of time a connection can be reused before being closed
26
//	- WatchBufferSize: specifies the buffer size for database watch operations, impacting how many changes can be queued
27
//	- MaxDataPerWrite: sets the maximum amount of data per write operation to the database
28
//	- MaxRetries: defines the maximum number of retries for database operations in case of failure
29
//
30
// Returns a database.Database instance if the database connection is successfully created, or an error if the
31
// creation fails or the specified database engine is unsupported.
32
func DatabaseFactory(conf config.Database) (db database.Database, err error) {
33
	switch conf.Engine {
34
	case database.POSTGRES.String():
35
36
		if conf.URI == "" {
37
			db, err = PQDatabase.NewWithSeparateURIs(conf.Writer.URI, conf.Reader.URI,
38
				PQDatabase.MaxOpenConnections(conf.MaxOpenConnections),
39
				PQDatabase.MaxIdleConnections(conf.MaxIdleConnections),
40
				PQDatabase.MaxConnectionIdleTime(conf.MaxConnectionIdleTime),
41
				PQDatabase.MaxConnectionLifeTime(conf.MaxConnectionLifetime),
42
				PQDatabase.WatchBufferSize(conf.WatchBufferSize),
43
				PQDatabase.MaxDataPerWrite(conf.MaxDataPerWrite),
44
				PQDatabase.MaxRetries(conf.MaxRetries),
45
			)
46
			if err != nil {
47
				return nil, err
48
			}
49
		} else {
50
			db, err = PQDatabase.New(conf.URI,
51
				PQDatabase.MaxOpenConnections(conf.MaxOpenConnections),
52
				PQDatabase.MaxIdleConnections(conf.MaxIdleConnections),
53
				PQDatabase.MaxConnectionIdleTime(conf.MaxConnectionIdleTime),
54
				PQDatabase.MaxConnectionLifeTime(conf.MaxConnectionLifetime),
55
				PQDatabase.WatchBufferSize(conf.WatchBufferSize),
56
				PQDatabase.MaxDataPerWrite(conf.MaxDataPerWrite),
57
				PQDatabase.MaxRetries(conf.MaxRetries),
58
			)
59
			if err != nil {
60
				return nil, err
61
			}
62
		}
63
64
		// check postgres version
65
		_, err = utils.EnsureDBVersion(db.(*PQDatabase.Postgres).ReadPool)
66
		if err != nil {
67
			return nil, err
68
		}
69
70
		return
71
	case database.MEMORY.String():
72
		db, err = IMDatabase.New(migrations.Schema)
73
		if err != nil {
74
			return nil, err
75
		}
76
		return
77
	default:
78
		return nil, fmt.Errorf("%s connection is unsupported", conf.Engine)
79
	}
80
}
81