131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
...
685
686
687
688
689
690
691
692
693
694
695
696
697
698
...
905
906
907
908
909
910
911
912
913
914
915
916
|
select relatee as user from parsav_rels
where relator = $1::bigint and kind = <follow>
),
followers as (
select relator as user from parsav_rels
where relatee = $1::bigint and kind = <follow>
),
mutuals as (select * from follows intersect select * from followers)
select count(tweets.*)::bigint,
count(follows.*)::bigint,
count(followers.*)::bigint,
count(mutuals.*)::bigint
from tweets, follows, followers, mutuals
]]):gsub('<(%w+)>',function(r) return tostring(lib.store.relation[r]) end)
};
actor_auth_how = {
params = {rawstring, lib.store.inet}, sql = [[
with mts as (select a.kind from parsav_auth as a
left join parsav_actors as u on u.id = a.uid
................................................................................
(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
]]
};
}
--($5::bool = false or p.parent is null) and
local struct pqr {
sz: intptr
res: &lib.pq.PGresult
}
terra pqr:free() if self.sz > 0 then lib.pq.PQclear(self.res) end end
terra pqr:null(row: intptr, col: intptr)
................................................................................
lib.report('successfully wiped out everything parsav-related in database')
return true
else
lib.warn('backend pgsql - failed to obliterate database: \n', lib.pq.PQresultErrorMessage(res))
return false
end
end];
conf_get = [terra(src: &lib.store.source, key: rawstring)
var r = queries.conf_get.exec(src, key)
if r.sz == 0 then return [lib.mem.ptr(int8)] { ptr = nil, ct = 0 } else
defer r:free()
return r:String(0,0)
end
................................................................................
queries.auth_purge_type.exec(src, handle, uid, 'otp-%')
end];
auth_purge_trust = [terra(src: &lib.store.source, uid: uint64, handle: rawstring): {}
queries.auth_purge_type.exec(src, handle, uid, 'trust')
end];
actor_auth_register_uid = nil; -- not necessary for view-based auth
}
return b
|
|
>
|
>
>
|
|
|
|
<
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
...
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
...
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
....
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
|
select relatee as user from parsav_rels
where relator = $1::bigint and kind = <follow>
),
followers as (
select relator as user from parsav_rels
where relatee = $1::bigint and kind = <follow>
),
mutuals as (
select * from follows intersect select * from followers
)
values (
(select count(tweets.*)::bigint from tweets),
(select count(follows.*)::bigint from follows),
(select count(followers.*)::bigint from followers),
(select count(mutuals.*)::bigint from mutuals)
)
]]):gsub('<(%w+)>',function(r) return tostring(lib.store.relation[r]) end)
};
actor_auth_how = {
params = {rawstring, lib.store.inet}, sql = [[
with mts as (select a.kind from parsav_auth as a
left join parsav_actors as u on u.id = a.uid
................................................................................
(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
) on conflict do nothing returning id
]];
};
artifact_expropriate = {
params = {uint64, uint64, pstring}, cmd = true, sql = [[
insert into parsav_artifact_claims (uid,rid,description,folder) values (
$1::bigint, $2::bigint, $3::text, 'new'
) on conflict do nothing
]];
};
artifact_quicksearch = {
params = {binblob}, sql = [[
select id, (content is null) from parsav_artifacts where hash = $1::bytea
limit 1
]];
};
artifact_disclaim = {
params = {uint64, uint64}, cmd = true, sql = [[
delete from parsav_artifact_claims where
uid = $1::bigint and
rid = $2::bigint
]];
};
artifact_excise_forget = {
-- delete the blasted thing and pretend it never existed
params = {uint64}, cmd=true, sql = [[
delete from parsav_artifacts where id = $1::bigint
]];
};
artifact_excise_suppress_nullify = {
-- banish the thing into the outer darkness, preventing
-- it from ever being admitted into our databases, and
-- tabulate a -- list of the degenerates who befouled
-- their accounts with such wanton and execrable filth,
-- the better to ensure their long-overdue punishment
params = {uint64}, cmd=true, sql = [[
update parsav_artifacts
set content = null
where id = $1::bigint;
]];
};
artifact_excise_suppress_breaklinks = {
-- "ERROR: cannot insert multiple commands into a prepared
-- statement" are you fucking shitting me with this shit
params = {uint64}, sql = [[
delete from parsav_artifact_claims where
rid = $1::bigint
returning uid, description, birth, folder;
]];
};
post_attach_ctl_ins = {
params = {uint64, uint64}, cmd=true, sql = [[
update parsav_posts set
artifacts = artifacts || $2::bigint
where id = $1::bigint and not
artifacts @> array[$2::bigint]
]];
};
post_attach_ctl_del = {
params = {uint64, uint64}, cmd=true, sql = [[
update parsav_posts set
artifacts = array_remove(artifacts, $2::bigint)
where id = $1::bigint and
artifacts @> array[$2::bigint]
]];
};
}
local struct pqr {
sz: intptr
res: &lib.pq.PGresult
}
terra pqr:free() if self.sz > 0 then lib.pq.PQclear(self.res) end end
terra pqr:null(row: intptr, col: intptr)
................................................................................
lib.report('successfully wiped out everything parsav-related in database')
return true
else
lib.warn('backend pgsql - failed to obliterate database: \n', lib.pq.PQresultErrorMessage(res))
return false
end
end];
tx_enter = [terra(src: &lib.store.source)
var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), 'begin')
if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
lib.dbg('beginning pgsql transaction')
return true
else
lib.warn('backend pgsql - failed to begin transaction: \n', lib.pq.PQresultErrorMessage(res))
return false
end
end];
tx_complete = [terra(src: &lib.store.source)
var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), 'end')
if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
lib.dbg('completing pgsql transaction')
return true
else
lib.warn('backend pgsql - failed to complete transaction: \n', lib.pq.PQresultErrorMessage(res))
return false
end
end];
conf_get = [terra(src: &lib.store.source, key: rawstring)
var r = queries.conf_get.exec(src, key)
if r.sz == 0 then return [lib.mem.ptr(int8)] { ptr = nil, ct = 0 } else
defer r:free()
return r:String(0,0)
end
................................................................................
queries.auth_purge_type.exec(src, handle, uid, 'otp-%')
end];
auth_purge_trust = [terra(src: &lib.store.source, uid: uint64, handle: rawstring): {}
queries.auth_purge_type.exec(src, handle, uid, 'trust')
end];
artifact_quicksearch = [terra(
src: &lib.store.source,
hash: binblob
): {uint64, bool}
var srec = queries.artifact_quicksearch.exec(src, hash)
if srec.sz > 0 then
defer srec:free()
var id = srec:int(uint64,0,0)
var ban = srec:bool(0,1)
return id, ban
else return 0, false end
end];
artifact_instantiate = [terra(
src: &lib.store.source,
artifact: binblob,
mime: pstring
): uint64
var arthash: uint8[lib.crypt.algsz.sha256]
if lib.md.mbedtls_md(lib.md.mbedtls_md_info_from_type(lib.crypt.alg.sha256.id),
artifact.ptr, artifact.ct, &arthash[0]) ~= 0 then
lib.bail('could not hash artifact to be instantiated')
end
var hashb = binblob{ptr=&arthash[0],ct=[arthash.type.N]}
var srec = queries.artifact_quicksearch.exec(src, hashb)
if srec.sz > 0 then
defer srec:free()
var ban = srec:bool(0,1)
if ban then
lib.report('user attempted to instantiate forsaken artifact')
return 0
end
var oldid = srec:int(uint64,0,0)
return oldid
else -- not in db, insert
var nrec = queries.artifact_instantiate.exec(src, artifact, hashb, mime)
if nrec.sz == 0 then
lib.warn('failed to instantiate artifact -- are you running out of storage?')
return 0
else defer nrec:free()
var newid = nrec:int(uint64,0,0)
return newid
end
end
end];
post_attach_ctl = [terra(
src: &lib.store.source,
post: uint64,
artifact: uint64,
detach: bool
): {}
if detach
then queries.post_attach_ctl_del.exec(src,post,artifact)
else queries.post_attach_ctl_ins.exec(src,post,artifact)
end
end];
actor_auth_register_uid = nil; -- TODO better support non-view based auth
}
return b
|