Differences From
Artifact [0ea1a47601]:
1 1 -- vim: ft=terra
2 +local pstring = lib.mem.ptr(int8)
3 +local binblob = lib.mem.ptr(uint8)
2 4 local queries = {
3 5 conf_get = {
4 6 params = {rawstring}, sql = [[
5 7 select value from parsav_config
6 8 where key = $1::text limit 1
7 9 ]];
8 10 };
................................................................................
20 22 delete from parsav_config where
21 23 key = $1::text
22 24 ]];
23 25 };
24 26
25 27 actor_fetch_uid = {
26 28 params = {uint64}, sql = [[
27 - select
28 - id, nym, handle, origin, bio,
29 - avataruri, rank, quota, key,
30 - extract(epoch from knownsince)::bigint
29 + select a.id, a.nym, a.handle, a.origin, a.bio,
30 + a.avataruri, a.rank, a.quota, a.key,
31 + extract(epoch from a.knownsince)::bigint,
32 + coalesce(a.handle || '@' || s.domain,
33 + '@' || a.handle) as xid
31 34
32 - from parsav_actors
33 - where id = $1::bigint
35 + from parsav_actors as a
36 + left join parsav_servers as s
37 + on a.origin = s.id
38 + where a.id = $1::bigint
34 39 ]];
35 40 };
36 41
37 42 actor_fetch_xid = {
38 - params = {lib.mem.ptr(int8)}, sql = [[
43 + params = {pstring}, sql = [[
39 44 select a.id, a.nym, a.handle, a.origin, a.bio,
40 45 a.avataruri, a.rank, a.quota, a.key,
41 - extract(epoch from knownsince)::bigint,
46 + extract(epoch from a.knownsince)::bigint,
42 47 coalesce(a.handle || '@' || s.domain,
43 48 '@' || a.handle) as xid,
44 49
45 50 coalesce(s.domain,
46 51 (select value from parsav_config
47 52 where key='domain' limit 1)) as domain
48 53
................................................................................
55 60 (a.origin is null and
56 61 $1::text = a.handle or
57 62 $1::text = ('@' || a.handle))
58 63 ]];
59 64 };
60 65
61 66 actor_auth_pw = {
62 - params = {lib.mem.ptr(int8),rawstring,lib.mem.ptr(int8),lib.store.inet}, sql = [[
67 + params = {pstring,rawstring,pstring,lib.store.inet}, sql = [[
63 68 select a.aid from parsav_auth as a
64 69 left join parsav_actors as u on u.id = a.uid
65 70 where (a.uid is null or u.handle = $1::text or (
66 71 a.uid = 0 and a.name = $1::text
67 72 )) and
68 73 (a.kind = 'trust' or (a.kind = $2::text and a.cred = $3::bytea)) and
69 74 (a.netmask is null or a.netmask >> $4::inet)
................................................................................
83 88 ]];
84 89 };
85 90
86 91 actor_enum = {
87 92 params = {}, sql = [[
88 93 select a.id, a.nym, a.handle, a.origin, a.bio,
89 94 a.avataruri, a.rank, a.quota, a.key,
90 - extract(epoch from knownsince)::bigint,
95 + extract(epoch from a.knownsince)::bigint,
91 96 coalesce(a.handle || '@' || s.domain,
92 97 '@' || a.handle) as xid
93 98 from parsav_actors a
94 99 left join parsav_servers s on s.id = a.origin
95 100 ]];
96 101 };
97 102
................................................................................
136 141 ]]; -- cheat
137 142 };
138 143
139 144 actor_session_fetch = {
140 145 params = {uint64, lib.store.inet}, sql = [[
141 146 select a.id, a.nym, a.handle, a.origin, a.bio,
142 147 a.avataruri, a.rank, a.quota, a.key,
143 - extract(epoch from knownsince)::bigint,
148 + extract(epoch from a.knownsince)::bigint,
144 149 coalesce(a.handle || '@' || s.domain,
145 150 '@' || a.handle) as xid,
146 151
147 152 au.restrict,
148 153 array['post' ] <@ au.restrict as can_post,
149 154 array['edit' ] <@ au.restrict as can_edit,
150 155 array['acct' ] <@ au.restrict as can_acct,
................................................................................
156 161 left join parsav_actors a on au.uid = a.id
157 162 left join parsav_servers s on a.origin = s.id
158 163
159 164 where au.aid = $1::bigint and au.blacklist = false and
160 165 (au.netmask is null or au.netmask >> $2::inet)
161 166 ]];
162 167 };
168 +
169 + post_create = {
170 + params = {uint64, rawstring, rawstring, rawstring}, sql = [[
171 + insert into parsav_posts (
172 + author, subject, acl, body,
173 + posted, discovered,
174 + circles, mentions
175 + ) values (
176 + $1::bigint, case when $2::text = '' then null else $2::text end,
177 + $3::text, $4::text,
178 + now(), now(), array[]::bigint[], array[]::bigint[]
179 + ) returning id
180 + ]]; -- TODO array handling
181 + };
182 +
183 + instance_timeline_fetch = {
184 + params = {uint64, uint64, uint64, uint64}, sql = [[
185 + select true,
186 + p.id, p.author, p.subject, p.acl, p.body,
187 + extract(epoch from p.posted )::bigint,
188 + extract(epoch from p.discovered)::bigint,
189 + p.parent, null::text
190 + from parsav_posts as p
191 + inner join parsav_actors as a on p.author = a.id
192 + where
193 + ($1::bigint = 0 or p.posted <= to_timestamp($1::bigint)) and
194 + ($2::bigint = 0 or to_timestamp($2::bigint) < p.posted) and
195 + (a.origin is null)
196 + order by (p.posted, p.discovered) desc
197 + limit case when $3::bigint = 0 then null
198 + else $3::bigint end
199 + offset $4::bigint
200 + ]]
201 + };
163 202 }
203 + --($5::bool = false or p.parent is null) and
164 204
165 205 local struct pqr {
166 206 sz: intptr
167 207 res: &lib.pq.PGresult
168 208 }
169 209 terra pqr:free() if self.sz > 0 then lib.pq.PQclear(self.res) end end
170 210 terra pqr:null(row: intptr, col: intptr)
................................................................................
278 318 ;[pqt[lib.store.inet](false)]([args[i]], [&uint8](&ipbuf))
279 319 in &ipbuf[0] end
280 320 dumpers[#dumpers+1] = `lib.io.fmt([tostring(i)..'. got inet\n'])
281 321 elseif ty.ptr_basetype == int8 or ty.ptr_basetype == uint8 then
282 322 counters[i] = `[args[i]].ct
283 323 casts[i] = `[&int8]([args[i]].ptr)
284 324 dumpers[#dumpers+1] = `lib.io.fmt([tostring(i)..'. got ptr %llu %.*s\n'], [args[i]].ct, [args[i]].ct, [args[i]].ptr)
325 + elseif ty.ptr_basetype == bool then
326 + counters[i] = `1
327 + casts[i] = `[&int8]([args[i]].ptr)
328 + -- dumpers[#dumpers+1] = `lib.io.fmt([tostring(i)..'. got bool = %hhu\n'], @[args[i]].ptr)
285 329 elseif ty:isintegral() then
286 330 counters[i] = ty.bytes
287 331 casts[i] = `[&int8](&[args[i]])
288 332 dumpers[#dumpers+1] = `lib.io.fmt([tostring(i)..'. got int %llu\n'], [args[i]])
289 333 fixers[#fixers + 1] = quote
290 - --lib.io.fmt('uid=%llu(%llx)\n',[args[i]],[args[i]])
291 334 [args[i]] = lib.math.netswap(ty, [args[i]])
292 335 end
293 336 end
294 337 end
295 338
296 339 terra q.exec(src: &lib.store.source, [args])
297 340 var params = arrayof([&int8], [casts])
................................................................................
314 357 return pqr {0, nil}
315 358 else
316 359 return pqr {ct, res}
317 360 end
318 361 end
319 362 end
320 363
364 +local terra row_to_post(r: &pqr, row: intptr): lib.mem.ptr(lib.store.post)
365 + --lib.io.fmt("body ptr %p len %llu\n", r:string(row,5), r:len(row,5))
366 + --lib.io.fmt("acl ptr %p len %llu\n", r:string(row,4), r:len(row,4))
367 + var subj: rawstring, sblen: intptr
368 + if r:null(row,3)
369 + then subj = nil sblen = 0
370 + else subj = r:string(row,3) sblen = r:len(row,3)+1
371 + end
372 + var p = [ lib.str.encapsulate(lib.store.post, {
373 + subject = { `subj, `sblen };
374 + acl = {`r:string(row,4), `r:len(row,4)+1};
375 + body = {`r:string(row,5), `r:len(row,5)+1};
376 + --convoheaduri = { `nil, `0 }; --FIXME
377 + }) ]
378 + p.ptr.id = r:int(uint64,row,1)
379 + p.ptr.author = r:int(uint64,row,2)
380 + p.ptr.posted = r:int(uint64,row,6)
381 + p.ptr.discovered = r:int(uint64,row,7)
382 + if r:null(row,8)
383 + then p.ptr.parent = 0
384 + else p.ptr.parent = r:int(uint64,row,8)
385 + end
386 + p.ptr.localpost = r:bool(row,0)
387 +
388 + return p
389 +end
321 390 local terra row_to_actor(r: &pqr, row: intptr): lib.mem.ptr(lib.store.actor)
322 391 var a: lib.mem.ptr(lib.store.actor)
323 -
324 - if r:cols() >= 9 then
325 - a = [ lib.str.encapsulate(lib.store.actor, {
326 - nym = {`r:string(row,1), `r:len(row,1)+1};
327 - bio = {`r:string(row,4), `r:len(row,4)+1};
328 - avatar = {`r:string(row,5), `r:len(row,5)+1};
329 - handle = {`r:string(row, 2); `r:len(row,2) + 1};
330 - xid = {`r:string(row, 10); `r:len(row,10) + 1};
331 - }) ]
332 - else
333 - a = [ lib.str.encapsulate(lib.store.actor, {
334 - nym = {`r:string(row,1), `r:len(row,1)+1};
335 - bio = {`r:string(row,4), `r:len(row,4)+1};
336 - avatar = {`r:string(row,5), `r:len(row,5)+1};
337 - handle = {`r:string(row, 2); `r:len(row,2) + 1};
338 - }) ]
339 - a.ptr.xid = nil
392 + var av: rawstring, avlen: intptr
393 + var nym: rawstring, nymlen: intptr
394 + var bio: rawstring, biolen: intptr
395 + if r:null(row,5) then avlen = 0 av = nil else
396 + av = r:string(row,5)
397 + avlen = r:len(row,5)+1
398 + end
399 + if r:null(row,1) then nymlen = 0 nym = nil else
400 + nym = r:string(row,1)
401 + nymlen = r:len(row,1)+1
402 + end
403 + if r:null(row,4) then biolen = 0 bio = nil else
404 + bio = r:string(row,4)
405 + biolen = r:len(row,4)+1
340 406 end
407 + a = [ lib.str.encapsulate(lib.store.actor, {
408 + nym = {`nym, `nymlen};
409 + bio = {`bio, `biolen};
410 + avatar = {`av,`avlen};
411 + handle = {`r:string(row, 2); `r:len(row,2) + 1};
412 + xid = {`r:string(row, 10); `r:len(row,10) + 1};
413 + }) ]
341 414 a.ptr.id = r:int(uint64, row, 0);
342 415 a.ptr.rights = lib.store.rights_default();
343 416 a.ptr.rights.rank = r:int(uint16, row, 6);
344 417 a.ptr.rights.quota = r:int(uint32, row, 7);
345 418 a.ptr.knownsince = r:int(int64,row, 9);
346 419 if r:null(row,8) then
347 420 a.ptr.key.ct = 0 a.ptr.key.ptr = nil
................................................................................
550 623
551 624 return au, a
552 625 end
553 626
554 627 ::fail:: return [lib.stat (lib.store.auth) ] { ok = false },
555 628 [lib.mem.ptr(lib.store.actor)] { ptr = nil, ct = 0 }
556 629 end];
630 +
631 + post_create = [terra(
632 + src: &lib.store.source,
633 + post: &lib.store.post
634 + ): uint64
635 + var r = queries.post_create.exec(src,post.author,post.subject,post.acl,post.body)
636 + if r.sz == 0 then return 0 end
637 + defer r:free()
638 + var id = r:int(uint64,0,0)
639 + return id
640 + end];
641 +
642 + instance_timeline_fetch = [terra(src: &lib.store.source, rg: lib.store.range)
643 + var r = pqr { sz = 0 }
644 + if rg.mode == 0 then
645 + r = queries.instance_timeline_fetch.exec(src,rg.from_time,rg.to_time,0,0)
646 + elseif rg.mode == 1 then
647 + r = queries.instance_timeline_fetch.exec(src,rg.from_time,0,rg.to_idx,0)
648 + elseif rg.mode == 2 then
649 + r = queries.instance_timeline_fetch.exec(src,0,rg.to_time,0,rg.from_idx)
650 + elseif rg.mode == 3 then
651 + r = queries.instance_timeline_fetch.exec(src,0,0,rg.to_idx,rg.from_idx)
652 + end
653 +
654 + var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
655 + for i=0,r.sz do ret.ptr[i] = row_to_post(&r, i) end -- MUST FREE ALL
656 +
657 + return ret
658 + end];
557 659 }
558 660
559 661 return b