parsav  Diff

Differences From Artifact [962a3e64e0]:

To Artifact [2e62d4947d]:


213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
349
350
351
352
353
354
355






356
357
358
359
360
361
362


363
364
365
366
367
368
369
370
371
372






373
374
375
376
377
378
379


380
381
382
383
384
385
386
...
401
402
403
404
405
406
407
408


























409
410

























411
412
413
414
415
416
417
418
419


420
421
422
423
424

425
426
427
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454










455
456
457
458
459
460
461
...
792
793
794
795
796
797
798




799
800
801
802
803
804
805
....
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
....
1211
1212
1213
1214
1215
1216
1217


































1218
1219
1220
1221
1222
1223
1224
			select a.id, a.nym, a.handle, a.origin, a.bio,
			       a.avataruri, a.rank, a.quota, a.key, a.epithet,
			       extract(epoch from a.knownsince)::bigint,
				   coalesce(a.handle || '@' || s.domain,
				            '@' || a.handle) as xid,

			       au.restrict,
						array['post'  ] <@ au.restrict as can_post,
						array['edit'  ] <@ au.restrict as can_edit,
						array['acct'  ] <@ au.restrict as can_acct,
						array['upload'] <@ au.restrict as can_upload,
						array['censor'] <@ au.restrict as can_censor,
						array['admin' ] <@ au.restrict as can_admin

			from      parsav_auth au
			left join parsav_actors a     on au.uid = a.id
			left join parsav_servers s    on a.origin = s.id

			where au.aid = $1::bigint and au.blacklist = false and
				(au.netmask is null or au.netmask >> $2::inet) and
