-
Notifications
You must be signed in to change notification settings - Fork 0
/
analysis.go
129 lines (103 loc) · 2.67 KB
/
analysis.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 publishing
import (
"io/fs"
"path/filepath"
"github.com/justinneff/kumiho/cache"
"github.com/justinneff/kumiho/entities"
)
func getDatabaseObjectPaths(dbDir string) ([]string, error) {
objectsDir := filepath.Join(dbDir, "objects")
var objectFiles []string
err := filepath.WalkDir(objectsDir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
if filepath.Ext(path) == ".sql" {
objectFiles = append(objectFiles, path)
}
return nil
})
if err != nil {
return nil, err
}
return objectFiles, nil
}
func resolveDependencies(obj *entities.DatabaseObject, otherObjects []*entities.DatabaseObject, provider entities.Provider) ([]string, error) {
var deps []string
for _, other := range otherObjects {
if obj.Hash != other.Hash {
matched, err := provider.IsDependency(obj.Content(), other.Schema, other.Name)
if err != nil {
return nil, err
}
if matched {
deps = append(deps, other.FullName())
}
}
}
return deps, nil
}
func allDependenciesIncluded(dependencies []string, objects []*entities.DatabaseObject) bool {
for _, dep := range dependencies {
found := false
for _, obj := range objects {
if dep == obj.FullName() {
found = true
}
}
if !found {
return false
}
}
return true
}
func sortObjects(remaining []*entities.DatabaseObject, sorted []*entities.DatabaseObject) []*entities.DatabaseObject {
if len(remaining) == 0 {
return sorted
}
var nextRemaining []*entities.DatabaseObject
for _, obj := range remaining {
if allDependenciesIncluded(obj.Dependencies, sorted) {
sorted = append(sorted, obj)
} else {
nextRemaining = append(nextRemaining, obj)
}
}
return sortObjects(nextRemaining, sorted)
}
func LoadDatabaseObjects(dbDir string, provider entities.Provider) ([]*entities.DatabaseObject, error) {
objectPaths, err := getDatabaseObjectPaths(dbDir)
if err != nil {
return nil, err
}
var objects []*entities.DatabaseObject
for _, objPath := range objectPaths {
obj, err := entities.NewDatabaseObject(objPath, provider)
if err != nil {
return nil, err
}
objects = append(objects, obj)
}
for i, obj := range objects {
cacheObj, err := cache.ReadDatabaseObject(obj.Hash)
if err != nil {
return nil, err
}
if cacheObj != nil {
objects[i].Dependencies = cacheObj.Dependencies
} else {
deps, err := resolveDependencies(obj, objects, provider)
if err != nil {
return nil, err
}
objects[i].Dependencies = deps
cache.WriteDatabaseObject(*objects[i])
}
}
var sortedObjects []*entities.DatabaseObject
sortedObjects = sortObjects(objects, sortedObjects)
return sortedObjects, nil
}