Differences From
Artifact [d6c61590d0]:
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()