5
5
"fmt"
6
6
"log"
7
7
"os"
8
+ "slices"
9
+ "strings"
8
10
"time"
9
11
10
12
_ "github.com/lib/pq"
@@ -18,24 +20,148 @@ type todo struct {
18
20
Item string
19
21
}
20
22
23
+ type Todoer interface {
24
+ NewTodo (* fiber.Ctx ) error
25
+ GetTodos (* fiber.Ctx , string ) error
26
+ DeleteTodo (* fiber.Ctx ) error
27
+ Healthcheck (c * fiber.Ctx ) error
28
+ Init () error
29
+ }
30
+
31
+ type PGDB struct {
32
+ DB * sql.DB
33
+ }
34
+
35
+ func (p * PGDB ) GetTodos (ctx * fiber.Ctx , version string ) error {
36
+ var res string
37
+ var todos []string
38
+ rows , err := p .DB .Query ("SELECT * FROM todos" )
39
+ if err != nil {
40
+ log .Fatalln (err )
41
+ ctx .JSON ("An error occurred" )
42
+ }
43
+ defer rows .Close ()
44
+
45
+ for rows .Next () {
46
+ rows .Scan (& res )
47
+ todos = append (todos , res )
48
+ }
49
+
50
+ return ctx .Render ("index" , fiber.Map {
51
+ "Todos" : todos ,
52
+ "Enterprise" : os .Getenv ("ENTERPRISE" ),
53
+ "Version" : version ,
54
+ })
55
+ }
56
+
57
+ func (p * PGDB ) NewTodo (ctx * fiber.Ctx ) error {
58
+ newTodo := todo {}
59
+ if err := ctx .BodyParser (& newTodo ); err != nil {
60
+ log .Printf ("An error occurred: %v" , err )
61
+ return ctx .SendString (err .Error ())
62
+ }
63
+ fmt .Printf ("Creating a new To Do: %q\n " , newTodo )
64
+ if newTodo .Item != "" {
65
+ _ , err := p .DB .Exec ("INSERT into todos VALUES ($1)" , newTodo .Item )
66
+ if err != nil {
67
+ log .Fatalf ("An error occurred while executing query: %v" , err )
68
+ }
69
+ }
70
+
71
+ return ctx .Redirect ("/" )
72
+ }
73
+
74
+ func (p * PGDB ) DeleteTodo (c * fiber.Ctx ) error {
75
+ todoToDelete := c .Query ("item" )
76
+ p .DB .Exec ("DELETE from todos WHERE item=$1" , todoToDelete )
77
+ fmt .Printf ("Deleting To Do: %q\n " , todoToDelete )
78
+ return c .SendString ("deleted" )
79
+ }
80
+
81
+ func (p * PGDB ) Healthcheck (c * fiber.Ctx ) error {
82
+ err := p .DB .Ping ()
83
+ if err != nil {
84
+ c .SendString (err .Error ())
85
+ }
86
+ return err
87
+ }
88
+
89
+ func (p * PGDB ) Init () error {
90
+ _ , err := p .DB .Exec ("CREATE TABLE IF NOT EXISTS todos (item text)" )
91
+ return err
92
+ }
93
+
94
+ type LocalDB struct {
95
+ Todos []string
96
+ }
97
+
98
+ func (l * LocalDB ) GetTodos (ctx * fiber.Ctx , version string ) error {
99
+ return ctx .Render ("index" , fiber.Map {
100
+ "Todos" : l .Todos ,
101
+ "Enterprise" : os .Getenv ("ENTERPRISE" ),
102
+ "Version" : version ,
103
+ })
104
+ }
105
+
106
+ func (l * LocalDB ) NewTodo (ctx * fiber.Ctx ) error {
107
+ newTodo := todo {}
108
+ if err := ctx .BodyParser (& newTodo ); err != nil {
109
+ log .Printf ("An error occurred: %v" , err )
110
+ return ctx .SendString (err .Error ())
111
+ }
112
+ fmt .Printf ("Creating a new To Do: %q\n " , newTodo )
113
+ if newTodo .Item != "" {
114
+ l .Todos = append (l .Todos , newTodo .Item )
115
+ }
116
+
117
+ return ctx .Redirect ("/" )
118
+ }
119
+
120
+ func (l * LocalDB ) DeleteTodo (c * fiber.Ctx ) error {
121
+ todoToDelete := c .Query ("item" )
122
+ for i , todo := range l .Todos {
123
+ if strings .EqualFold (todo , todoToDelete ) {
124
+ l .Todos = slices .Delete (l .Todos , i , i + 1 )
125
+ }
126
+ }
127
+ fmt .Printf ("Deleting To Do: %q\n " , todoToDelete )
128
+ return c .SendString ("deleted" )
129
+ }
130
+
131
+ func (p * LocalDB ) Healthcheck (c * fiber.Ctx ) error {
132
+ return nil
133
+ }
134
+
135
+ func (p * LocalDB ) Init () error {
136
+ return nil
137
+ }
138
+
21
139
func main () {
22
140
pgUser := or (or (os .Getenv ("DB_USER" ), os .Getenv ("PGUSER" )), "postgres" )
23
141
pgPassword := or (os .Getenv ("DB_PASSWORD" ), os .Getenv ("PGPASSWORD" ))
24
- pgHost := or (or ( os .Getenv ("DB_HOST" ), os .Getenv ("PGHOST" )), "localhost:5432" )
142
+ pgHost := or (os .Getenv ("DB_HOST" ), os .Getenv ("PGHOST" ))
25
143
pgSSLMode := or (or (os .Getenv ("DB_SSL_MODE" ), os .Getenv ("PGSSLMODE" )), "require" )
26
144
dbName := or (or (os .Getenv ("DB_NAME" ), os .Getenv ("DBNAME" )), "mydb" )
27
145
28
- connStr := fmt .Sprintf ("postgresql://%s:%s@%s/%s?sslmode=%s" , pgUser , pgPassword , pgHost , dbName , pgSSLMode )
29
-
30
146
version := os .Getenv ("VERSION" )
31
147
fmt .Println ("Version: " , version )
32
148
33
- // Connect to database
34
- db , err := sql .Open ("postgres" , connStr )
35
- if err != nil {
36
- log .Fatal (err )
149
+ var querier Todoer
150
+ if pgHost != "" {
151
+ // Connect to database if PGHOST is set
152
+ connStr := fmt .Sprintf ("postgresql://%s:%s@%s/%s?sslmode=%s" , pgUser , pgPassword , pgHost , dbName , pgSSLMode )
153
+ db , err := sql .Open ("postgres" , connStr )
154
+ if err != nil {
155
+ log .Fatal (err )
156
+ }
157
+ defer db .Close ()
158
+
159
+ querier = & PGDB {
160
+ DB : db ,
161
+ }
162
+ } else {
163
+ querier = & LocalDB {}
37
164
}
38
- defer db .Close ()
39
165
40
166
engine := html .New ("./views" , ".html" )
41
167
app := fiber .New (fiber.Config {
@@ -45,23 +171,20 @@ func main() {
45
171
//checked by kubernetes to see if the pod is ready to receive traffic
46
172
app .Get ("/healthz" , func (c * fiber.Ctx ) error {
47
173
fmt .Println ("healthcheck" )
48
- err := db .Ping ()
49
- if err != nil {
50
- c .SendString (err .Error ())
51
- }
174
+ err := querier .Healthcheck (c )
52
175
return err
53
176
})
54
177
55
178
app .Get ("/" , func (c * fiber.Ctx ) error {
56
- return getTodos ( c , db , version )
179
+ return querier . GetTodos ( c , version )
57
180
})
58
181
59
182
app .Post ("/" , func (c * fiber.Ctx ) error {
60
- return newTodo ( c , db )
183
+ return querier . NewTodo ( c )
61
184
})
62
185
63
186
app .Delete ("/delete" , func (c * fiber.Ctx ) error {
64
- return deleteTodo ( c , db )
187
+ return querier . DeleteTodo ( c )
65
188
})
66
189
67
190
port := or (os .Getenv ("PORT" ), "8080" )
@@ -74,8 +197,8 @@ func main() {
74
197
x := 0
75
198
for {
76
199
log .Println ("Attempting to connect to DB" )
77
-
78
- if err := initDB ( db ); err == nil {
200
+ var err error
201
+ if err = querier . Init ( ); err == nil {
79
202
break
80
203
}
81
204
@@ -92,57 +215,6 @@ func main() {
92
215
log .Println (app .Listen (fmt .Sprintf (":%v" , port )))
93
216
}
94
217
95
- func getTodos (c * fiber.Ctx , db * sql.DB , version string ) error {
96
- var res string
97
- var todos []string
98
- rows , err := db .Query ("SELECT * FROM todos" )
99
- if err != nil {
100
- log .Fatalln (err )
101
- c .JSON ("An error occured" )
102
- }
103
- defer rows .Close ()
104
-
105
- for rows .Next () {
106
- rows .Scan (& res )
107
- todos = append (todos , res )
108
- }
109
-
110
- return c .Render ("index" , fiber.Map {
111
- "Todos" : todos ,
112
- "Enterprise" : os .Getenv ("ENTERPRISE" ),
113
- "Version" : version ,
114
- })
115
- }
116
-
117
- func newTodo (c * fiber.Ctx , db * sql.DB ) error {
118
- newTodo := todo {}
119
- if err := c .BodyParser (& newTodo ); err != nil {
120
- log .Printf ("An error occured: %v" , err )
121
- return c .SendString (err .Error ())
122
- }
123
- fmt .Printf ("Creating a new To Do: %q\n " , newTodo )
124
- if newTodo .Item != "" {
125
- _ , err := db .Exec ("INSERT into todos VALUES ($1)" , newTodo .Item )
126
- if err != nil {
127
- log .Fatalf ("An error occured while executing query: %v" , err )
128
- }
129
- }
130
-
131
- return c .Redirect ("/" )
132
- }
133
-
134
- func deleteTodo (c * fiber.Ctx , db * sql.DB ) error {
135
- todoToDelete := c .Query ("item" )
136
- db .Exec ("DELETE from todos WHERE item=$1" , todoToDelete )
137
- fmt .Printf ("Deleting To Do: %q\n " , todoToDelete )
138
- return c .SendString ("deleted" )
139
- }
140
-
141
- func initDB (db * sql.DB ) error {
142
- _ , err := db .Exec ("CREATE TABLE IF NOT EXISTS todos (item text)" )
143
- return err
144
- }
145
-
146
218
func or (a string , b string ) string {
147
219
if a == "" {
148
220
return b
0 commit comments