@@ -2,16 +2,12 @@ const std = @import("std");
22const httpz = @import ("httpz" );
33const pg = @import ("pg" );
44const datetimez = @import ("datetimez" );
5- const mustache = @import ("mustache" );
65
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 = "" ;
107
118pub const Global = struct {
129 pool : * pg.Pool ,
1310 rand : * std.rand.Random ,
14- mutex : std.Thread.Mutex = .{},
1511};
1612
1713const World = struct {
@@ -40,9 +36,7 @@ pub fn json(_: *Global, _: *httpz.Request, res: *httpz.Response) !void {
4036pub fn db (global : * Global , _ : * httpz.Request , res : * httpz.Response ) ! void {
4137 try setHeaders (res .arena , res );
4238
43- global .mutex .lock ();
4439 const random_number = 1 + (global .rand .uintAtMostBiased (u32 , 9999 ));
45- global .mutex .unlock ();
4640
4741 const world = getWorld (global .pool , random_number ) catch | err | {
4842 std .debug .print ("Error querying database: {}\n " , .{err });
@@ -76,31 +70,37 @@ fn getWorld(pool: *pg.Pool, random_number: u32) !World {
7670fn setHeaders (allocator : std.mem.Allocator , res : * httpz.Response ) ! void {
7771 res .header ("Server" , "Httpz" );
7872
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();
8175
8276 // Wed, 17 Apr 2013 12:00:00 GMT
8377 // 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 });
8680
8781 //defer allocator.free(now_str);
8882
89- res .header ("Date" , now_str );
83+ res .header ("Date" , try allocator . dupe ( u8 , date_str ) );
9084}
9185
9286fn getFortunesHtml (allocator : std.mem.Allocator , pool : * pg.Pool ) ! []const u8 {
9387 const fortunes = try getFortunes (allocator , pool );
9488
95- const raw = try mustache . allocRenderText ( allocator , template , .{ . fortunes = fortunes } );
89+ var sb = try std . ArrayListUnmanaged ( u8 ). initCapacity ( allocator , 0 );
9690
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>" );
9893
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+ }
100100
101- // std.debug.print("html output {s}\n", .{ html} );
101+ try sb . appendSlice ( allocator , "</table></body></ html>" );
102102
103- return html ;
103+ return sb . toOwnedSlice ( allocator ) ;
104104}
105105
106106fn 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 {
110110 var rows = try conn .query ("SELECT id, message FROM Fortune" , .{});
111111 defer rows .deinit ();
112112
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 );
115115
116116 while (try rows .next ()) | row | {
117117 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 );
119119 }
120120
121121 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 );
123123
124- const fortunes_slice = try fortunes .toOwnedSlice ();
124+ const fortunes_slice = try fortunes .toOwnedSlice (allocator );
125125 std .mem .sort (Fortune , fortunes_slice , {}, cmpFortuneByMessage );
126126
127127 return fortunes_slice ;
@@ -131,53 +131,17 @@ fn cmpFortuneByMessage(_: void, a: Fortune, b: Fortune) bool {
131131 return std .mem .order (u8 , a .message , b .message ).compare (std .math .CompareOperator .lt );
132132}
133133
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 ),
179143 }
180144 }
181145
182- return output .toOwnedSlice ();
146+ return output .toOwnedSlice (allocator );
183147}
0 commit comments