forked from amacneil/dbmate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpostgres.go
129 lines (100 loc) · 2.94 KB
/
postgres.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package dbmate
import (
"database/sql"
"fmt"
"net/url"
"github.com/lib/pq"
)
// PostgresDriver provides top level database functions
type PostgresDriver struct {
}
// Open creates a new database connection
func (drv PostgresDriver) Open(u *url.URL) (*sql.DB, error) {
return sql.Open("postgres", u.String())
}
func (drv PostgresDriver) openPostgresDB(u *url.URL) (*sql.DB, error) {
// connect to postgres database
postgresURL := *u
postgresURL.Path = "postgres"
return drv.Open(&postgresURL)
}
// CreateDatabase creates the specified database
func (drv PostgresDriver) CreateDatabase(u *url.URL) error {
name := databaseName(u)
fmt.Printf("Creating: %s\n", name)
db, err := drv.openPostgresDB(u)
if err != nil {
return err
}
defer mustClose(db)
_, err = db.Exec(fmt.Sprintf("create database %s",
pq.QuoteIdentifier(name)))
return err
}
// DropDatabase drops the specified database (if it exists)
func (drv PostgresDriver) DropDatabase(u *url.URL) error {
name := databaseName(u)
fmt.Printf("Dropping: %s\n", name)
db, err := drv.openPostgresDB(u)
if err != nil {
return err
}
defer mustClose(db)
_, err = db.Exec(fmt.Sprintf("drop database if exists %s",
pq.QuoteIdentifier(name)))
return err
}
// DatabaseExists determines whether the database exists
func (drv PostgresDriver) DatabaseExists(u *url.URL) (bool, error) {
name := databaseName(u)
db, err := drv.openPostgresDB(u)
if err != nil {
return false, err
}
defer mustClose(db)
exists := false
err = db.QueryRow("select true from pg_database where datname = $1", name).
Scan(&exists)
if err == sql.ErrNoRows {
return false, nil
}
return exists, err
}
// CreateMigrationsTable creates the schema_migrations table
func (drv PostgresDriver) CreateMigrationsTable(db *sql.DB) error {
_, err := db.Exec(`create table if not exists schema_migrations (
version varchar(255) primary key)`)
return err
}
// SelectMigrations returns a list of applied migrations
// with an optional limit (in descending order)
func (drv PostgresDriver) SelectMigrations(db *sql.DB, limit int) (map[string]bool, error) {
query := "select version from schema_migrations order by version desc"
if limit >= 0 {
query = fmt.Sprintf("%s limit %d", query, limit)
}
rows, err := db.Query(query)
if err != nil {
return nil, err
}
defer mustClose(rows)
migrations := map[string]bool{}
for rows.Next() {
var version string
if err := rows.Scan(&version); err != nil {
return nil, err
}
migrations[version] = true
}
return migrations, nil
}
// InsertMigration adds a new migration record
func (drv PostgresDriver) InsertMigration(db Transaction, version string) error {
_, err := db.Exec("insert into schema_migrations (version) values ($1)", version)
return err
}
// DeleteMigration removes a migration record
func (drv PostgresDriver) DeleteMigration(db Transaction, version string) error {
_, err := db.Exec("delete from schema_migrations where version = $1", version)
return err
}