@@ -2,16 +2,12 @@ const std = @import("std");
2
2
const httpz = @import ("httpz" );
3
3
const pg = @import ("pg" );
4
4
const datetimez = @import ("datetimez" );
5
- const mustache = @import ("mustache" );
6
5
7
- const Thread = std .Thread ;
8
- const Mutex = Thread .Mutex ;
9
- const template = "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>{{#fortunes}}<tr><td>{{id}}</td><td>{{message}}</td></tr>{{/fortunes}}</table></body></html>" ;
6
+ pub var date_str : []u8 = "" ;
10
7
11
8
pub const Global = struct {
12
9
pool : * pg.Pool ,
13
10
rand : * std.rand.Random ,
14
- mutex : std.Thread.Mutex = .{},
15
11
};
16
12
17
13
const World = struct {
@@ -40,9 +36,7 @@ pub fn json(_: *Global, _: *httpz.Request, res: *httpz.Response) !void {
40
36
pub fn db (global : * Global , _ : * httpz.Request , res : * httpz.Response ) ! void {
41
37
try setHeaders (res .arena , res );
42
38
43
- global .mutex .lock ();
44
39
const random_number = 1 + (global .rand .uintAtMostBiased (u32 , 9999 ));
45
- global .mutex .unlock ();
46
40
47
41
const world = getWorld (global .pool , random_number ) catch | err | {
48
42
std .debug .print ("Error querying database: {}\n " , .{err });
@@ -76,31 +70,37 @@ fn getWorld(pool: *pg.Pool, random_number: u32) !World {
76
70
fn setHeaders (allocator : std.mem.Allocator , res : * httpz.Response ) ! void {
77
71
res .header ("Server" , "Httpz" );
78
72
79
- const now = datetimez .datetime .Date .now ();
80
- const time = datetimez .datetime .Time .now ();
73
+ // const now = datetimez.datetime.Date.now();
74
+ // const time = datetimez.datetime.Time.now();
81
75
82
76
// Wed, 17 Apr 2013 12:00:00 GMT
83
77
// Return date in ISO format YYYY-MM-DD
84
- const TB_DATE_FMT = "{s:0>3}, {d:0>2} {s:0>3} {d:0>4} {d:0>2}:{d:0>2}:{d:0>2} GMT" ;
85
- const now_str = try std .fmt .allocPrint (allocator , TB_DATE_FMT , .{ now .weekdayName ()[0.. 3], now .day , now .monthName ()[0.. 3], now .year , time .hour , time .minute , time .second });
78
+ // const TB_DATE_FMT = "{s:0>3}, {d:0>2} {s:0>3} {d:0>4} {d:0>2}:{d:0>2}:{d:0>2} GMT";
79
+ // const now_str = try std.fmt.allocPrint(allocator, TB_DATE_FMT, .{ now.weekdayName()[0..3], now.day, now.monthName()[0..3], now.year, time.hour, time.minute, time.second });
86
80
87
81
//defer allocator.free(now_str);
88
82
89
- res .header ("Date" , now_str );
83
+ res .header ("Date" , try allocator . dupe ( u8 , date_str ) );
90
84
}
91
85
92
86
fn getFortunesHtml (allocator : std.mem.Allocator , pool : * pg.Pool ) ! []const u8 {
93
87
const fortunes = try getFortunes (allocator , pool );
94
88
95
- const raw = try mustache . allocRenderText ( allocator , template , .{ . fortunes = fortunes } );
89
+ var sb = try std . ArrayListUnmanaged ( u8 ). initCapacity ( allocator , 0 );
96
90
97
- // std.debug.print("mustache output {s}\n", .{raw});
91
+ const writer = sb .writer (allocator );
92
+ try sb .appendSlice (allocator , "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>" );
98
93
99
- const html = try deescapeHtml (allocator , raw );
94
+ for (fortunes ) | ft | {
95
+ try writer .print ("<tr><td>{d}</td><td>{s}</td></tr>" , .{
96
+ ft .id ,
97
+ try escape_html (allocator , ft .message ),
98
+ });
99
+ }
100
100
101
- // std.debug.print("html output {s}\n", .{ html} );
101
+ try sb . appendSlice ( allocator , "</table></body></ html>" );
102
102
103
- return html ;
103
+ return sb . toOwnedSlice ( allocator ) ;
104
104
}
105
105
106
106
fn getFortunes (allocator : std.mem.Allocator , pool : * pg.Pool ) ! []const Fortune {
@@ -110,18 +110,18 @@ fn getFortunes(allocator: std.mem.Allocator, pool: *pg.Pool) ![]const Fortune {
110
110
var rows = try conn .query ("SELECT id, message FROM Fortune" , .{});
111
111
defer rows .deinit ();
112
112
113
- var fortunes = std .ArrayList (Fortune ).init (allocator );
114
- defer fortunes .deinit ();
113
+ var fortunes = try std .ArrayListUnmanaged (Fortune ).initCapacity (allocator , 0 );
114
+ defer fortunes .deinit (allocator );
115
115
116
116
while (try rows .next ()) | row | {
117
117
const current_fortune = Fortune { .id = row .get (i32 , 0 ), .message = row .get ([]const u8 , 1 ) };
118
- try fortunes .append (current_fortune );
118
+ try fortunes .append (allocator , current_fortune );
119
119
}
120
120
121
121
const zero_fortune = Fortune { .id = 0 , .message = "Additional fortune added at request time." };
122
- try fortunes .append (zero_fortune );
122
+ try fortunes .append (allocator , zero_fortune );
123
123
124
- const fortunes_slice = try fortunes .toOwnedSlice ();
124
+ const fortunes_slice = try fortunes .toOwnedSlice (allocator );
125
125
std .mem .sort (Fortune , fortunes_slice , {}, cmpFortuneByMessage );
126
126
127
127
return fortunes_slice ;
@@ -131,53 +131,17 @@ fn cmpFortuneByMessage(_: void, a: Fortune, b: Fortune) bool {
131
131
return std .mem .order (u8 , a .message , b .message ).compare (std .math .CompareOperator .lt );
132
132
}
133
133
134
- fn deescapeHtml (allocator : std.mem.Allocator , input : []const u8 ) ! []const u8 {
135
- var output = std .ArrayList (u8 ).init (allocator );
136
- defer output .deinit ();
137
-
138
- var i : usize = 0 ;
139
- while (i < input .len ) {
140
- if (std .mem .startsWith (u8 , input [i .. ], " " )) {
141
- try output .append (' ' );
142
- i += 5 ;
143
- } else if (std .mem .startsWith (u8 , input [i .. ], """ )) {
144
- try output .append ('"' );
145
- i += 5 ;
146
- } else if (std .mem .startsWith (u8 , input [i .. ], "&" )) {
147
- try output .append ('&' );
148
- i += 5 ;
149
- } else if (std .mem .startsWith (u8 , input [i .. ], "'" )) {
150
- try output .append ('\' ' );
151
- i += 5 ;
152
- } else if (std .mem .startsWith (u8 , input [i .. ], "(" )) {
153
- try output .append ('(' );
154
- i += 5 ;
155
- } else if (std .mem .startsWith (u8 , input [i .. ], ")" )) {
156
- try output .append (')' );
157
- i += 5 ;
158
- } else if (std .mem .startsWith (u8 , input [i .. ], "+" )) {
159
- try output .append ('+' );
160
- i += 5 ;
161
- } else if (std .mem .startsWith (u8 , input [i .. ], "," )) {
162
- try output .append (',' );
163
- i += 5 ;
164
- } else if (std .mem .startsWith (u8 , input [i .. ], "." )) {
165
- try output .append ('.' );
166
- i += 5 ;
167
- } else if (std .mem .startsWith (u8 , input [i .. ], "/" )) {
168
- try output .append ('/' );
169
- i += 5 ;
170
- } else if (std .mem .startsWith (u8 , input [i .. ], ":" )) {
171
- try output .append (':' );
172
- i += 5 ;
173
- } else if (std .mem .startsWith (u8 , input [i .. ], ";" )) {
174
- try output .append (';' );
175
- i += 5 ;
176
- } else {
177
- try output .append (input [i ]);
178
- i += 1 ;
134
+ fn escape_html (allocator : std.mem.Allocator , input : []const u8 ) ! []const u8 {
135
+ var output = try std .ArrayListUnmanaged (u8 ).initCapacity (allocator , 0 );
136
+ defer output .deinit (allocator );
137
+
138
+ for (input ) | char | {
139
+ switch (char ) {
140
+ '<' = > try output .appendSlice (allocator , "<" ),
141
+ '>' = > try output .appendSlice (allocator , ">" ),
142
+ else = > try output .append (allocator , char ),
179
143
}
180
144
}
181
145
182
- return output .toOwnedSlice ();
146
+ return output .toOwnedSlice (allocator );
183
147
}
0 commit comments