................................................................................
		params = {uint64}, cmd = true, sql = [[
			delete from parsav_posts where id = $1::bigint
		]]
	};
	
	post_fetch = {
		params = {uint64}, sql = [[






			select a.origin is null,
				p.id, p.author, p.subject, p.acl, p.body,
				extract(epoch from p.posted    )::bigint,
				extract(epoch from p.discovered)::bigint,
				extract(epoch from p.edited    )::bigint,
				p.parent, p.convoheaduri, p.chgcount,
				coalesce(c.value, -1)::smallint



			from parsav_posts as p
				inner join parsav_actors          as a on p.author = a.id
				left join  parsav_actor_conf_ints as c on c.uid    = a.id and c.key = 'ui-accent'
			where p.id = $1::bigint
		]];
	};

	post_enum_parent = {
		params = {uint64}, sql = [[






			select a.origin is null,
				p.id, p.author, p.subject, p.acl, p.body,
				extract(epoch from p.posted    )::bigint,
				extract(epoch from p.discovered)::bigint,
				extract(epoch from p.edited    )::bigint,
				p.parent, p.convoheaduri, p.chgcount,
				coalesce(c.value, -1)::smallint



			from parsav_posts as p
				inner join parsav_actors as a on a.id = p.author
				left join  parsav_actor_conf_ints as c on c.uid = a.id and c.key = 'ui-accent'
			where p.parent = $1::bigint
			order by p.posted, p.discovered asc
		]]
................................................................................
					inner join parsav_posts as p
						on p.id = posts.id
			)

			select extract(epoch from max(m))::bigint from maxes
		]];
	};



























	post_enum_author_uid = {
		params = {uint64,uint64,uint64,uint64, uint64}, sql = [[

























			select a.origin is null,
				p.id, p.author, p.subject, p.acl, p.body,
				extract(epoch from p.posted    )::bigint,
				extract(epoch from p.discovered)::bigint,
				extract(epoch from p.edited    )::bigint,
				p.parent, p.convoheaduri, p.chgcount,
				coalesce((select value from parsav_actor_conf_ints as c where
					c.uid = $1::bigint and c.key = 'ui-accent'),-1)::smallint



			from parsav_posts as p
				inner join parsav_actors as a on p.author = a.id
			where p.author = $5::bigint and
				($1::bigint = 0 or p.posted <= to_timestamp($1::bigint)) and
				($2::bigint = 0 or to_timestamp($2::bigint) < p.posted)

			order by (p.posted, p.discovered) desc
			limit case when $3::bigint = 0 then null
			           else $3::bigint end
			offset $4::bigint
		]]
	};

	-- maybe there's some way to unify these two, idk, im tired

	timeline_instance_fetch = {
		params = {uint64, uint64, uint64, uint64}, sql = [[

			select true,
				p.id, p.author, p.subject, p.acl, p.body,
				extract(epoch from p.posted    )::bigint,
				extract(epoch from p.discovered)::bigint,
				extract(epoch from p.edited    )::bigint,
				p.parent, null::text, p.chgcount,
				coalesce(c.value, -1)::smallint

			from parsav_posts as p
				inner join parsav_actors          as a on p.author = a.id
				left join  parsav_actor_conf_ints as c on c.uid    = a.id and c.key = 'ui-accent'
			where
				($1::bigint = 0 or p.posted <= to_timestamp($1::bigint)) and
				($2::bigint = 0 or to_timestamp($2::bigint) < p.posted) and
				(a.origin is null)
			order by (p.posted, p.discovered) desc
			limit case when $3::bigint = 0 then null
			           else $3::bigint end
			offset $4::bigint










		]]
	};

	artifact_instantiate = {
		params = {binblob, binblob, pstring}, sql = [[
			insert into parsav_artifacts (content,hash,mime) values (
				$1::bytea, $2::bytea, $3::text
................................................................................
	end
	p.ptr.parent = r:int(uint64,row,9)
	if r:null(row,11)
		then p.ptr.chgcount = 0
		else p.ptr.chgcount = r:int(uint32,row,11)
	end 
	p.ptr.accent = r:int(int16,row,12)




	p.ptr.localpost = r:bool(row,0)

	return p
end
local terra row_to_actor(r: &pqr, row: intptr): lib.mem.ptr(lib.store.actor)
	var a: lib.mem.ptr(lib.store.actor)
	var av: rawstring, avlen: intptr
................................................................................
			a.ptr.source = src

			var au = [lib.stat(lib.store.auth)] { ok = true }
			au.val.aid = aid
			au.val.uid = a.ptr.id
			if not r:null(0,14) then -- restricted?
				au.val.privs:clear()
				(au.val.privs.post   << r:bool(0,15)) 
				(au.val.privs.edit   << r:bool(0,16))
				(au.val.privs.acct   << r:bool(0,17))
				(au.val.privs.upload << r:bool(0,18))
				(au.val.privs.censor << r:bool(0,19))
				(au.val.privs.admin  << r:bool(0,20))
			else au.val.privs:fill() end

			return au, a
		end

		::fail:: return [lib.stat   (lib.store.auth) ] { ok = false        },
			            [lib.mem.ptr(lib.store.actor)] { ptr = nil, ct = 0 }
................................................................................
	): lib.mem.ptr(lib.store.post)
		var r = queries.post_fetch.exec(src, post)
		if r.sz == 0 then return [lib.mem.ptr(lib.store.post)].null() end
		var p = row_to_post(&r, 0)
		p.ptr.source = src
		return p
	end];



































	timeline_instance_fetch = [terra(src: &lib.store.source, rg: lib.store.range)
		var r = pqr { sz = 0 }
		var A,B,C,D = rg:matrix() -- :/
		r = queries.timeline_instance_fetch.exec(src,A,B,C,D)
		
		var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)







|
|
|
|
|
|







 







>
>
>
>
>
>






|
>
>










>
>
>
>
>
>






|
>
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
|
<
>
>
|

<
|
|
>


|








>
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>







 







|
|
|
|
|
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
...
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485

486
487
488
489

490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
...
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
....
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
....
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
			select a.id, a.nym, a.handle, a.origin, a.bio,
			       a.avataruri, a.rank, a.quota, a.key, a.epithet,
			       extract(epoch from a.knownsince)::bigint,
				   coalesce(a.handle || '@' || s.domain,
				            '@' || a.handle) as xid,

			       au.restrict,
						array['post'    ] <@ au.restrict,
						array['edit'    ] <@ au.restrict,
						array['account' ] <@ au.restrict,
						array['upload'  ] <@ au.restrict,
						array['moderate'] <@ au.restrict,
						array['admin'   ] <@ au.restrict

			from      parsav_auth au
			left join parsav_actors a     on au.uid = a.id
			left join parsav_servers s    on a.origin = s.id

			where au.aid = $1::bigint and au.blacklist = false and
				(au.netmask is null or au.netmask >> $2::inet) and
................................................................................
		params = {uint64}, cmd = true, sql = [[
			delete from parsav_posts where id = $1::bigint
		]]
	};
	
	post_fetch = {
		params = {uint64}, sql = [[
			with counts as (
				select a.kind, p.id as subject, count(*) as ct from parsav_acts as a
					inner join parsav_posts as p on p.id = a.subject
				group by a.kind, p.id
			)

			select a.origin is null,
				p.id, p.author, p.subject, p.acl, p.body,
				extract(epoch from p.posted    )::bigint,
				extract(epoch from p.discovered)::bigint,
				extract(epoch from p.edited    )::bigint,
				p.parent, p.convoheaduri, p.chgcount,
				coalesce(c.value, -1)::smallint, 0::bigint, 0::bigint,
				coalesce((select ct from counts where kind = 'like' and counts.subject = p.id),0)::integer,
				coalesce((select ct from counts where kind = 'rt' and counts.subject = p.id),0)::integer

			from parsav_posts as p
				inner join parsav_actors          as a on p.author = a.id
				left join  parsav_actor_conf_ints as c on c.uid    = a.id and c.key = 'ui-accent'
			where p.id = $1::bigint
		]];
	};

	post_enum_parent = {
		params = {uint64}, sql = [[
			with counts as (
				select a.kind, p.id as subject, count(*) as ct from parsav_acts as a
					inner join parsav_posts as p on p.id = a.subject
				group by a.kind, p.id
			)

			select a.origin is null,
				p.id, p.author, p.subject, p.acl, p.body,
				extract(epoch from p.posted    )::bigint,
				extract(epoch from p.discovered)::bigint,
				extract(epoch from p.edited    )::bigint,
				p.parent, p.convoheaduri, p.chgcount,
				coalesce(c.value, -1)::smallint, 0::bigint, 0::bigint,
				coalesce((select ct from counts where kind = 'like' and counts.subject = p.id),0)::integer,
				coalesce((select ct from counts where kind = 'rt' and counts.subject = p.id),0)::integer

			from parsav_posts as p
				inner join parsav_actors as a on a.id = p.author
				left join  parsav_actor_conf_ints as c on c.uid = a.id and c.key = 'ui-accent'
			where p.parent = $1::bigint
			order by p.posted, p.discovered asc
		]]
................................................................................
					inner join parsav_posts as p
						on p.id = posts.id
			)

			select extract(epoch from max(m))::bigint from maxes
		]];
	};

	post_react_simple = {
		params = {uint64, uint64, pstring}, sql = [[
			insert into parsav_acts (kind,actor,subject) values (
				$3::text, $1::bigint, $2::bigint
			) returning id
		]];
	};

	post_react_cancel = {
		params = {uint64, uint64, pstring}, cmd = true, sql = [[
			delete from parsav_acts where
				actor = $1::bigint and
				subject = $2::bigint and
				kind = $3::text
		]];
	};

	post_reacts_fetch_uid = {
		params = {uint64, uint64, pstring}, sql = [[
			select id, actor, subject, kind, body, time from parsav_acts where
				($1::bigint = 0 or actor   = $1::bigint) and
				($2::bigint = 0 or subject = $2::bigint) and
				($3::text is null or kind  = $3::text  )
		]]
	};

	post_enum_author_uid = {
		params = {uint64,uint64,uint64,uint64, uint64}, sql = [[
			with ownposts as (
				select *, 0::bigint as rtid from parsav_posts as p
				where p.author = $5::bigint and
					($1::bigint = 0 or p.posted <= to_timestamp($1::bigint)) and
					($2::bigint = 0 or to_timestamp($2::bigint) < p.posted)
			),

			retweets as (
				select p.*, a.id as rtid from parsav_acts as a
					inner join parsav_posts as p on a.subject = p.id
				where a.actor = $5::bigint and
					  a.kind = 'rt' and
					  ($1::bigint = 0 or a.time <= to_timestamp($1::bigint)) and
					  ($2::bigint = 0 or to_timestamp($2::bigint) < a.time)
			),

			allposts as (select *, 0::bigint  as retweeter from ownposts
			      union  select *, $5::bigint as retweeter from retweets),

			counts as (
				select a.kind, p.id as subject, count(*) as ct from parsav_acts as a
					inner join parsav_posts as p on p.id = a.subject
				group by a.kind, p.id
			)

			select a.origin is null,
				p.id, p.author, p.subject, p.acl, p.body,
				extract(epoch from p.posted    )::bigint,
				extract(epoch from p.discovered)::bigint,
				extract(epoch from p.edited    )::bigint,
				p.parent, p.convoheaduri, p.chgcount,
				coalesce(c.value,-1)::smallint,
				p.retweeter, p.rtid,

				coalesce((select ct from counts where kind = 'like' and counts.subject = p.id),0)::integer,
				coalesce((select ct from counts where kind = 'rt' and counts.subject = p.id),0)::integer
			from allposts as p
				inner join parsav_actors as a on p.author = a.id

				left  join parsav_actor_conf_ints as c
					on c.key = 'ui-accent' and
					   c.uid = a.id
			order by (p.posted, p.discovered) desc
			limit case when $3::bigint = 0 then null
					   else $3::bigint end
			offset $4::bigint
		]]
	};

	-- maybe there's some way to unify these two, idk, im tired

	timeline_instance_fetch = {
		params = {uint64, uint64, uint64, uint64}, sql = [[
			with posts as (
				select true,
					p.id, p.author, p.subject, p.acl, p.body,
					extract(epoch from p.posted    )::bigint,
					extract(epoch from p.discovered)::bigint,
					extract(epoch from p.edited    )::bigint,
					p.parent, null::text, p.chgcount,
					coalesce(c.value, -1)::smallint, 0::bigint, 0::bigint

				from parsav_posts as p
					inner join parsav_actors          as a on p.author = a.id
					left join  parsav_actor_conf_ints as c on c.uid    = a.id and c.key = 'ui-accent'
				where
					($1::bigint = 0 or p.posted <= to_timestamp($1::bigint)) and
					($2::bigint = 0 or to_timestamp($2::bigint) < p.posted) and
					(a.origin is null)
				order by (p.posted, p.discovered) desc
				limit case when $3::bigint = 0 then null
						   else $3::bigint end
				offset $4::bigint
			), counts as (
				select a.kind, p.id as subject, count(*) as ct from parsav_acts as a
					inner join parsav_posts as p on p.id = a.subject
				group by a.kind, p.id
			)

			select *,
				coalesce((select ct from counts as c where kind = 'like' and c.subject = posts.id),0)::integer,
				coalesce((select ct from counts as c where kind = 'rt' and c.subject = posts.id),0)::integer
			from posts
		]]
	};

	artifact_instantiate = {
		params = {binblob, binblob, pstring}, sql = [[
			insert into parsav_artifacts (content,hash,mime) values (
				$1::bytea, $2::bytea, $3::text
................................................................................
	end
	p.ptr.parent = r:int(uint64,row,9)
	if r:null(row,11)
		then p.ptr.chgcount = 0
		else p.ptr.chgcount = r:int(uint32,row,11)
	end 
	p.ptr.accent = r:int(int16,row,12)
	p.ptr.rtdby = r:int(uint64,row,13)
	p.ptr.rtact = r:int(uint64,row,14)
	p.ptr.likes = r:int(uint32,row,15)
	p.ptr.rts = r:int(uint32,row,16)
	p.ptr.localpost = r:bool(row,0)

	return p
end
local terra row_to_actor(r: &pqr, row: intptr): lib.mem.ptr(lib.store.actor)
	var a: lib.mem.ptr(lib.store.actor)
	var av: rawstring, avlen: intptr
................................................................................
			a.ptr.source = src

			var au = [lib.stat(lib.store.auth)] { ok = true }
			au.val.aid = aid
			au.val.uid = a.ptr.id
			if not r:null(0,14) then -- restricted?
				au.val.privs:clear()
				(au.val.privs.post    << r:bool(0,15)) 
				(au.val.privs.edit    << r:bool(0,16))
				(au.val.privs.account << r:bool(0,17))
				(au.val.privs.upload  << r:bool(0,18))
				(au.val.privs.moderate<< r:bool(0,19))
				(au.val.privs.admin   << r:bool(0,20))
			else au.val.privs:fill() end

			return au, a
		end

		::fail:: return [lib.stat   (lib.store.auth) ] { ok = false        },
			            [lib.mem.ptr(lib.store.actor)] { ptr = nil, ct = 0 }
................................................................................
	): lib.mem.ptr(lib.store.post)
		var r = queries.post_fetch.exec(src, post)
		if r.sz == 0 then return [lib.mem.ptr(lib.store.post)].null() end
		var p = row_to_post(&r, 0)
		p.ptr.source = src
		return p
	end];

	post_retweet = [terra(
		src: &lib.store.source,
		uid: uint64,
		post: uint64,
		undo: bool
	): {}
		if not undo then
			queries.post_react_simple.exec(src,uid,post,"rt")
		else
			queries.post_react_cancel.exec(src,uid,post,"rt")
		end
	end];
	post_like = [terra(
		src: &lib.store.source,
		uid: uint64,
		post: uint64,
		undo: bool
	): {}
		if not undo then
			queries.post_react_simple.exec(src,uid,post,"like")
		else
			queries.post_react_cancel.exec(src,uid,post,"like")
		end
	end];
	post_liked_uid = [terra(
		src: &lib.store.source,
		uid: uint64,
		post: uint64
	): bool
		var q = queries.post_reacts_fetch_uid.exec(src,uid,post,'like')
		if q.sz > 0 then q:free() return true end
		return false
	end];

	timeline_instance_fetch = [terra(src: &lib.store.source, rg: lib.store.range)
		var r = pqr { sz = 0 }
		var A,B,C,D = rg:matrix() -- :/
		r = queries.timeline_instance_fetch.exec(src,A,B,C,D)
		
		var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)