Differences From
Artifact [d54604496b]:
167 167
168 168 values (
169 169 (select count(tweets.*)::bigint from tweets),
170 170 (select count(follows.*)::bigint from follows),
171 171 (select count(followers.*)::bigint from followers),
172 172 (select count(mutuals.*)::bigint from mutuals)
173 173 )
174 - ]]):gsub('<(%w+)>',function(r) return tostring(lib.store.relation[r]) end)
174 + ]]):gsub('<(%w+)>',function(r) return tostring(lib.store.relation.idvmap[r]) end)
175 175 };
176 176
177 177 actor_auth_how = {
178 178 params = {rawstring, lib.store.inet}, sql = [[
179 179 with mts as (select a.kind from parsav_auth as a
180 180 left join parsav_actors as u on u.id = a.uid
181 181 where (a.uid is null or u.handle = $1::text or (
................................................................................
189 189 (select count(*) from mts where kind like 'otp-%') > 0,
190 190 (select count(*) from mts where kind like 'challenge-%') > 0,
191 191 (select count(*) from mts where kind = 'trust') > 0
192 192 ]]; -- cheat
193 193 };
194 194
195 195 actor_session_fetch = {
196 - params = {uint64, lib.store.inet}, sql = [[
196 + params = {uint64, lib.store.inet, int64}, sql = [[
197 197 select a.id, a.nym, a.handle, a.origin, a.bio,
198 198 a.avataruri, a.rank, a.quota, a.key, a.epithet,
199 199 extract(epoch from a.knownsince)::bigint,
200 200 coalesce(a.handle || '@' || s.domain,
201 201 '@' || a.handle) as xid,
202 202
203 203 au.restrict,
................................................................................
209 209 array['admin' ] <@ au.restrict as can_admin
210 210
211 211 from parsav_auth au
212 212 left join parsav_actors a on au.uid = a.id
213 213 left join parsav_servers s on a.origin = s.id
214 214
215 215 where au.aid = $1::bigint and au.blacklist = false and
216 - (au.netmask is null or au.netmask >> $2::inet)
216 + (au.netmask is null or au.netmask >> $2::inet) and
217 + ($3::bigint = 0 or --slightly abusing the epoch time fmt here, but
218 + ((a.authtime is null or a.authtime <= to_timestamp($3::bigint)) and
219 + (au.valperiod is null or au.valperiod <= to_timestamp($3::bigint))))
217 220 ]];
218 221 };
219 222
220 223 actor_powers_fetch = {
221 224 params = {uint64}, sql = [[
222 225 select key, allow from parsav_rights where actor = $1::bigint
223 226 ]]
................................................................................
234 237 actor_power_delete = {
235 238 params = {uint64,lib.mem.ptr(int8)}, cmd = true, sql = [[
236 239 delete from parsav_rights where
237 240 actor = $1::bigint and
238 241 key = $2::text
239 242 ]]
240 243 };
244 +
245 + auth_sigtime_user_fetch = {
246 + params = {uint64}, sql = [[
247 + select extract(epoch from authtime)::bigint
248 + from parsav_actors where id = $1::bigint
249 + ]];
250 + };
251 +
252 + auth_sigtime_user_alter = {
253 + params = {uint64,int64}, cmd = true, sql = [[
254 + update parsav_actors set
255 + authtime = to_timestamp($2::bigint)
256 + where id = $1::bigint
257 + ]];
258 + };
241 259
242 260 auth_create_pw = {
243 261 params = {uint64, lib.mem.ptr(uint8)}, cmd = true, sql = [[
244 262 insert into parsav_auth (uid, name, kind, cred) values (
245 263 $1::bigint,
246 264 (select handle from parsav_actors where id = $1::bigint),
247 265 'pw-sha256', $2::bytea
................................................................................
252 270 auth_purge_type = {
253 271 params = {rawstring, uint64, rawstring}, cmd = true, sql = [[
254 272 delete from parsav_auth where
255 273 ((uid = 0 and name = $1::text) or uid = $2::bigint) and
256 274 kind like $3::text
257 275 ]]
258 276 };
277 +
278 + post_save = {
279 + params = {
280 + uint64, uint32, int64;
281 + rawstring, rawstring, rawstring;
282 + }, cmd = true, sql = [[
283 + update parsav_posts set
284 + subject = $4::text,
285 + acl = $5::text,
286 + body = $6::text,
287 + chgcount = $2::integer,
288 + edited = to_timestamp($3::bigint)
289 + where id = $1::bigint
290 + ]]
291 + };
259 292
260 293 post_create = {
261 294 params = {uint64, rawstring, rawstring, rawstring}, sql = [[
262 295 insert into parsav_posts (
263 296 author, subject, acl, body,
264 297 posted, discovered,
265 298 circles, mentions
................................................................................
266 299 ) values (
267 300 $1::bigint, case when $2::text = '' then null else $2::text end,
268 301 $3::text, $4::text,
269 302 now(), now(), array[]::bigint[], array[]::bigint[]
270 303 ) returning id
271 304 ]]; -- TODO array handling
272 305 };
306 +
307 + post_fetch = {
308 + params = {uint64}, sql = [[
309 + select a.origin is null,
310 + p.id, p.author, p.subject, p.acl, p.body,
311 + extract(epoch from p.posted )::bigint,
312 + extract(epoch from p.discovered)::bigint,
313 + extract(epoch from p.edited )::bigint,
314 + p.parent, p.convoheaduri, p.chgcount
315 + from parsav_posts as p
316 + inner join parsav_actors as a on p.author = a.id
317 + where p.id = $1::bigint
318 + ]];
319 + };
273 320
274 321 post_enum_author_uid = {
275 322 params = {uint64,uint64,uint64,uint64, uint64}, sql = [[
276 323 select a.origin is null,
277 324 p.id, p.author, p.subject, p.acl, p.body,
278 325 extract(epoch from p.posted )::bigint,
279 326 extract(epoch from p.discovered)::bigint,
280 - p.parent, p.convoheaduri
327 + extract(epoch from p.edited )::bigint,
328 + p.parent, p.convoheaduri, p.chgcount
281 329 from parsav_posts as p
282 330 inner join parsav_actors as a on p.author = a.id
283 331 where p.author = $5::bigint and
284 332 ($1::bigint = 0 or p.posted <= to_timestamp($1::bigint)) and
285 333 ($2::bigint = 0 or to_timestamp($2::bigint) < p.posted)
286 334 order by (p.posted, p.discovered) desc
287 335 limit case when $3::bigint = 0 then null
................................................................................
294 342
295 343 timeline_instance_fetch = {
296 344 params = {uint64, uint64, uint64, uint64}, sql = [[
297 345 select true,
298 346 p.id, p.author, p.subject, p.acl, p.body,
299 347 extract(epoch from p.posted )::bigint,
300 348 extract(epoch from p.discovered)::bigint,
301 - p.parent, null::text
349 + extract(epoch from p.edited )::bigint,
350 + p.parent, null::text, p.chgcount
302 351 from parsav_posts as p
303 352 inner join parsav_actors as a on p.author = a.id
304 353 where
305 354 ($1::bigint = 0 or p.posted <= to_timestamp($1::bigint)) and
306 355 ($2::bigint = 0 or to_timestamp($2::bigint) < p.posted) and
307 356 (a.origin is null)
308 357 order by (p.posted, p.discovered) desc
................................................................................
565 614 local terra row_to_post(r: &pqr, row: intptr): lib.mem.ptr(lib.store.post)
566 615 var subj: rawstring, sblen: intptr
567 616 var cvhu: rawstring, cvhlen: intptr
568 617 if r:null(row,3)
569 618 then subj = nil sblen = 0
570 619 else subj = r:string(row,3) sblen = r:len(row,3)+1
571 620 end
572 - if r:null(row,9)
621 + if r:null(row,10)
573 622 then cvhu = nil cvhlen = 0
574 - else cvhu = r:string(row,9) cvhlen = r:len(row,9)+1
623 + else cvhu = r:string(row,10) cvhlen = r:len(row,10)+1
575 624 end
576 625 var p = [ lib.str.encapsulate(lib.store.post, {
577 626 subject = { `subj, `sblen };
578 627 acl = {`r:string(row,4), `r:len(row,4)+1};
579 628 body = {`r:string(row,5), `r:len(row,5)+1};
580 629 convoheaduri = { `cvhu, `cvhlen }; --FIXME
581 630 }) ]
582 631 p.ptr.id = r:int(uint64,row,1)
583 632 p.ptr.author = r:int(uint64,row,2)
584 633 p.ptr.posted = r:int(uint64,row,6)
585 634 p.ptr.discovered = r:int(uint64,row,7)
586 - if r:null(row,8)
635 + p.ptr.edited = r:int(uint64,row,8)
636 + if r:null(row,9)
587 637 then p.ptr.parent = 0
588 - else p.ptr.parent = r:int(uint64,row,8)
638 + else p.ptr.parent = r:int(uint64,row,9)
639 + end
640 + if r:null(row,11)
641 + then p.ptr.chgcount = 0
642 + else p.ptr.chgcount = r:int(uint32,row,11)
589 643 end
590 644 p.ptr.localpost = r:bool(row,0)
591 645
592 646 return p
593 647 end
594 648 local terra row_to_actor(r: &pqr, row: intptr): lib.mem.ptr(lib.store.actor)
595 649 var a: lib.mem.ptr(lib.store.actor)
................................................................................
918 972 s.mutuals = r:int(uint64, 0, 3)
919 973 return s
920 974 end];
921 975
922 976 actor_session_fetch = [terra(
923 977 src: &lib.store.source,
924 978 aid: uint64,
925 - ip : lib.store.inet
979 + ip : lib.store.inet,
980 + issuetime: lib.store.timepoint
926 981 ): { lib.stat(lib.store.auth), lib.mem.ptr(lib.store.actor) }
927 - var r = queries.actor_session_fetch.exec(src, aid, ip)
982 + var r = queries.actor_session_fetch.exec(src, aid, ip, issuetime)
928 983 if r.sz == 0 then goto fail end
929 984 do defer r:free()
930 985
931 986 if r:null(0,0) then goto fail end
932 987
933 988 var a = row_to_actor(&r, 0)
934 989 a.ptr.source = src
................................................................................
959 1014 ): uint64
960 1015 var r = queries.post_create.exec(src,post.author,post.subject,post.acl,post.body)
961 1016 if r.sz == 0 then return 0 end
962 1017 defer r:free()
963 1018 var id = r:int(uint64,0,0)
964 1019 return id
965 1020 end];
1021 +
1022 + post_fetch = [terra(
1023 + src: &lib.store.source,
1024 + post: uint64
1025 + ): lib.mem.ptr(lib.store.post)
1026 + var r = queries.post_fetch.exec(src, post)
1027 + if r.sz == 0 then return [lib.mem.ptr(lib.store.post)].null() end
1028 + var p = row_to_post(&r, 0)
1029 + p.ptr.source = src
1030 + return p
1031 + end];
966 1032
967 1033 timeline_instance_fetch = [terra(src: &lib.store.source, rg: lib.store.range)
968 1034 var r = pqr { sz = 0 }
969 1035 var A,B,C,D = rg:matrix() -- :/
970 1036 r = queries.timeline_instance_fetch.exec(src,A,B,C,D)
971 1037
972 1038 var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
................................................................................
1106 1172 detach: bool
1107 1173 ): {}
1108 1174 if detach
1109 1175 then queries.post_attach_ctl_del.exec(src,post,artifact)
1110 1176 else queries.post_attach_ctl_ins.exec(src,post,artifact)
1111 1177 end
1112 1178 end];
1179 +
1180 + post_save = [terra(
1181 + src: &lib.store.source,
1182 + post: &lib.store.post
1183 + ): {}
1184 + queries.post_save.exec(src,
1185 + post.id, post.chgcount, post.edited,
1186 + post.subject, post.acl, post.body)
1187 + end];
1188 +
1189 + auth_sigtime_user_fetch = [terra(
1190 + src: &lib.store.source,
1191 + uid: uint64
1192 + ): lib.store.timepoint
1193 + var r = queries.auth_sigtime_user_fetch.exec(src, uid)
1194 + if r.sz > 0 then defer r:free()
1195 + var t = r:int(int64,0,0)
1196 + return t
1197 + else return 0 end
1198 + end];
1199 +
1200 + auth_sigtime_user_alter = [terra(
1201 + src: &lib.store.source,
1202 + uid: uint64,
1203 + time: lib.store.timepoint
1204 + ): {} queries.auth_sigtime_user_alter.exec(src, uid, time) end];
1113 1205
1114 1206 actor_auth_register_uid = nil; -- TODO better support non-view based auth
1115 1207 }
1116 1208
1117 1209 return b