parsav  Diff

Differences From Artifact [0ea1a47601]:

To Artifact [1740166796]:


     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