-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
145 lines (121 loc) · 4.23 KB
/
main.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* ChromoDB
* ******************************************************************
* Originally authored by Alex Gaetano Padula
* Copyright (C) ChromoDB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package main
import (
"bufio"
"bytes"
"chromodb/datastructure"
"chromodb/system"
"context"
"flag"
"fmt"
"os"
"os/signal"
"sync"
"syscall"
)
// System starts here
// ./chromodb
// ./chromodb --help
// ./chromodb --memory-limit=7500 * 1024 * 1024
// ./chromodb --shell=false --user=alex --pasword=somepassword
// ./chromodb --shell=false --user=alex --pasword=somepassword --tls=true --key="key.pem" --cert="cert.pem"
func main() {
var db system.Database // Main system variable
db.Config.MemoryLimit = 750 * 1024 * 1024 // 750MB
go db.MonitorMemory() // This is for the MEM/mem command. We check every 5 seconds
// Load database and index file
ds, err := datastructure.OpenDB("chromo.db", "chromo.idx")
if err != nil {
return
}
db.DataStructure = ds // Set ds into system variable
db.Config.Port = 7676 // Set default port
db.Mu = &sync.Mutex{} // Mainly for transaction/concurrency control
shell := true // Use shell, good for embedded stuff
var tls bool // Upgrade clients to TLS
var help bool // Help show all flags
var user string // Database user for remote connections to use
var pass string // Database password for remote connections to use
// if tls enabled
var cert string // tls cert location
var key string // tls key location
flag.BoolVar(&help, "help", help, "displays flag instructions")
flag.BoolVar(&shell, "shell", shell, "true or false to use internal shell")
flag.BoolVar(&tls, "tls", tls, "enable tls listener. you must provide a cert and key using --cert and --key flags.")
flag.IntVar(&db.Config.MemoryLimit, "memory-limit", db.Config.MemoryLimit, "configure desired memory limit. default is 750mb i.e 750 * 1024 * 1024")
flag.StringVar(&user, "user", user, "database user username for when using network")
flag.StringVar(&pass, "pass", pass, "database user password for when using network")
flag.StringVar(&cert, "key", user, "tls cert location")
flag.StringVar(&key, "cert", pass, "tls key location")
flag.IntVar(&db.Config.Port, "port", db.Config.Port, "tcp/tls listener port default is 7676")
flag.Parse() // parse flags
if help { // if help display flag usages
flag.Usage()
os.Exit(0)
}
if !shell { // if not shell we will start up a networked ChromoDB
if user == "" && pass == "" {
fmt.Println("Database username and password is required when configuring database to be networked.")
os.Exit(1)
}
db.DBUser.Username = user
db.DBUser.Password = pass
// User is now set for listener
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
<-sigCh
cancel()
}()
db.StartTCPTLSListener(ctx)
db.Stop()
} else { // Not networked
qChan := make(chan []byte) // Query channel
go func() {
for {
reader := bufio.NewReader(os.Stdin)
fmt.Print("db>")
query, _ := reader.ReadBytes('\n')
qChan <- bytes.TrimSpace(query) // Receive from standard input and relay to query channel
}
}()
for {
query := <-qChan // Receive from query channel
// Check for exit command
if bytes.HasSuffix(query, []byte("exit")) {
fmt.Println("..\nbye!")
break
} // maybe not needed or unnecessary
// Execute the command
output, err := db.ExecuteCommand(query)
if err != nil {
fmt.Println("Error executing query:", err)
fmt.Print("db>")
} else {
// Print the output of the command
fmt.Println(output)
fmt.Print("db>")
}
}
}
}