-
Notifications
You must be signed in to change notification settings - Fork 63
/
mongo_utils.go
118 lines (106 loc) · 3.02 KB
/
mongo_utils.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
// Copyright 2020-present Kuei-chun Chen. All rights reserved.
package keyhole
import (
"context"
"strings"
"sync"
"github.com/simagix/keyhole/mdb"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/x/mongo/driver/connstring"
)
var cmutex sync.Mutex
type mongoClientsMap map[string]*mongo.Client
var pool *mongoClientsMap
// GetMongoClientFromPool returns a mongo client by an endpoint
func GetMongoClientFromPool(uri string) (*mongo.Client, error) {
var err error
var connstr connstring.ConnString
cmutex.Lock()
defer cmutex.Unlock()
if pool == nil {
pool = &mongoClientsMap{}
}
if (*pool)[uri] == nil {
if connstr, err = mdb.ParseURI(uri); err != nil {
return nil, err
}
if (*pool)[uri], err = mdb.NewMongoClient(connstr.String()); err != nil {
(*pool)[uri] = nil
return (*pool)[uri], err
}
} else {
if err = (*pool)[uri].Ping(context.Background(), nil); err != nil {
(*pool)[uri] = nil
return (*pool)[uri], err
}
}
return (*pool)[uri], nil
}
// GetQualifiedDatabases returns a list of qualified database names
func GetQualifiedDatabases(client *mongo.Client) ([]string, error) {
var err error
var ctx = context.Background()
var dbNames = []string{}
var dbs mdb.ListDatabases
if err = client.Database("admin").RunCommand(ctx, bson.D{{Key: "listDatabases", Value: 1}}).Decode(&dbs); err != nil {
return dbNames, err
}
for _, db := range dbs.Databases {
if db.Name == "admin" || db.Name == "config" || db.Name == "local" {
continue
}
dbNames = append(dbNames, db.Name)
}
return dbNames, nil
}
// GetQualifiedNamespaces returns a list of qualified namespace names
func GetQualifiedNamespaces(client *mongo.Client) ([]string, error) {
var err error
var ctx = context.Background()
var cursor *mongo.Cursor
var dbNames = []string{}
var namespaces = []string{}
if dbNames, err = GetQualifiedDatabases(client); err != nil {
return namespaces, err
}
for _, dbName := range dbNames {
if cursor, err = client.Database(dbName).ListCollections(ctx, bson.D{}); err != nil {
return namespaces, err
}
for cursor.Next(ctx) {
var doc bson.M
cursor.Decode(&doc)
name := doc["name"].(string)
if strings.HasPrefix(name, "system.") && name != "system.js" {
continue
} else {
namespaces = append(namespaces, dbName+"."+name)
}
}
cursor.Close(ctx)
}
return namespaces, nil
}
// GetQualifiedNamespacesByDB returns a list of qualified namespace names
func GetQualifiedNamespacesByDB(client *mongo.Client, dbName string) ([]string, error) {
var err error
var ctx = context.Background()
var cursor *mongo.Cursor
var namespaces = []string{}
if cursor, err = client.Database(dbName).ListCollections(ctx, bson.D{}); err != nil {
return namespaces, err
}
for cursor.Next(ctx) {
var doc bson.M
cursor.Decode(&doc)
name := doc["name"].(string)
if strings.HasPrefix(name, "system.") && name != "system.js" {
continue
} else {
namespaces = append(namespaces, dbName+"."+name)
}
}
cursor.Close(ctx)
return namespaces, nil
}