-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcollection_index.go
115 lines (92 loc) · 3.42 KB
/
collection_index.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
package gorpheus
import (
"fmt"
"strconv"
"strings"
"github.com/jmoiron/sqlx"
"github.com/toudi/gorpheus/migration"
)
type NamespaceMeta struct {
current int
mostRecent int
positionIndex map[int]int
}
const AppliedRevisionsQuery = "SELECT revision FROM gorpheus_revisions"
// index function creates indices of migrations so that when we want to
// apply them we will know at which position in the array they residue.
func (c *Collection) index(db *sqlx.DB) error {
var err error
var exists bool
var namespace string
var versionNo int
var namespaceMeta NamespaceMeta
var appliedRevision string
result, err := db.Query(AppliedRevisionsQuery)
for result.Next() {
if err = result.Scan(&appliedRevision); err != nil {
return fmt.Errorf("cannot parse applied revision: %v", err)
}
c.applied[appliedRevision] = true
}
for collectionIndex, migration := range c.Versions {
if namespace, err = migration.GetNamespace(); err != nil {
return fmt.Errorf("could not extract namespace for %v: %v", migration.GetVersion(), err)
}
if versionNo, err = migration.GetVersionNumber(); err != nil {
return fmt.Errorf("could not get version number for %v: %v", migration.GetVersion(), err)
}
if namespaceMeta, exists = c.metadata[namespace]; !exists {
namespaceMeta = NamespaceMeta{positionIndex: make(map[int]int), current: -1}
}
namespaceMeta.positionIndex[versionNo] = collectionIndex
if versionNo > namespaceMeta.mostRecent {
namespaceMeta.mostRecent = versionNo
}
if _, exists = c.applied[migration.GetVersion()]; exists && versionNo > namespaceMeta.current {
namespaceMeta.current = versionNo
}
c.metadata[namespace] = namespaceMeta
}
return err
}
func (c *Collection) GetDependencies(_migration migration.MigrationI) ([]migration.MigrationI, error) {
var versionNo int
var err error
var namespace string
// fmt.Printf("getDependencies of %s\n", _migration.GetVersion())
migrationDependencies := _migration.Dependencies()
dependencies := make([]migration.MigrationI, 0)
// fmt.Printf("dependencies: %+v\n", dependencies)
for _, dependency := range migrationDependencies {
namespace, versionNo, err = parseNamespaceAndVersionNo(dependency)
// fmt.Printf("result of parseNamespaceAndVersionNo: %s, %d, %v\n", namespace, versionNo, err)
if err != nil {
return nil, fmt.Errorf("could not detect dependency: %v", err)
}
dependencies = append(dependencies, c.Versions[c.metadata[namespace].positionIndex[versionNo]])
// fmt.Printf("dependecies array: %+v\n", dependencies)
}
versionNo, err = _migration.GetVersionNumber()
if err != nil {
return nil, fmt.Errorf("could not detect version number of current migration: %v", err)
}
if versionNo > 1 {
namespace, err = _migration.GetNamespace()
if err != nil {
return nil, fmt.Errorf("could not parse namespace from %s: %v", _migration.GetVersion(), err)
}
dependencies = append(dependencies, c.Versions[c.metadata[namespace].positionIndex[versionNo-1]])
}
return dependencies, nil
}
func parseNamespaceAndVersionNo(revision string) (string, int, error) {
underscoreIdx := strings.Index(revision, "_")
slashIdx := strings.Index(revision, "/")
namespace := revision[:slashIdx]
versionNumberString := revision[slashIdx+1 : underscoreIdx]
versionNumber, err := strconv.Atoi(versionNumberString)
if err != nil {
return "", -1, fmt.Errorf("unable to parse the numeric revision: %v", err)
}
return namespace, versionNumber, nil
}