{"_id":"@ashnazg/squirrelnado-difftable","_rev":"6-78e79638017082f87fee6088d279db34","name":"@ashnazg/squirrelnado-difftable","dist-tags":{"latest":"0.0.6"},"versions":{"0.0.2":{"name":"@ashnazg/squirrelnado-difftable","version":"0.0.2","main":"diff.js","author":{"name":"Xander","email":"xander@ashnazg.com","url":"ashnazg.com"},"license":"MIT","dependencies":{"@ashnazg/utils":"^0.3.0"},"description":"``` const sqrl = require('@ashnazg/squirrelnado'); require('@ashnazg/squirrelnado-psql')(sqrl); require('@ashnazg/squirrelnado-difftable')(sqrl);","_id":"@ashnazg/squirrelnado-difftable@0.0.2","dist":{"shasum":"e8fae56e67cb6a597260152302bd20fbac677275","integrity":"sha512-VUXFvY7nH8+rpi2T9WDlb4X5QGoFMAQ69w5eaZZwMhHS/gi2w2rJI/FPXtiPHb31fbF41N2/JhDEqqr8+mH+fg==","tarball":"https://registry.npmjs.org/@ashnazg/squirrelnado-difftable/-/squirrelnado-difftable-0.0.2.tgz","fileCount":4,"unpackedSize":19176,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCpFerMAsxJwWWII9AaSiuje36xyUCD0xDgHIZDpa4oVQIhANNd2lYVYzLcHm18YMlHMmY/T1WQ4KWgM4lRYZRWOJMz"}]},"_npmUser":{"name":"xander","email":"xander@ashnazg.com"},"directories":{},"maintainers":[{"name":"xander","email":"xander@ashnazg.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/squirrelnado-difftable_0.0.2_1635398165396_0.46727900043289905"},"_hasShrinkwrap":false},"0.0.3":{"name":"@ashnazg/squirrelnado-difftable","version":"0.0.3","main":"diff.js","author":{"name":"Xander","email":"xander@ashnazg.com","url":"ashnazg.com"},"license":"MIT","dependencies":{"@ashnazg/utils":"^0.3.1"},"description":"``` const sqrl = require('@ashnazg/squirrelnado'); require('@ashnazg/squirrelnado-psql')(sqrl); require('@ashnazg/squirrelnado-difftable')(sqrl);","_id":"@ashnazg/squirrelnado-difftable@0.0.3","dist":{"shasum":"6f67a95fb4ab3244219f60ea945d84108da8e61f","integrity":"sha512-W97jUgiPmnNONeg5zXwX6SUnOGWG06hGRzc/1EzC7ds23UrKI976Tt6G422pa6qL7Tuz5EgR4jqfluQds7r9HQ==","tarball":"https://registry.npmjs.org/@ashnazg/squirrelnado-difftable/-/squirrelnado-difftable-0.0.3.tgz","fileCount":4,"unpackedSize":19176,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFl/ismKs0K+YbU+EQ+70gQWaShPI1D3Kurw7e5TZo7dAiEA6hL2ZXSfu9hwRaJk4fYMIj+Fiw0QYCQNNi6mcNQJM3E="}]},"_npmUser":{"name":"xander","email":"xander@ashnazg.com"},"directories":{},"maintainers":[{"name":"xander","email":"xander@ashnazg.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/squirrelnado-difftable_0.0.3_1635398973058_0.457634212628647"},"_hasShrinkwrap":false},"0.0.4":{"name":"@ashnazg/squirrelnado-difftable","version":"0.0.4","main":"diff.js","author":{"name":"Xander","email":"xander@ashnazg.com","url":"ashnazg.com"},"license":"MIT","dependencies":{"@ashnazg/utils":"^0.3.1"},"description":"``` const sqrl = require('@ashnazg/squirrelnado'); require('@ashnazg/squirrelnado-psql')(sqrl); require('@ashnazg/squirrelnado-difftable')(sqrl);","_id":"@ashnazg/squirrelnado-difftable@0.0.4","dist":{"shasum":"2ea3c4699c142a374bc571f341f3e64993d18a3b","integrity":"sha512-iIMyzYeCZvZ+j7JNi7Yv8NLP36Gn7JBmTCiJFphjBow10O5JuwxvrWjCKvW70Br9LiSTkGY4/Bnj2QM3mzwtxg==","tarball":"https://registry.npmjs.org/@ashnazg/squirrelnado-difftable/-/squirrelnado-difftable-0.0.4.tgz","fileCount":4,"unpackedSize":19128,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh119lCRA9TVsSAnZWagAAv1gP/017b1aIV3gZo2n7id0P\n2/tzPMany2/POnkDzdg1sYIk/7U7AhnVq337VvHgaKblrw3cK1ewfYZd2pUB\nHiGCfvLsq22NizNhTBx11V5dnYjlF5jkMQs1nyserAVT6/nvfileS5HCULbj\nZDZ+0v174uq78no2lqpLVR3BGBuAHYfOkhUSzwUPBlBO+AvDPy/UUCbOQbIM\nyMI5tYdI90OTYIFvsztZF0lkxqGUpSJ2bMzMzlwwR9VRK1M17NmVyieoUuDC\nvUJI4QGlTO+jrrO5p1BJitjkNMXovgYc7Az36g9AQK/2sRW4yskfiBanEuTC\ni2G/J/OeEB8jKs7JUgogXRaqd+Ry2JYM4tboLspOCUEMEitEG9iSP8TpF+7U\niyW2lxNFrOEum+kVEiLshWT/Qv2PiS7N64cb5UMcuRPXFp0eDYRGStgdQipU\nA5sBpETSgVPGu4xfIZkOSTSH0dpLGFyN8KU6XqutlEdIEz75vz2ZIpnaxgt5\nbLJwwfCc3BbC9u80xoubaO3n2NBqI/dyLZdPU8zIn6aGD7WeIHF9v5+UBYOb\nw7+/UCwYJn3AZSySoa8SLwema0mRGNgsTZSCwdsUAM6DdKlcY/ccU0AYa4UX\nDWOHofIkqcmSG6YiNJFvetrrqtD15x7JuMmGQU3S3Ozgyu4yXoyy9uY7uUbh\ndj0S\r\n=CgVC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGjhUofNJOfwZZrJ8I27oMewupL2uTEEBuLAsw6LZqE9AiBEazlKsdc8Cg5juGVV2PQezO8NNvD7VQ4i2vnAFALJjg=="}]},"_npmUser":{"name":"xander","email":"xander@ashnazg.com"},"directories":{},"maintainers":[{"name":"xander","email":"xander@ashnazg.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/squirrelnado-difftable_0.0.4_1635401885498_0.6844334168101742"},"_hasShrinkwrap":false},"0.0.5":{"name":"@ashnazg/squirrelnado-difftable","version":"0.0.5","main":"diff.js","author":{"name":"Xander","email":"xander@ashnazg.com","url":"ashnazg.com"},"license":"MIT","dependencies":{"@ashnazg/utils":"^0.3.1"},"description":"``` const sqrl = require('@ashnazg/squirrelnado'); require('@ashnazg/squirrelnado-psql')(sqrl); require('@ashnazg/squirrelnado-difftable')(sqrl);","_id":"@ashnazg/squirrelnado-difftable@0.0.5","dist":{"shasum":"b459bc0a6a1f01e138eca78574c7c5efbe49c4a2","integrity":"sha512-7ipiGssXTmZAZYKPZzP3CShZRi1HZnBUlwAG6TsR2UUXjHAlNhmWhyhCIwyynWGM+TNuIAfLWLgH9WwFkLiu6w==","tarball":"https://registry.npmjs.org/@ashnazg/squirrelnado-difftable/-/squirrelnado-difftable-0.0.5.tgz","fileCount":4,"unpackedSize":20287,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCqjZW/ZCWmdzGjDh0orC4yV2DCpH9ljG5jcs96jw6UpwIgeQFKpP2Q6AsUMdC2hHkYcR3OipmV3OK4+6ZhLG2p2J4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiaGC3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo7eA/8C8fFPW4oM5BBlIpMioQ2F9ubEEcS7ZR61kESs5ylIlnvJ8Nh\r\nRh2yVphbZbj7UyQ0gjVdA5dEypWknjBdR9eb8w0P+o6/Jygd4NmpxZpQIckA\r\nU8kVkUStHeiisALWjElN8HQVlQSiM+SXeVNQCFMxVx8+OkKm49P1M876GNR+\r\n+HLjWg0EoR6BTW9M7Ebk8YyB+FwR27MQ5hn5CUzXUD0DqzrpNhNvEyP4cgTw\r\nxZfRHI0oLIdPXFpwcR7qTE3++SsL12dh8U8VIpD8ElyJphhywcHKyU6qH2+H\r\nElhd6kFjGd/titfXOMQHdQfZJOSiXfWAVCtw/dA4tcsoZxImsIvCbK/hDYZB\r\nGfFBKTZAd6a0OB73pcXwY+XVGuaBh1x62oN1bIrabIak1PDSzolgONbQG2f7\r\nF2xV/IrxHmxy5DLRC4rwlkyIgouI5rNwEnVBFDf/X8g7O417al4XGqi1+wN+\r\nasfj5J5I8KUnT0WQflgbwSKNbdlRjmGKWx9uO8xaU6CfmDsXfA0mKsp0yIC/\r\nRmq4St4Cx3UabU5CKG301gc1u3J0u6Le+3Nyqt6+bWC+mb4J1ueYLVeN15af\r\nBmH7SOsb7R6+AOvoRpwHGoWwqqMClBkFFv+Xn916n9JNM6WlImmDXBiyPe5z\r\nXaMXCPG5qf8ONOUABic/2OposA8sWVxkSyU=\r\n=zjfs\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"xander","email":"xander@ashnazg.com"},"directories":{},"maintainers":[{"name":"xander","email":"xander@ashnazg.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/squirrelnado-difftable_0.0.5_1651007670755_0.3880526322245863"},"_hasShrinkwrap":false},"0.0.6":{"name":"@ashnazg/squirrelnado-difftable","version":"0.0.6","main":"diff.js","author":{"name":"Xander","email":"xander@ashnazg.com","url":"ashnazg.com"},"license":"MIT","dependencies":{"@ashnazg/utils":"^0.3.1"},"description":"``` const sqrl = require('@ashnazg/squirrelnado'); require('@ashnazg/squirrelnado-psql')(sqrl); require('@ashnazg/squirrelnado-difftable')(sqrl);","_id":"@ashnazg/squirrelnado-difftable@0.0.6","dist":{"shasum":"cf9c17657c639c5ad7d2b9be4f3092548a714677","integrity":"sha512-AdeLvt/aYjPaBo2JX21bB2x7tzkePgdxVSC3gF7bwqZDgxLXdbS3nqUpB89efjA35z5PWWtSEqKCJZYp9pGkxA==","tarball":"https://registry.npmjs.org/@ashnazg/squirrelnado-difftable/-/squirrelnado-difftable-0.0.6.tgz","fileCount":4,"unpackedSize":20466,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICnKE7fH5GeFwCOTG8dD0cNJrO7A4mgUPZODC9ruABWTAiEAo4tRHyoxJz9xJMuxiSlPxdFsqp9rKOF62Y37zDenxD8="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiaWIwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoY7A//ZE+bEi8lEXZlGPW9ySL93X2TM5xci7O4JoeQRorrcOKLLDR4\r\nDIc5VxdI64sKwxHIIXTFnnr2SVt9NtJx/cAfS7q65FwmLEZG1U7D2yCUtcGL\r\nL3iEhI70dc4TStd+8IoHYjo77hkN6V3DkVZeBCooczffHJiO7wp1kNi5x32k\r\ntb49knx8pKsDMD2vCJ4IRWQKXCrPMuM0GFUlViimMBR5lQJMyuFdeS2cI0LY\r\nYRkaBZa76wONDfegmu/i7SKN6hF3mOH9+MohRUL0Ak/q3K95enuBSeXUq0+R\r\nDZ8J+yn5pM657ljIqiex8MkVYh5wd4VNXdOlQMaezlv1Wpzs2R9VCWGliGaR\r\naW/A9zLBPhbuRPtKiHv+p8N715QJljL3yjTOgV8Zz6mj/qw9PMf6EKErPIUi\r\nQ0o0Qy6Z338SwBt7H/kGM0DvhlsFROwntahUHCl+vCd/R/ISoSbQheiWXHcn\r\nsroQ8+z9+nsPWVDHfvFYx7ccHRyzo4FUfvBQl017R3nTUy7BSc3r/csEq+fB\r\nJGSsy2IsAoCCaC6Qz868ZoHh5sZvtVhXkEg680PYX4u7HSmRRbn1Petw/2z9\r\ny5tpNZp5KODY6MmJdynMDwDF0RF48WH2U3qstBJ/BsvZIRf9Bg/jPROSfaBr\r\npPhaWDpqUCey0ZrxNN9VwwOU1dx/QVBLdxI=\r\n=Ml4R\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"xander","email":"xander@ashnazg.com"},"directories":{},"maintainers":[{"name":"xander","email":"xander@ashnazg.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/squirrelnado-difftable_0.0.6_1651073584466_0.3339528790867039"},"_hasShrinkwrap":false}},"time":{"created":"2021-10-28T05:16:05.340Z","0.0.2":"2021-10-28T05:16:05.758Z","modified":"2022-04-27T15:33:04.665Z","0.0.3":"2021-10-28T05:29:33.213Z","0.0.4":"2021-10-28T06:18:05.653Z","0.0.5":"2022-04-26T21:14:30.982Z","0.0.6":"2022-04-27T15:33:04.592Z"},"maintainers":[{"name":"xander","email":"xander@ashnazg.com"}],"description":"``` const sqrl = require('@ashnazg/squirrelnado'); require('@ashnazg/squirrelnado-psql')(sqrl); require('@ashnazg/squirrelnado-difftable')(sqrl);","author":{"name":"Xander","email":"xander@ashnazg.com","url":"ashnazg.com"},"license":"MIT","readme":"## Usage\n\n```\nconst sqrl = require('@ashnazg/squirrelnado');\nrequire('@ashnazg/squirrelnado-psql')(sqrl);\nrequire('@ashnazg/squirrelnado-difftable')(sqrl);\n\nconst diff = sqrl.diff({\n\tcontrol:    'postgres://known_good_server/db1',\n\texperiment: 'postgres://audit_this_server/db2',\n\tcache:      'postgres://localhost/tmpdb/some_schema',\n\twrite:      'postgres://final_server/db3/reports/single_anomaly_table',\n\n\ttmp: process.env.HOME + '/sqrl-diff-cache' // all control/experiment tables looked at will be cached as $tmp/{ctl|exp}/schema/table/page-N.jsonl.gz\n\t// !! handle your own expiration of tables out of tmp !!\n\t// to avoid burning DB I/O, sqrl.diff assumes that its existing cache is still usable as long as a folder named $tmp/$mode/schema/table exists.\n});\n\n\nawait diff('schema1.table1'); // write table1's anomalies to 'single_anomaly_table'\nawait diff('schema1'); // scan tables in control. for each table, do the above.\n\n// you can also break the steps out and sequence all the reads at once. the above oneliner breaks out as:\nawait diff.snapshot('schema1.table1'); // cache both copies of the target(s) into $tmp\nawait diff.compare('schema1.table1'); // compare each pair, building up and then slicing down a copy of the data in $cache, leaving only the anomalies behind\nawait diff.write('schema1.table1'); // export that group of anomalies from local cahe to $write's 'single_anomaly_table'\nawait diff.close();\n\nbroken out, the only step that needs access to control/experiment is snapshot, and only write needs access to $write db.\ncompare always reads from $tmp, and nukes and replaces the state in cache. So you could run snapshots on Monday; delete \"$tmp/exp\" on Tuesday to force snapshot to re-pull only that\nside, and run compare() on Wednesday.\n```\n\n### variations\n* If experiment does not specify a table, scan schema3 for all tables/views, and look them up in control's schema2 (in this mode, a table name on control is ignored.)\n* if write does not specify a table, pick a report name name based on \"control\"\n\t* (The above \"control\" URL would put all final records in \"db3/reports/schema2_table\" if we're in table:table mode, or reports.schema2 if we're in schema:schema mode.)\n* you can compare two tables in one DB as well: just use the same URL for control and experiment, and then use 2 params on `diff('experiment.table', 'reference.table')`\n\t* when the URLs are the same, the reference copy will load from $tmp/ctl if it exist, else $tmp/exp\n\n### index columns\nBy default, diff only looks for a column named 'id'. If not usable as a unique index, it falls back on the whole raw row as identity.\n\nYou can pass in any array of strings as the last param to indicate valid candidaates:\n* `diff('table', ['id', 'src_id'])`\n* `diff('table', 'ref_table', ['id', 'src_id'])`\n* `diff.compare('table', ['id', 'src_id'])`\n* `diff.compare('table', 'ref_table', ['id', 'src_id'])`\n\nAnd an empty list indicates not to use the default of 'id'.\n","readmeFilename":"README.md"}