parsav  Diff

Differences From Artifact [d6c61590d0]:

To Artifact [8e095d7d59]:


   954    954   -- only to the connecting parsav instance, stored in memory, and dropped
   955    955   -- as soon as the connection session ends.
   956    956   
   957    957   local tempviews = sqlsquash(lib.util.ingest 'backend/schema/pgsql-views.sql')
   958    958   local prep = { quote
   959    959   	var res = lib.pq.PQexec([con], tempviews)
   960    960   	if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
   961         -		lib.dbg('uploading pgsql session views')
          961  +		lib.dbg('uploaded pgsql session views')
          962  +		lib.pq.PQclear(res)
   962    963   	else
   963    964   		lib.bail('backend pgsql - failed to upload session views: \n', lib.pq.PQresultErrorMessage(res))
   964    965   	end
   965    966   end }
   966    967   
   967    968   for k,q in pairs(queries) do
   968    969   	local qt = sqlsquash(q.sql)
................................................................................
  1026   1027   			[#args], params, params_sz, params_ft, 1)
  1027   1028   		if res == nil then
  1028   1029   			lib.bail(['grievous error occurred executing '..k..' against database'])
  1029   1030   		elseif lib.pq.PQresultStatus(res) ~= okconst then
  1030   1031   			lib.bail(['PGSQL database procedure '..k..' failed\n'],
  1031   1032   			lib.pq.PQresultErrorMessage(res))
  1032   1033   		end
  1033         -
  1034         -		var ct = lib.pq.PQntuples(res)
  1035         -		if ct == 0 then
  1036         -			lib.pq.PQclear(res)
  1037         -			return pqr {0, nil}
  1038         -		else
  1039         -			return pqr {ct, res}
         1034  +		escape
         1035  +			if q.cmd then
         1036  +				emit quote lib.pq.PQclear(res) end
         1037  +			else emit quote
         1038  +				var ct = lib.pq.PQntuples(res)
         1039  +				if ct == 0 then
         1040  +					lib.pq.PQclear(res)
         1041  +					return pqr {0, nil}
         1042  +				else
         1043  +					return pqr {ct, res}
         1044  +				end
         1045  +			end end
  1040   1046   		end
  1041   1047   	end
  1042   1048   	q.exec.name = 'pgsql.' .. k .. '.exec'
  1043   1049   end
  1044   1050   
  1045   1051   local terra row_to_artifact(res: &pqr, i: intptr): lib.mem.ptr(lib.store.artifact)
  1046   1052   	var id = res:int(uint64,i,0)
................................................................................
  1242   1248   local getpow = terra(
  1243   1249   	src: &lib.store.source,
  1244   1250   	uid: uint64
  1245   1251   ): lib.store.powerset
  1246   1252   	var powers = lib.store.rights_default().powers
  1247   1253   	var map = array([privmap])
  1248   1254   	var r = queries.actor_powers_fetch.exec(src, uid)
         1255  +	defer r:free()
  1249   1256   
  1250   1257   	for i=0, r.sz do
  1251   1258   		for j=0, [map.type.N] do
  1252   1259   			var pn = r:_string(i,0)
  1253   1260   			if map[j].name:cmp(pn) then
  1254   1261   				if r:bool(i,1)
  1255   1262   					then powers = powers + map[j].val
................................................................................
  1261   1268   
  1262   1269   	return powers
  1263   1270   end
  1264   1271   
  1265   1272   
  1266   1273   local txdo = terra(src: &lib.store.source)
  1267   1274   	var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), 'begin')
         1275  +	var r: bool
  1268   1276   	if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
  1269   1277   		lib.dbg('beginning pgsql transaction')
  1270         -		return true
         1278  +		r = true
  1271   1279   	else
  1272   1280   		lib.warn('backend pgsql - failed to begin transaction: \n', lib.pq.PQresultErrorMessage(res))
  1273         -		return false
         1281  +		r = false
  1274   1282   	end
         1283  +	lib.pq.PQclear(res)
         1284  +	return r
  1275   1285   end
  1276   1286   
  1277   1287   local txdone = terra(src: &lib.store.source)
  1278   1288   	var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), 'end')
         1289  +	var r: bool
  1279   1290   	if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
  1280   1291   		lib.dbg('completing pgsql transaction')
  1281         -		return true
         1292  +		r = true
  1282   1293   	else
  1283   1294   		lib.warn('backend pgsql - failed to complete transaction: \n', lib.pq.PQresultErrorMessage(res))
  1284         -		return false
         1295  +		r = false
  1285   1296   	end
         1297  +	lib.pq.PQclear(res)
         1298  +	return r
  1286   1299   end
  1287   1300   
  1288   1301   local b = `lib.store.backend {
  1289   1302   	id = "pgsql";
  1290   1303   	open = [terra(src: &lib.store.source): &opaque
  1291   1304   		lib.report('connecting to postgres database: ', src.string.ptr)
  1292   1305   		var [con] = lib.pq.PQconnectdb(src.string.ptr)
................................................................................
  1348   1361   		key: binblob
  1349   1362   	): {}
  1350   1363   		queries.server_setup_self.exec(src,domain,key,lib.osclock.time(nil))
  1351   1364   	end];
  1352   1365   
  1353   1366   	dbsetup = [terra(src: &lib.store.source): bool
  1354   1367   		var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), schema)
         1368  +		var r = true
  1355   1369   		if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
  1356   1370   			lib.report('successfully instantiated schema in database')
  1357         -			return true
  1358   1371   		else
  1359   1372   			lib.warn('backend pgsql - failed to initialize database: \n', lib.pq.PQresultErrorMessage(res))
  1360         -			return false
         1373  +			r = false
  1361   1374   		end
         1375  +		lib.pq.PQclear(res)
         1376  +		return r
  1362   1377   	end];
  1363   1378   
  1364   1379   	obliterate_everything = [terra(src: &lib.store.source): bool
  1365   1380   		var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), obliterator)
         1381  +		var r = true
  1366   1382   		if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
  1367   1383   			lib.report('successfully wiped out everything parsav-related in database')
  1368         -			return true
  1369   1384   		else
  1370   1385   			lib.warn('backend pgsql - failed to obliterate database: \n', lib.pq.PQresultErrorMessage(res))
  1371   1386   			return false
  1372   1387   		end
         1388  +		lib.pq.PQclear(res)
         1389  +		return r
  1373   1390   	end];
  1374   1391   
  1375         -	conf_get = [terra(src: &lib.store.source, key: pstring)
         1392  +	conf_get = [terra(src: &lib.store.source, pool: &lib.mem.pool, key: pstring)
  1376   1393   		var r = queries.conf_get.exec(src, key)
  1377   1394   		if r.sz == 0 then return [lib.mem.ptr(int8)] { ptr = nil, ct = 0 } else
  1378   1395   			defer r:free()
  1379         -			return r:String(0,0)
         1396  +			return r:_string(0,0):pdup(pool)
  1380   1397   		end
  1381   1398   	end];
  1382   1399   	conf_set = [terra(src: &lib.store.source, key: pstring, val: pstring)
  1383         -		queries.conf_set.exec(src, key, val):free() end];
         1400  +		queries.conf_set.exec(src, key, val) end];
  1384   1401   	conf_reset = [terra(src: &lib.store.source, key: rawstring)
  1385         -		queries.conf_reset.exec(src, key):free() end];
         1402  +		queries.conf_reset.exec(src, key) end];
  1386   1403   	
  1387   1404   	actor_fetch_uid = [terra(src: &lib.store.source, uid: uint64)
  1388   1405   		var r = queries.actor_fetch_uid.exec(src, uid)
  1389   1406   		if r.sz == 0 then
  1390   1407   			return [lib.mem.ptr(lib.store.actor)] { ct = 0, ptr = nil }
  1391   1408   		else defer r:free()
  1392   1409   			var a = row_to_actor(&r, 0)
................................................................................
  1511   1528   		::fail::return 0, 0, pstring.null()
  1512   1529   	end];
  1513   1530   
  1514   1531   
  1515   1532   	actor_stats = [terra(src: &lib.store.source, uid: uint64)
  1516   1533   		var r = queries.actor_stats.exec(src, uid)
  1517   1534   		if r.sz == 0 then lib.bail('error fetching actor stats!') end
         1535  +		defer r:free()
  1518   1536   		var s: lib.store.actor_stats
  1519   1537   		s.posts = r:int(uint64, 0, 0)
  1520   1538   		s.follows = r:int(uint64, 0, 1)
  1521   1539   		s.followers = r:int(uint64, 0, 2)
  1522   1540   		s.mutuals = r:int(uint64, 0, 3)
  1523   1541   		return s
  1524   1542   	end];
................................................................................
  1587   1605   
  1588   1606   	post_fetch = [terra(
  1589   1607   		src: &lib.store.source,
  1590   1608   		post: uint64
  1591   1609   	): lib.mem.ptr(lib.store.post)
  1592   1610   		var r = queries.post_fetch.exec(src, post)
  1593   1611   		if r.sz == 0 then return [lib.mem.ptr(lib.store.post)].null() end
         1612  +		defer r:free()
  1594   1613   		var p = row_to_post(&r, 0)
  1595   1614   		p.ptr.source = src
  1596   1615   		return p
  1597   1616   	end];
  1598   1617   
  1599   1618   	post_act_cancel = [terra(
  1600   1619   		src: &lib.store.source,
................................................................................
  1646   1665   		r = queries.timeline_instance_fetch.exec(src,A,B,C,D)
  1647   1666   		
  1648   1667   		var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
  1649   1668   		for i=0,r.sz do
  1650   1669   			ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL
  1651   1670   			ret.ptr[i].ptr.source = src
  1652   1671   		end
         1672  +		r:free()
  1653   1673   
  1654   1674   		return ret
  1655   1675   	end];
  1656   1676   
  1657   1677   	timeline_circle_fetch = [terra(
  1658   1678   		src: &lib.store.source,
  1659   1679   		cid: uint64,
................................................................................
  1664   1684   		r = queries.timeline_circle_fetch.exec(src,cid,A,B,C,D)
  1665   1685   		
  1666   1686   		var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
  1667   1687   		for i=0,r.sz do
  1668   1688   			ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL
  1669   1689   			ret.ptr[i].ptr.source = src
  1670   1690   		end
         1691  +		r:free()
  1671   1692   
  1672   1693   		return ret
  1673   1694   	end];
  1674   1695   
  1675   1696   	timeline_actor_fetch_uid = [terra(
  1676   1697   		src: &lib.store.source,
  1677   1698   		uid: uint64,
................................................................................
  1682   1703   		r = queries.timeline_actor_fetch.exec(src,uid,A,B,C,D)
  1683   1704   		
  1684   1705   		var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
  1685   1706   		for i=0,r.sz do
  1686   1707   			ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL
  1687   1708   			ret.ptr[i].ptr.source = src
  1688   1709   		end
         1710  +		r:free()
  1689   1711   
  1690   1712   		return ret
  1691   1713   	end];
  1692   1714   
  1693   1715   	post_enum_author_uid = [terra(
  1694   1716   		src: &lib.store.source,
  1695   1717   		uid: uint64,
................................................................................
  1700   1722   		r = queries.post_enum_author_uid.exec(src,A,B,C,D,uid)
  1701   1723   		
  1702   1724   		var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
  1703   1725   		for i=0,r.sz do
  1704   1726   			ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL
  1705   1727   			ret.ptr[i].ptr.source = src
  1706   1728   		end
         1729  +		r:free()
  1707   1730   
  1708   1731   		return ret
  1709   1732   	end];
  1710   1733   
  1711   1734   	actor_powers_fetch = getpow;
  1712   1735   	actor_save = [terra(
  1713   1736   		src: &lib.store.source,
................................................................................
  1732   1755   		ac.id = r:int(uint64,0,0)
  1733   1756   
  1734   1757   		-- check against default rights, insert records for wherever powers differ
  1735   1758   		lib.dbg('created new actor, establishing powers')
  1736   1759   		privupdate(src,ac)
  1737   1760   
  1738   1761   		lib.dbg('powers established')
         1762  +		r:free()
  1739   1763   		return ac.id
  1740   1764   	end];
  1741   1765   
  1742   1766   	actor_rel_create = [terra(
  1743   1767   		src: &lib.store.source,
  1744   1768   		kind:    uint16,
  1745   1769   		relator: uint64,
................................................................................
  1818   1842   
  1819   1843   	auth_fetch_aid = [terra(
  1820   1844   		src: &lib.store.source,
  1821   1845   		aid: uint64
  1822   1846   	): lib.mem.ptr(lib.store.auth)
  1823   1847   		var r = queries.auth_fetch_aid.exec(src,aid)
  1824   1848   		if r.sz == 0 then return [lib.mem.ptr(lib.store.auth)].null() end
         1849  +		defer r:free()
  1825   1850   		var kind = r:_string(0, 2)
  1826   1851   		var comment = r:_string(0, 3)
  1827   1852   		var a = [ lib.str.encapsulate(lib.store.auth, {
  1828   1853   			kind = {`kind.ptr, `kind.ct+1};
  1829   1854   			comment = {`comment.ptr, `comment.ct+1};
  1830   1855   		}) ]
  1831   1856   		a.ptr.aid = r:int(uint64, 0, 0)
................................................................................
  1840   1865   
  1841   1866   	auth_enum_uid = [terra(
  1842   1867   		src: &lib.store.source,
  1843   1868   		uid: uint64
  1844   1869   	): lib.mem.lstptr(lib.store.auth)
  1845   1870   		var r = queries.auth_enum_uid.exec(src,uid)
  1846   1871   		if r.sz == 0 then return [lib.mem.lstptr(lib.store.auth)].null() end
         1872  +		defer r:free()
  1847   1873   		var ret = lib.mem.heapa([lib.mem.ptr(lib.store.auth)], r.sz)
  1848   1874   		for i=0, r.sz do
  1849   1875   			var kind = r:_string(i, 1)
  1850   1876   			var comment = r:_string(i, 2)
  1851   1877   			var a = [ lib.str.encapsulate(lib.store.auth, {
  1852   1878   				kind = {`kind.ptr, `kind.ct+1};
  1853   1879   				comment = {`comment.ptr, `comment.ct+1};
................................................................................
  2004   2030   
  2005   2031   	artifact_enum_uid = [terra(
  2006   2032   		src: &lib.store.source,
  2007   2033   		uid: uint64,
  2008   2034   		folder: pstring
  2009   2035   	)
  2010   2036   		var res = queries.artifact_enum_uid.exec(src,uid,folder)
  2011         -		if res.sz > 0 then
         2037  +		if res.sz > 0 then defer res:free()
  2012   2038   			var m = lib.mem.heapa([lib.mem.ptr(lib.store.artifact)], res.sz)
  2013   2039   			for i=0,res.sz do
  2014   2040   				m.ptr[i] = row_to_artifact(&res, i)
  2015   2041   				m(i).ptr.owner = uid
  2016   2042   			end
  2017   2043   			return m
  2018   2044   		else return [lib.mem.lstptr(lib.store.artifact)].null() end
................................................................................
  2160   2186   	actor_conf_str_enum = nil;
  2161   2187   	actor_conf_str_get = [terra(
  2162   2188   		src: &lib.store.source,
  2163   2189   		pool: &lib.mem.pool,
  2164   2190   		uid: uint64,
  2165   2191   		key: pstring
  2166   2192   	): pstring
  2167         -			var r = queries.actor_conf_str_get.exec(src, uid, key)
  2168         -			if r.sz > 0 then
  2169         -				return r:_string(0,0):pdup(pool)
  2170         -			else return pstring.null() end
  2171         -		end];
         2193  +		var r = queries.actor_conf_str_get.exec(src, uid, key)
         2194  +		if r.sz > 0 then defer r:free()
         2195  +			return r:_string(0,0):pdup(pool)
         2196  +		else return pstring.null() end
         2197  +	end];
  2172   2198   	actor_conf_str_set = [terra(src: &lib.store.source, uid: uint64, key: pstring, value: pstring): {}
  2173         -			queries.actor_conf_str_set.exec(src,uid,key,value) end];
         2199  +		queries.actor_conf_str_set.exec(src,uid,key,value) end];
  2174   2200   	actor_conf_str_reset = [terra(src: &lib.store.source, uid: uint64, key: pstring): {}
  2175         -			queries.actor_conf_str_reset.exec(src,uid,key) end];
         2201  +		queries.actor_conf_str_reset.exec(src,uid,key) end];
  2176   2202   
  2177   2203   	actor_conf_int_enum = nil;
  2178   2204   	actor_conf_int_get = [terra(src: &lib.store.source, uid: uint64, key: pstring)
  2179   2205   			var r = queries.actor_conf_int_get.exec(src, uid, key)
  2180   2206   			if r.sz > 0 then
  2181   2207   				var ret = r:int(uint64,0,0)
  2182   2208   				r:free()