2019-10-07 08:14:47 -06:00
|
|
|
// Copyright (c) Mainflux
|
2018-08-26 13:15:48 +02:00
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
2018-05-10 23:53:25 +02:00
|
|
|
package postgres
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2019-04-16 14:58:56 +02:00
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
|
2018-05-11 01:00:10 +02:00
|
|
|
_ "github.com/lib/pq" // required for SQL access
|
|
|
|
migrate "github.com/rubenv/sql-migrate"
|
2018-05-10 23:53:25 +02:00
|
|
|
)
|
|
|
|
|
2018-12-15 17:28:22 -06:00
|
|
|
// Config defines the options that are used when connecting to a PostgreSQL instance
|
|
|
|
type Config struct {
|
|
|
|
Host string
|
|
|
|
Port string
|
|
|
|
User string
|
|
|
|
Pass string
|
|
|
|
Name string
|
|
|
|
SSLMode string
|
|
|
|
SSLCert string
|
|
|
|
SSLKey string
|
|
|
|
SSLRootCert string
|
|
|
|
}
|
|
|
|
|
2018-05-11 01:00:10 +02:00
|
|
|
// Connect creates a connection to the PostgreSQL instance and applies any
|
|
|
|
// unapplied database migrations. A non-nil error is returned to indicate
|
|
|
|
// failure.
|
2019-04-16 14:58:56 +02:00
|
|
|
func Connect(cfg Config) (*sqlx.DB, error) {
|
2018-12-15 17:28:22 -06:00
|
|
|
url := fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=%s sslmode=%s sslcert=%s sslkey=%s sslrootcert=%s", cfg.Host, cfg.Port, cfg.User, cfg.Name, cfg.Pass, cfg.SSLMode, cfg.SSLCert, cfg.SSLKey, cfg.SSLRootCert)
|
2018-05-10 23:53:25 +02:00
|
|
|
|
2019-04-16 14:58:56 +02:00
|
|
|
db, err := sqlx.Open("postgres", url)
|
2018-05-10 23:53:25 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-05-11 01:00:10 +02:00
|
|
|
if err := migrateDB(db); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return db, nil
|
|
|
|
}
|
|
|
|
|
2019-04-16 14:58:56 +02:00
|
|
|
func migrateDB(db *sqlx.DB) error {
|
2020-09-23 23:18:53 +02:00
|
|
|
|
2018-05-11 01:00:10 +02:00
|
|
|
migrations := &migrate.MemoryMigrationSource{
|
|
|
|
Migrations: []*migrate.Migration{
|
2018-05-21 12:51:46 +02:00
|
|
|
{
|
2018-05-11 01:00:10 +02:00
|
|
|
Id: "users_1",
|
|
|
|
Up: []string{
|
2018-08-27 12:17:41 +02:00
|
|
|
`CREATE TABLE IF NOT EXISTS users (
|
2020-09-23 23:18:53 +02:00
|
|
|
email VARCHAR(254) PRIMARY KEY,
|
|
|
|
password CHAR(60) NOT NULL
|
|
|
|
)`,
|
2018-05-11 01:00:10 +02:00
|
|
|
},
|
|
|
|
Down: []string{"DROP TABLE users"},
|
|
|
|
},
|
2019-09-28 11:15:41 +00:00
|
|
|
{
|
|
|
|
Id: "users_2",
|
|
|
|
Up: []string{
|
|
|
|
`ALTER TABLE IF EXISTS users ADD COLUMN IF NOT EXISTS metadata JSONB`,
|
|
|
|
},
|
|
|
|
},
|
2020-06-04 22:29:16 +02:00
|
|
|
{
|
|
|
|
Id: "users_3",
|
|
|
|
Up: []string{
|
2020-06-19 01:37:54 +03:00
|
|
|
`CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
2020-09-23 23:18:53 +02:00
|
|
|
ALTER TABLE IF EXISTS users ADD COLUMN IF NOT EXISTS
|
|
|
|
id UUID NOT NULL DEFAULT gen_random_uuid()`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Id: "users_4",
|
|
|
|
Up: []string{
|
|
|
|
`ALTER TABLE IF EXISTS users DROP CONSTRAINT users_pkey`,
|
|
|
|
`ALTER TABLE IF EXISTS users ADD CONSTRAINT users_email_key UNIQUE (email)`,
|
|
|
|
`ALTER TABLE IF EXISTS users ADD PRIMARY KEY (id)`,
|
|
|
|
`CREATE TABLE IF NOT EXISTS groups (
|
|
|
|
id UUID NOT NULL,
|
|
|
|
parent_id UUID,
|
|
|
|
owner_id UUID,
|
|
|
|
name VARCHAR(254) UNIQUE NOT NULL,
|
|
|
|
description VARCHAR(1024),
|
|
|
|
metadata JSONB,
|
|
|
|
PRIMARY KEY (id),
|
|
|
|
FOREIGN KEY (parent_id) REFERENCES groups (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
|
|
|
FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
|
|
|
|
)`,
|
|
|
|
`CREATE TABLE IF NOT EXISTS group_relations (
|
|
|
|
user_id UUID NOT NULL,
|
|
|
|
group_id UUID NOT NULL,
|
|
|
|
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
|
|
|
FOREIGN KEY (group_id) REFERENCES groups (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
|
|
|
PRIMARY KEY (user_id, group_id)
|
|
|
|
)`,
|
|
|
|
`ALTER TABLE IF EXISTS users ADD COLUMN IF NOT EXISTS owner_id UUID`,
|
|
|
|
`ALTER TABLE IF EXISTS users ADD FOREIGN KEY (owner_id) REFERENCES groups(id)`,
|
2020-06-04 22:29:16 +02:00
|
|
|
},
|
|
|
|
},
|
2018-05-11 01:00:10 +02:00
|
|
|
},
|
|
|
|
}
|
2018-05-10 23:53:25 +02:00
|
|
|
|
2019-04-16 14:58:56 +02:00
|
|
|
_, err := migrate.Exec(db.DB, "postgres", migrations, migrate.Up)
|
2018-05-11 01:00:10 +02:00
|
|
|
return err
|
2018-05-10 23:53:25 +02:00
|
|
|
}
|