forked from ApacheExpress/ApacheExpress
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DatabaseHandler.swift
127 lines (100 loc) · 3.48 KB
/
DatabaseHandler.swift
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
//
// Copyright (C) 2017 ZeeZide GmbH, All Rights Reserved
// Created by Helge Hess on 23/01/2017.
//
import ZzApache
import Apache2
import ApachePortableRuntime
// Just a handler that logs a little info about a request and delivers
// the file when appropriate
func DatabaseHandler(p: UnsafeMutablePointer<request_rec>?) -> Int32 {
var req = ZzApacheRequest(raw: p!) // var because we set the contentType
guard req.handler == "database" else { return DECLINED }
guard req.method == "GET" else { return HTTP_METHOD_NOT_ALLOWED }
req.contentType = "text/html; charset=ascii"
req.puts("<html><head><title>Hello DBD</title>\(semanticUI)</head>")
req.puts("<body><div class='ui main container' style='margin-top: 1em;'>")
req.puts("<h3>Swift Apache DBD Module Demo Handler</h3>")
defer { req.puts("</body></html>") }
req.puts("<a href='/'>[Server Root]</a>")
req.puts(
"<p>" +
"This handler can access a mod_dbd database as configured in the " +
"apache.conf." +
"</p>"
)
// dbd test
guard let dbd = req.dbdAcquire() else {
print("got no DB handle ...")
req.puts("<p>Could not acquire database connection. Configure the " +
"relevant section in the apache.conf (load mod_dbd and set the absolute" +
"path to the database in the data directory).</p>"
)
return OK
}
let preStyle =
"margin: 0 1em 1em 1em; padding: 0.8em; border: 1px dotted #AAA;"
req.puts(
"<p>Acquired database connection successfully.</p>" +
"<p>Run:</p>" +
"<pre style='\(preStyle)'>" +
"dbd.select(\"SELECT * FROM pets\")</pre>"
)
// MARK: - Raw Select
guard let res = dbd.select("SELECT * FROM pets") else {
req.puts("<p>Query failed. No idea why, check the logs :-)</p>")
return OK
}
req.puts(
"<p>The query returned a result: \(res.columnCount) columns, " +
"\(res.count) rows:</p>"
)
req.puts("<table class='ui sortable celled table'>")
req.puts("<thead><tr><th>Name</th></tr></thead><tbody>")
// TODO: make this a Swift Iterator (but then we can't use protocols)
while let row = res.next() {
req.puts("<tr><td>")
if let value = row[0] {
req.puts(value)
// req.puts(" name(\(row[name: 0]))") // fails
}
req.puts("</td></tr>")
}
req.puts("</tbody></table>")
// MARK: - Wrapped Select - Strongly Typed!
req.puts("<table class='ui sortable celled table'>")
req.puts("<thead>" +
"<tr><th colspan='2'>Callback typed fetch, with optionals</th></tr>" +
"<tr><th>Name</th><th>Count</th></tr></thead><tbody>"
)
dbd.select("SELECT * FROM pets") { (name : String, count : Int?) in
req.puts("<tr><td>\(name)</td><td>\(count)</td></tr>")
}
req.puts("</tbody></table>")
// MARK: - Wrapped Select - with model-like access
struct Model {
struct Pet {
static let name = Attribute<String>(name: "name")
static let count = Attribute<Int> (name: "count")
}
}
req.puts("<table class='ui sortable celled table'>")
req.puts("<thead>" +
"<tr><th colspan='2'>Model fetch</th></tr>" +
"<tr><th>Name</th><th>Count</th></tr></thead><tbody>"
)
dbd.select(Model.Pet.name, Model.Pet.count, from: "pets") { name, count in
req.puts("<tr><td>\(name)</td><td>\(count)</td></tr>")
}
req.puts("</tbody></table>")
// MARK: - Smarter Model
struct SmartModel {
struct Pet {
var name : String
var count : Int
}
}
// MARK: - Finish up
req.puts("</div></body></html>")
return OK
}