{"action":"created","comment":{"url":"https://api.github.com/repos/bloomberg/comdb2/pulls/comments/203852237","pull_request_review_id":138827402,"id":203852237,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwMzg1MjIzNw==","diff_hunk":"@@ -0,0 +1,1507 @@\n+/*\n+   Copyright 2018 Bloomberg Finance L.P.\n+\n+   Licensed under the Apache License, Version 2.0 (the \"License\");\n+   you may not use this file except in compliance with the License.\n+   You may obtain a copy of the License at\n+\n+       http://www.apache.org/licenses/LICENSE-2.0\n+\n+   Unless required by applicable law or agreed to in writing, software\n+   distributed under the License is distributed on an \"AS IS\" BASIS,\n+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+   See the License for the specific language governing permissions and\n+   limitations under the License.\n+ */\n+\n+#include <stdarg.h>\n+#include \"sqlite3ext.h\"\n+#include <assert.h>\n+#include <string.h>\n+#include \"comdb2.h\"\n+#include \"sql.h\"\n+#include \"build/db.h\"\n+#include \"build/db_int.h\"\n+#include \"dbinc/db_swap.h\"\n+#include \"dbinc/txn.h\"\n+#include \"dbinc_auto/txn_ext.h\"\n+#include \"dbinc_auto/txn_auto.h\"\n+#include \"bdb_osql_log_rec.h\"\n+#include \"llog_auto.h\"\n+#include \"bdb_osqllog.h\"\n+#include \"util.h\"\n+#include <bdb/bdb_int.h>\n+#include \"llog_ext.h\"\n+\n+/* Allocate maximum for unpacking */\n+#define PACKED_MEMORY_SIZE (MAXBLOBLENGTH + 7)\n+\n+/* Column numbers */\n+#define LOGICALOPS_COLUMN_START        0\n+#define LOGICALOPS_COLUMN_STOP         1\n+#define LOGICALOPS_COLUMN_COMMITLSN    2\n+#define LOGICALOPS_COLUMN_OPNUM        3\n+#define LOGICALOPS_COLUMN_OPERATION    4\n+#define LOGICALOPS_COLUMN_TABLE        5\n+#define LOGICALOPS_COLUMN_OLDGENID     6\n+#define LOGICALOPS_COLUMN_OLDRECORD    7\n+#define LOGICALOPS_COLUMN_GENID        8\n+#define LOGICALOPS_COLUMN_RECORD       9\n+\n+/* Dynamically reallocating string type */\n+typedef struct dynstr {\n+    char *buf;\n+    int len;\n+    int alloced;\n+} dynstr_t;\n+\n+/* Modeled after generate_series */\n+typedef struct logicalops_cursor logicalops_cursor;\n+struct logicalops_cursor {\n+  sqlite3_vtab_cursor base;  /* Base class - must be first */\n+  sqlite3_int64 iRowid;      /* The rowid */\n+  DB_LSN curLsn;             /* Current LSN */\n+  DB_LSN minLsn;             /* Minimum LSN */\n+  DB_LSN maxLsn;             /* Maximum LSN */\n+  char *minLsnStr;\n+  char *maxLsnStr;\n+  char *curLsnStr;\n+  int hitLast;\n+  int openCursor;\n+  int subop;\n+  DB_LOGC *logc;             /* Log Cursor */\n+  DBT data;\n+  bdb_osql_log_t *log;\n+  char *tz;\n+  char *table;\n+  void *packedprev;\n+  void *unpackedprev;\n+  void *packed;\n+  void *unpacked;\n+  dynstr_t jsonrec;\n+  dynstr_t oldjsonrec;\n+  struct dbtable *db;\n+  struct odh odh;\n+  struct odh oldodh;\n+  void *record;\n+  void *oldrecord;\n+  char opstring[32];\n+  char oldgenid[32];\n+  char genid[32];\n+  int reclen;\n+  int oldreclen;\n+};\n+\n+static int logicalopsConnect(\n+  sqlite3 *db,\n+  void *pAux,\n+  int argc, const char *const*argv,\n+  sqlite3_vtab **ppVtab,\n+  char **pzErr\n+){\n+  sqlite3_vtab *pNew;\n+  int rc;\n+  rc = sqlite3_declare_vtab(db,\n+     \"CREATE TABLE x(minlsn hidden,maxlsn hidden,commitlsn,opnum,operation,tablename,oldgenid,oldrecord,genid,record)\");\n+  if( rc==SQLITE_OK ){\n+    pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );\n+    if( pNew==0 ) return SQLITE_NOMEM;\n+    memset(pNew, 0, sizeof(*pNew));\n+  }\n+\n+  return rc;\n+}\n+\n+static int logicalopsDisconnect(sqlite3_vtab *pVtab){\n+  sqlite3_free(pVtab);\n+  return SQLITE_OK;\n+}\n+\n+static int logicalopsOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){\n+  logicalops_cursor *pCur;\n+  pCur = sqlite3_malloc( sizeof(*pCur) );\n+  if( pCur==0 ) return SQLITE_NOMEM;\n+  memset(pCur, 0, sizeof(*pCur));\n+  struct sql_thread *thd = pthread_getspecific(query_info_key);\n+  if (thd && thd->clnt)\n+      pCur->tz = thd->clnt->tzname;\n+  *ppCursor = &pCur->base;\n+  return SQLITE_OK;\n+}\n+\n+static int logicalopsClose(sqlite3_vtab_cursor *cur){\n+  logicalops_cursor *pCur = (logicalops_cursor*)cur;\n+  if (pCur->openCursor) {\n+      assert(pCur->logc);\n+      pCur->logc->close(pCur->logc, 0);\n+      pCur->openCursor = 0;\n+  }\n+  if (pCur->data.data)\n+      free(pCur->data.data);\n+  if (pCur->minLsnStr)\n+      sqlite3_free(pCur->minLsnStr);\n+  if (pCur->maxLsnStr)\n+      sqlite3_free(pCur->maxLsnStr);\n+  if (pCur->curLsnStr)\n+      sqlite3_free(pCur->curLsnStr);\n+  if (pCur->packed)\n+      sqlite3_free(pCur->packed);\n+  if (pCur->unpacked)\n+      sqlite3_free(pCur->unpacked);\n+  if (pCur->packedprev)\n+      sqlite3_free(pCur->packedprev);\n+  if (pCur->unpackedprev)\n+      sqlite3_free(pCur->unpackedprev);\n+  if (pCur->jsonrec.buf)\n+      free(pCur->jsonrec.buf);\n+  if (pCur->oldjsonrec.buf)\n+      free(pCur->oldjsonrec.buf);\n+  if (pCur->table)\n+      free(pCur->table);\n+  sqlite3_free(pCur);\n+  return SQLITE_OK;\n+}\n+\n+static int is_commit(u_int32_t rectype)\n+{\n+    switch(rectype) {\n+        case DB___txn_regop:\n+        case DB___txn_regop_gen:\n+        case DB___txn_regop_rowlocks:\n+            return 1;\n+        default:\n+            return 0;\n+    }\n+}\n+\n+static inline int retrieve_start_lsn(DBT *data, u_int32_t rectype, DB_LSN *lsn)\n+{\n+    bdb_state_type *bdb_state = thedb->bdb_env;\n+    DB_ENV *dbenv = bdb_state->dbenv;\n+\t__txn_regop_args *txn_args;\n+\t__txn_regop_gen_args *txn_gen_args;\n+\t__txn_regop_rowlocks_args *txn_rl_args;\n+    int rc;\n+\n+    switch(rectype) {\n+        case DB___txn_regop:\n+            if ((rc = __txn_regop_read(dbenv, data->data,\n+                            &txn_args)) != 0) {\n+                logmsg(LOGMSG_ERROR, \"%s line %d regop read returns %d for \"\n+                        \"%d:%d\\n\", __func__, __LINE__, rc, lsn->file,\n+                        lsn->offset);\n+                return 1;\n+            }\n+            if (txn_args->opcode != TXN_COMMIT) {\n+                logmsg(LOGMSG_ERROR, \"%s line %d regop opcode not commit, %d \"\n+                        \"for %d:%d\\n\", __func__, __LINE__, txn_args->opcode,\n+                        lsn->file, lsn->offset);\n+                free(txn_args);\n+                return 1;\n+            }\n+            *lsn = txn_args->prev_lsn;\n+            free(txn_args);\n+            break;\n+\n+        case DB___txn_regop_gen:\n+            if ((rc = __txn_regop_gen_read(dbenv, data->data,\n+                            &txn_gen_args)) != 0) {\n+                logmsg(LOGMSG_ERROR, \"%s line %d regop_gen read returns %d for \"\n+                        \"%d:%d\\n\", __func__, __LINE__, rc, lsn->file,\n+                        lsn->offset);\n+                return 1;\n+            }\n+            if (txn_gen_args->opcode != TXN_COMMIT) {\n+                logmsg(LOGMSG_ERROR, \"%s line %d regop_gen opcode not commit, \"\n+                        \"%d for %d:%d\\n\", __func__, __LINE__,\n+                        txn_gen_args->opcode, lsn->file, lsn->offset);\n+                free(txn_gen_args);\n+                return 1;\n+            }\n+            *lsn = txn_gen_args->prev_lsn;\n+            free(txn_gen_args);\n+            break;\n+\n+        case DB___txn_regop_rowlocks:\n+            if ((rc = __txn_regop_rowlocks_read(dbenv, data->data,\n+                            &txn_rl_args)) != 0) {\n+                logmsg(LOGMSG_ERROR, \"%s line %d regop_rl opcode failed read, \"\n+                        \"%d for %d:%d\\n\",\n+                        __func__, __LINE__, rc, lsn->file, lsn->offset);\n+                free(txn_rl_args);\n+                return 1;\n+            }\n+\n+            if (txn_rl_args->opcode != TXN_COMMIT ||\n+                    !(txn_rl_args->lflags & DB_TXN_LOGICAL_COMMIT)) {\n+                logmsg(LOGMSG_ERROR, \"%s line %d regop_rl opcode not commit, %d\"\n+                        \"for %d:%d\\n\", __func__, __LINE__, txn_rl_args->opcode,\n+                        lsn->file, lsn->offset);\n+                free(txn_rl_args);\n+                return 1;\n+            }\n+            *lsn = txn_rl_args->prev_lsn;\n+            free(txn_rl_args);\n+            break;\n+\n+        default:\n+            abort();\n+    }\n+    return 0;\n+}\n+\n+static int create_logical_payload(logicalops_cursor *pCur, DB_LSN regop_lsn,\n+        DBT *data, u_int32_t rectype)\n+{\n+    bdb_state_type *bdb_state = thedb->bdb_env;\n+    int rc, bdberr=0;\n+    DB_LOGC *logc;\n+    DB_LSN lsn;\n+\n+    if (rc = retrieve_start_lsn(data, rectype, &lsn))\n+        return rc;\n+\n+    if (rc = bdb_state->dbenv->log_cursor(bdb_state->dbenv, &logc, 0) != 0) {\n+        logmsg(LOGMSG_ERROR, \"%s line %d cannot allocate log-cursor\\n\",\n+                __func__, __LINE__);\n+        return SQLITE_NOMEM;\n+    }\n+\n+    if ((pCur->log = parse_log_for_shadows(bdb_state, logc, &lsn, 0, &bdberr)) == NULL) {\n+        logmsg(LOGMSG_DEBUG, \"%d line %d parse_log_for_shadows failed for \"\n+                \"%d:%d\\n\", __func__, __LINE__, lsn.file, lsn.offset);\n+        logc->close(logc, 0);\n+        return 1;\n+    }\n+\n+    logc->close(logc, 0);\n+    pCur->subop = -1;\n+    return 0;\n+}\n+\n+static int advance_to_next_commit(logicalops_cursor *pCur)\n+{\n+    bdb_state_type *bdb_state = thedb->bdb_env;\n+    u_int32_t rectype = 0;\n+    int rc, getflags = 0, durable_gen = 0;\n+    if (!pCur->openCursor) {\n+        if ((rc = bdb_state->dbenv->log_cursor(bdb_state->dbenv, &pCur->logc,\n+                        0)) != 0) {\n+            logmsg(LOGMSG_ERROR, \"%s line %d error getting log-cursor rc=%d\\n\",\n+                    __func__, __LINE__, rc);\n+            return SQLITE_INTERNAL;\n+        }\n+        pCur->openCursor = 1;\n+        pCur->data.flags = DB_DBT_REALLOC;\n+\n+        if (pCur->minLsn.file == 0) {\n+            getflags = DB_FIRST;\n+        } else {\n+            pCur->curLsn = pCur->minLsn;\n+            getflags = DB_SET;\n+        }\n+    } else {\n+        getflags = DB_NEXT;\n+    }\n+\n+again:\n+    do {\n+        if (rc = pCur->logc->get(pCur->logc, &pCur->curLsn, &pCur->data,\n+                    getflags) != 0) {\n+            pCur->hitLast = 1;\n+        }\n+        getflags = DB_NEXT;\n+        if (pCur->data.data)\n+            LOGCOPY_32(&rectype, pCur->data.data); \n+        else \n+            rectype = 0;\n+    } while(!pCur->hitLast && !is_commit(rectype));\n+\n+\n+    if (!pCur->hitLast) {\n+        /* Can happen if we're missing the beginning of the transaction */\n+        switch (rc = create_logical_payload(pCur, pCur->curLsn, &pCur->data, rectype)){\n+            /* Reconstructed logical log */\n+            case 0:\n+                logmsg(LOGMSG_INFO, \"%s line %d couldn't create payload for %d:%d\\n\",\n+                        __func__, __LINE__, pCur->curLsn.file, pCur->curLsn.offset);\n+                assert(pCur->log != NULL);\n+                break;\n+             /* Go to next */\n+            case 1:\n+                getflags = DB_NEXT;\n+                goto again;\n+                break;\n+            /* Other error */\n+            default:\n+                pCur->hitLast = 1;\n+                break;\n+        }\n+    }\n+    return 0;\n+}\n+\n+static void *retrieve_packed_memory_prev(logicalops_cursor *pCur)\n+{\n+    if (pCur->packedprev == NULL) {\n+        pCur->packedprev = sqlite3_malloc(PACKED_MEMORY_SIZE);\n+    }\n+    return pCur->packedprev;\n+}\n+\n+static void *retrieve_packed_memory(logicalops_cursor *pCur)\n+{\n+    if (pCur->packed == NULL) {\n+        pCur->packed = sqlite3_malloc(PACKED_MEMORY_SIZE);\n+    }\n+    return pCur->packed;\n+}\n+\n+static void *retrieve_unpacked_memory(logicalops_cursor *pCur)\n+{\n+    if (pCur->unpacked == NULL) {\n+        pCur->unpacked = sqlite3_malloc(MAXRECSZ);\n+    }\n+    return pCur->unpacked;\n+}\n+\n+static void *retrieve_unpacked_memory_prev(logicalops_cursor *pCur)\n+{\n+    if (pCur->unpackedprev == NULL) {\n+        pCur->unpackedprev = sqlite3_malloc(MAXRECSZ);\n+    }\n+    return pCur->unpackedprev;\n+}\n+\n+static int decompress_and_upgrade(logicalops_cursor *pCur, char *table,\n+        void *dta, int dtalen, int isrec, char *unpackedbuf, struct odh *odh,\n+        void **record, int *reclen)\n+{\n+    int rc;\n+\n+    if ((rc = bdb_unpack(pCur->db->handle, dta, dtalen, unpackedbuf, MAXRECSZ,\n+                    odh, NULL)) != 0) {\n+        logmsg(LOGMSG_ERROR, \"%s line %d error unpacking buf %d\\n\", __func__,\n+                __LINE__, rc);\n+        return SQLITE_INTERNAL;\n+    }\n+\n+    *record = odh->recptr;\n+\n+    if (isrec && (rc = vtag_to_ondisk_vermap(pCur->db, *record, reclen,\n+                    odh->csc2vers)) <= 0) {\n+        logmsg(LOGMSG_ERROR, \"%s line %d vtag-to-ondisk error %d\\n\", __func__,\n+                __LINE__, rc);\n+        return SQLITE_INTERNAL;\n+    } else {\n+        *reclen = odh->length;\n+    }\n+\n+    return 0;\n+}\n+\n+static void dynstr_reset(dynstr_t *dynstr)\n+{\n+    dynstr->len = 0;\n+    if (dynstr->alloced > 0)\n+        dynstr->buf[0]='\\0';\n+}\n+\n+static int dynstr_append(dynstr_t *dynstr, const char *str, int len)","path":"sqlite/ext/comdb2/logicalops.c","position":410,"original_position":410,"commit_id":"48de21c9952680b151a02deb3eb2d66cb47d8d9a","original_commit_id":"f59399ba299d13bd1d7021cfa8aed686e6c694a7","user":{"login":"markhannum","id":16245330,"node_id":"MDQ6VXNlcjE2MjQ1MzMw","avatar_url":"https://avatars2.githubusercontent.com/u/16245330?v=4","gravatar_id":"","url":"https://api.github.com/users/markhannum","html_url":"https://github.com/markhannum","followers_url":"https://api.github.com/users/markhannum/followers","following_url":"https://api.github.com/users/markhannum/following{/other_user}","gists_url":"https://api.github.com/users/markhannum/gists{/gist_id}","starred_url":"https://api.github.com/users/markhannum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/markhannum/subscriptions","organizations_url":"https://api.github.com/users/markhannum/orgs","repos_url":"https://api.github.com/users/markhannum/repos","events_url":"https://api.github.com/users/markhannum/events{/privacy}","received_events_url":"https://api.github.com/users/markhannum/received_events","type":"User","site_admin":false},"body":"yeah.. changing now.. I discovered strbuf after I wrote this ..","created_at":"2018-07-19T19:57:54Z","updated_at":"2018-07-19T19:57:54Z","html_url":"https://github.com/bloomberg/comdb2/pull/983#discussion_r203852237","pull_request_url":"https://api.github.com/repos/bloomberg/comdb2/pulls/983","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/bloomberg/comdb2/pulls/comments/203852237"},"html":{"href":"https://github.com/bloomberg/comdb2/pull/983#discussion_r203852237"},"pull_request":{"href":"https://api.github.com/repos/bloomberg/comdb2/pulls/983"}},"in_reply_to_id":203412335},"pull_request":{"url":"https://api.github.com/repos/bloomberg/comdb2/pulls/983","id":200780072,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAwNzgwMDcy","html_url":"https://github.com/bloomberg/comdb2/pull/983","diff_url":"https://github.com/bloomberg/comdb2/pull/983.diff","patch_url":"https://github.com/bloomberg/comdb2/pull/983.patch","issue_url":"https://api.github.com/repos/bloomberg/comdb2/issues/983","number":983,"state":"open","locked":false,"title":"Logical log systable","user":{"login":"markhannum","id":16245330,"node_id":"MDQ6VXNlcjE2MjQ1MzMw","avatar_url":"https://avatars2.githubusercontent.com/u/16245330?v=4","gravatar_id":"","url":"https://api.github.com/users/markhannum","html_url":"https://github.com/markhannum","followers_url":"https://api.github.com/users/markhannum/followers","following_url":"https://api.github.com/users/markhannum/following{/other_user}","gists_url":"https://api.github.com/users/markhannum/gists{/gist_id}","starred_url":"https://api.github.com/users/markhannum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/markhannum/subscriptions","organizations_url":"https://api.github.com/users/markhannum/orgs","repos_url":"https://api.github.com/users/markhannum/repos","events_url":"https://api.github.com/users/markhannum/events{/privacy}","received_events_url":"https://api.github.com/users/markhannum/received_events","type":"User","site_admin":false},"body":"The comdb2_logical_operations systable prints the logical operations (insert, update, or delete) done for a given commit.  It requires logical logging to be enabled to work, and does not work across schema changes.  In this form it's useful quickly understand a given commit's logical operations.","created_at":"2018-07-11T17:56:01Z","updated_at":"2018-07-19T19:57:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8e42a9c7241dbc80a6330277b5b1fb5ed79f98f5","assignee":{"login":"mponomar","id":16244873,"node_id":"MDQ6VXNlcjE2MjQ0ODcz","avatar_url":"https://avatars0.githubusercontent.com/u/16244873?v=4","gravatar_id":"","url":"https://api.github.com/users/mponomar","html_url":"https://github.com/mponomar","followers_url":"https://api.github.com/users/mponomar/followers","following_url":"https://api.github.com/users/mponomar/following{/other_user}","gists_url":"https://api.github.com/users/mponomar/gists{/gist_id}","starred_url":"https://api.github.com/users/mponomar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mponomar/subscriptions","organizations_url":"https://api.github.com/users/mponomar/orgs","repos_url":"https://api.github.com/users/mponomar/repos","events_url":"https://api.github.com/users/mponomar/events{/privacy}","received_events_url":"https://api.github.com/users/mponomar/received_events","type":"User","site_admin":false},"assignees":[{"login":"mponomar","id":16244873,"node_id":"MDQ6VXNlcjE2MjQ0ODcz","avatar_url":"https://avatars0.githubusercontent.com/u/16244873?v=4","gravatar_id":"","url":"https://api.github.com/users/mponomar","html_url":"https://github.com/mponomar","followers_url":"https://api.github.com/users/mponomar/followers","following_url":"https://api.github.com/users/mponomar/following{/other_user}","gists_url":"https://api.github.com/users/mponomar/gists{/gist_id}","starred_url":"https://api.github.com/users/mponomar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mponomar/subscriptions","organizations_url":"https://api.github.com/users/mponomar/orgs","repos_url":"https://api.github.com/users/mponomar/repos","events_url":"https://api.github.com/users/mponomar/events{/privacy}","received_events_url":"https://api.github.com/users/mponomar/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/bloomberg/comdb2/pulls/983/commits","review_comments_url":"https://api.github.com/repos/bloomberg/comdb2/pulls/983/comments","review_comment_url":"https://api.github.com/repos/bloomberg/comdb2/pulls/comments{/number}","comments_url":"https://api.github.com/repos/bloomberg/comdb2/issues/983/comments","statuses_url":"https://api.github.com/repos/bloomberg/comdb2/statuses/48de21c9952680b151a02deb3eb2d66cb47d8d9a","head":{"label":"markhannum:logical_log_systable","ref":"logical_log_systable","sha":"48de21c9952680b151a02deb3eb2d66cb47d8d9a","user":{"login":"markhannum","id":16245330,"node_id":"MDQ6VXNlcjE2MjQ1MzMw","avatar_url":"https://avatars2.githubusercontent.com/u/16245330?v=4","gravatar_id":"","url":"https://api.github.com/users/markhannum","html_url":"https://github.com/markhannum","followers_url":"https://api.github.com/users/markhannum/followers","following_url":"https://api.github.com/users/markhannum/following{/other_user}","gists_url":"https://api.github.com/users/markhannum/gists{/gist_id}","starred_url":"https://api.github.com/users/markhannum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/markhannum/subscriptions","organizations_url":"https://api.github.com/users/markhannum/orgs","repos_url":"https://api.github.com/users/markhannum/repos","events_url":"https://api.github.com/users/markhannum/events{/privacy}","received_events_url":"https://api.github.com/users/markhannum/received_events","type":"User","site_admin":false},"repo":{"id":91597642,"node_id":"MDEwOlJlcG9zaXRvcnk5MTU5NzY0Mg==","name":"comdb2","full_name":"markhannum/comdb2","owner":{"login":"markhannum","id":16245330,"node_id":"MDQ6VXNlcjE2MjQ1MzMw","avatar_url":"https://avatars2.githubusercontent.com/u/16245330?v=4","gravatar_id":"","url":"https://api.github.com/users/markhannum","html_url":"https://github.com/markhannum","followers_url":"https://api.github.com/users/markhannum/followers","following_url":"https://api.github.com/users/markhannum/following{/other_user}","gists_url":"https://api.github.com/users/markhannum/gists{/gist_id}","starred_url":"https://api.github.com/users/markhannum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/markhannum/subscriptions","organizations_url":"https://api.github.com/users/markhannum/orgs","repos_url":"https://api.github.com/users/markhannum/repos","events_url":"https://api.github.com/users/markhannum/events{/privacy}","received_events_url":"https://api.github.com/users/markhannum/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/markhannum/comdb2","description":"Bloomberg's distributed RDBMS","fork":true,"url":"https://api.github.com/repos/markhannum/comdb2","forks_url":"https://api.github.com/repos/markhannum/comdb2/forks","keys_url":"https://api.github.com/repos/markhannum/comdb2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/markhannum/comdb2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/markhannum/comdb2/teams","hooks_url":"https://api.github.com/repos/markhannum/comdb2/hooks","issue_events_url":"https://api.github.com/repos/markhannum/comdb2/issues/events{/number}","events_url":"https://api.github.com/repos/markhannum/comdb2/events","assignees_url":"https://api.github.com/repos/markhannum/comdb2/assignees{/user}","branches_url":"https://api.github.com/repos/markhannum/comdb2/branches{/branch}","tags_url":"https://api.github.com/repos/markhannum/comdb2/tags","blobs_url":"https://api.github.com/repos/markhannum/comdb2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/markhannum/comdb2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/markhannum/comdb2/git/refs{/sha}","trees_url":"https://api.github.com/repos/markhannum/comdb2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/markhannum/comdb2/statuses/{sha}","languages_url":"https://api.github.com/repos/markhannum/comdb2/languages","stargazers_url":"https://api.github.com/repos/markhannum/comdb2/stargazers","contributors_url":"https://api.github.com/repos/markhannum/comdb2/contributors","subscribers_url":"https://api.github.com/repos/markhannum/comdb2/subscribers","subscription_url":"https://api.github.com/repos/markhannum/comdb2/subscription","commits_url":"https://api.github.com/repos/markhannum/comdb2/commits{/sha}","git_commits_url":"https://api.github.com/repos/markhannum/comdb2/git/commits{/sha}","comments_url":"https://api.github.com/repos/markhannum/comdb2/comments{/number}","issue_comment_url":"https://api.github.com/repos/markhannum/comdb2/issues/comments{/number}","contents_url":"https://api.github.com/repos/markhannum/comdb2/contents/{+path}","compare_url":"https://api.github.com/repos/markhannum/comdb2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/markhannum/comdb2/merges","archive_url":"https://api.github.com/repos/markhannum/comdb2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/markhannum/comdb2/downloads","issues_url":"https://api.github.com/repos/markhannum/comdb2/issues{/number}","pulls_url":"https://api.github.com/repos/markhannum/comdb2/pulls{/number}","milestones_url":"https://api.github.com/repos/markhannum/comdb2/milestones{/number}","notifications_url":"https://api.github.com/repos/markhannum/comdb2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/markhannum/comdb2/labels{/name}","releases_url":"https://api.github.com/repos/markhannum/comdb2/releases{/id}","deployments_url":"https://api.github.com/repos/markhannum/comdb2/deployments","created_at":"2017-05-17T16:27:16Z","updated_at":"2018-07-18T13:39:57Z","pushed_at":"2018-07-19T19:55:16Z","git_url":"git://github.com/markhannum/comdb2.git","ssh_url":"git@github.com:markhannum/comdb2.git","clone_url":"https://github.com/markhannum/comdb2.git","svn_url":"https://github.com/markhannum/comdb2","homepage":"","size":25624,"stargazers_count":0,"watchers_count":0,"language":"C","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"bloomberg:master","ref":"master","sha":"a94e696200e8eabefd50829f31c130af25677c4d","user":{"login":"bloomberg","id":1416818,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTY4MTg=","avatar_url":"https://avatars2.githubusercontent.com/u/1416818?v=4","gravatar_id":"","url":"https://api.github.com/users/bloomberg","html_url":"https://github.com/bloomberg","followers_url":"https://api.github.com/users/bloomberg/followers","following_url":"https://api.github.com/users/bloomberg/following{/other_user}","gists_url":"https://api.github.com/users/bloomberg/gists{/gist_id}","starred_url":"https://api.github.com/users/bloomberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bloomberg/subscriptions","organizations_url":"https://api.github.com/users/bloomberg/orgs","repos_url":"https://api.github.com/users/bloomberg/repos","events_url":"https://api.github.com/users/bloomberg/events{/privacy}","received_events_url":"https://api.github.com/users/bloomberg/received_events","type":"Organization","site_admin":false},"repo":{"id":91593042,"node_id":"MDEwOlJlcG9zaXRvcnk5MTU5MzA0Mg==","name":"comdb2","full_name":"bloomberg/comdb2","owner":{"login":"bloomberg","id":1416818,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTY4MTg=","avatar_url":"https://avatars2.githubusercontent.com/u/1416818?v=4","gravatar_id":"","url":"https://api.github.com/users/bloomberg","html_url":"https://github.com/bloomberg","followers_url":"https://api.github.com/users/bloomberg/followers","following_url":"https://api.github.com/users/bloomberg/following{/other_user}","gists_url":"https://api.github.com/users/bloomberg/gists{/gist_id}","starred_url":"https://api.github.com/users/bloomberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bloomberg/subscriptions","organizations_url":"https://api.github.com/users/bloomberg/orgs","repos_url":"https://api.github.com/users/bloomberg/repos","events_url":"https://api.github.com/users/bloomberg/events{/privacy}","received_events_url":"https://api.github.com/users/bloomberg/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/bloomberg/comdb2","description":"Bloomberg's distributed RDBMS","fork":false,"url":"https://api.github.com/repos/bloomberg/comdb2","forks_url":"https://api.github.com/repos/bloomberg/comdb2/forks","keys_url":"https://api.github.com/repos/bloomberg/comdb2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bloomberg/comdb2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bloomberg/comdb2/teams","hooks_url":"https://api.github.com/repos/bloomberg/comdb2/hooks","issue_events_url":"https://api.github.com/repos/bloomberg/comdb2/issues/events{/number}","events_url":"https://api.github.com/repos/bloomberg/comdb2/events","assignees_url":"https://api.github.com/repos/bloomberg/comdb2/assignees{/user}","branches_url":"https://api.github.com/repos/bloomberg/comdb2/branches{/branch}","tags_url":"https://api.github.com/repos/bloomberg/comdb2/tags","blobs_url":"https://api.github.com/repos/bloomberg/comdb2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bloomberg/comdb2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bloomberg/comdb2/git/refs{/sha}","trees_url":"https://api.github.com/repos/bloomberg/comdb2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bloomberg/comdb2/statuses/{sha}","languages_url":"https://api.github.com/repos/bloomberg/comdb2/languages","stargazers_url":"https://api.github.com/repos/bloomberg/comdb2/stargazers","contributors_url":"https://api.github.com/repos/bloomberg/comdb2/contributors","subscribers_url":"https://api.github.com/repos/bloomberg/comdb2/subscribers","subscription_url":"https://api.github.com/repos/bloomberg/comdb2/subscription","commits_url":"https://api.github.com/repos/bloomberg/comdb2/commits{/sha}","git_commits_url":"https://api.github.com/repos/bloomberg/comdb2/git/commits{/sha}","comments_url":"https://api.github.com/repos/bloomberg/comdb2/comments{/number}","issue_comment_url":"https://api.github.com/repos/bloomberg/comdb2/issues/comments{/number}","contents_url":"https://api.github.com/repos/bloomberg/comdb2/contents/{+path}","compare_url":"https://api.github.com/repos/bloomberg/comdb2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bloomberg/comdb2/merges","archive_url":"https://api.github.com/repos/bloomberg/comdb2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bloomberg/comdb2/downloads","issues_url":"https://api.github.com/repos/bloomberg/comdb2/issues{/number}","pulls_url":"https://api.github.com/repos/bloomberg/comdb2/pulls{/number}","milestones_url":"https://api.github.com/repos/bloomberg/comdb2/milestones{/number}","notifications_url":"https://api.github.com/repos/bloomberg/comdb2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bloomberg/comdb2/labels{/name}","releases_url":"https://api.github.com/repos/bloomberg/comdb2/releases{/id}","deployments_url":"https://api.github.com/repos/bloomberg/comdb2/deployments","created_at":"2017-05-17T15:39:23Z","updated_at":"2018-07-19T18:08:32Z","pushed_at":"2018-07-19T19:55:17Z","git_url":"git://github.com/bloomberg/comdb2.git","ssh_url":"git@github.com:bloomberg/comdb2.git","clone_url":"https://github.com/bloomberg/comdb2.git","svn_url":"https://github.com/bloomberg/comdb2","homepage":"","size":23653,"stargazers_count":753,"watchers_count":753,"language":"C","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":95,"mirror_url":null,"archived":false,"open_issues_count":63,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":95,"open_issues":63,"watchers":753,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/bloomberg/comdb2/pulls/983"},"html":{"href":"https://github.com/bloomberg/comdb2/pull/983"},"issue":{"href":"https://api.github.com/repos/bloomberg/comdb2/issues/983"},"comments":{"href":"https://api.github.com/repos/bloomberg/comdb2/issues/983/comments"},"review_comments":{"href":"https://api.github.com/repos/bloomberg/comdb2/pulls/983/comments"},"review_comment":{"href":"https://api.github.com/repos/bloomberg/comdb2/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/bloomberg/comdb2/pulls/983/commits"},"statuses":{"href":"https://api.github.com/repos/bloomberg/comdb2/statuses/48de21c9952680b151a02deb3eb2d66cb47d8d9a"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"markhannum"}}