// TODO consider the possible perf benefits of changing this routine // to accept lots of changeset ids instead of just one, so it // can handle them all at once. void SG_treendx__update__multiple( SG_context* pCtx, SG_treendx* pTreeNdx, SG_stringarray* psa ) { SG_changeset* pcs = NULL; sqlite3_stmt* pStmt = NULL; SG_vhash* pvh_treepaths = NULL; SG_uint32 count_treepaths = 0; SG_uint32 count_changesets = 0; SG_uint32 ics = 0; SG_NULLARGCHECK_RETURN(psa); SG_NULLARGCHECK_RETURN(pTreeNdx); SG_ERR_CHECK( SG_stringarray__count(pCtx, psa, &count_changesets) ); SG_ERR_CHECK( sg_sqlite__exec__va(pCtx, pTreeNdx->psql, "BEGIN TRANSACTION; ") ); SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pTreeNdx->psql, &pStmt, "INSERT OR IGNORE INTO treendx (gid, strpath) VALUES (?, ?)") ); for (ics=0; ics<count_changesets; ics++) { const char* psz_hid = NULL; SG_uint32 i = 0; SG_ERR_CHECK( SG_stringarray__get_nth(pCtx, psa, ics, &psz_hid) ); SG_ERR_CHECK( SG_changeset__load_from_repo(pCtx, pTreeNdx->pRepo, psz_hid, &pcs) ); SG_ERR_CHECK( SG_changeset__get_treepaths(pCtx, pcs, &pvh_treepaths) ); if (pvh_treepaths) { SG_ERR_CHECK( SG_vhash__count(pCtx, pvh_treepaths, &count_treepaths) ); for (i=0; i<count_treepaths; i++) { const char* psz_gid = NULL; const SG_variant* pv = NULL; const char* psz_path = NULL; SG_ERR_CHECK( SG_vhash__get_nth_pair(pCtx, pvh_treepaths, i, &psz_gid, &pv) ); SG_ERR_CHECK( SG_variant__get__sz(pCtx, pv, &psz_path) ); SG_ERR_CHECK( sg_sqlite__reset(pCtx, pStmt) ); SG_ERR_CHECK( sg_sqlite__clear_bindings(pCtx, pStmt) ); SG_ERR_CHECK( sg_sqlite__bind_text(pCtx, pStmt, 1, psz_gid) ); SG_ERR_CHECK( sg_sqlite__bind_text(pCtx, pStmt, 2, psz_path) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); } } SG_CHANGESET_NULLFREE(pCtx, pcs); } SG_ERR_CHECK( sg_sqlite__nullfinalize(pCtx, &pStmt) ); SG_ERR_CHECK( sg_sqlite__exec__va(pCtx, pTreeNdx->psql, "COMMIT TRANSACTION; ") ); fail: SG_CHANGESET_NULLFREE(pCtx, pcs); }
void sg_wc_db__gid__get_gid_from_alias(SG_context * pCtx, sg_wc_db * pDb, SG_uint64 uiAliasGid, char ** ppszGid) { char * pszGid = NULL; int rc; // TODO 2011/08/01 Should this check for "*null*" and offer to return NULL ? //Caching the prepared statement is a pretty huge performance win. if (pDb->pSqliteStmt__get_gid_from_alias == NULL) { SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pDb->pSqliteStmt__get_gid_from_alias, ("SELECT gid FROM tbl_gid WHERE alias_gid = ?")) ); } SG_ERR_CHECK( sg_sqlite__bind_int64(pCtx, pDb->pSqliteStmt__get_gid_from_alias, 1, uiAliasGid) ); if ((rc=sqlite3_step(pDb->pSqliteStmt__get_gid_from_alias)) != SQLITE_ROW) { SG_int_to_string_buffer bufui64; SG_ERR_THROW2( SG_ERR_SQLITE(rc), (pCtx, "sg_wc_db:tbl_gid can't find alias %s.", SG_uint64_to_sz(uiAliasGid, bufui64)) ); } SG_ERR_CHECK( SG_STRDUP(pCtx, (const char *)sqlite3_column_text(pDb->pSqliteStmt__get_gid_from_alias, 0), &pszGid) ); SG_ERR_CHECK( sg_sqlite__reset(pCtx, pDb->pSqliteStmt__get_gid_from_alias) ); SG_ERR_CHECK( sg_sqlite__clear_bindings(pCtx, pDb->pSqliteStmt__get_gid_from_alias) ); *ppszGid = pszGid; return; fail: SG_ERR_IGNORE( sg_sqlite__reset(pCtx, pDb->pSqliteStmt__get_gid_from_alias) ); SG_ERR_IGNORE( sg_sqlite__clear_bindings(pCtx, pDb->pSqliteStmt__get_gid_from_alias) ); SG_NULLFREE(pCtx, pszGid); }
/** * BIND the fields for an INSERT or UPDATE a single row for this TreeNodeEntry (not * recursive) to the tne_L0 table. Caller must compute the * GID aliases for the foreign keys and have already added * rows to tbl_gid as necessary. */ void sg_wc_db__tne__bind_insert(SG_context * pCtx, sqlite3_stmt * pStmt, SG_uint64 uiAliasGid, SG_uint64 uiAliasGidParent, const SG_treenode_entry * pTreenodeEntry) { const char * pszHid = NULL; // we do not own this const char * pszEntryname = NULL; // we do not own this SG_int64 attrbits; SG_treenode_entry_type tneType; // pull all of the fields from the TNE. SG_ERR_CHECK( SG_treenode_entry__get_hid_blob(pCtx, pTreenodeEntry, &pszHid) ); SG_ERR_CHECK( SG_treenode_entry__get_entry_name(pCtx, pTreenodeEntry, &pszEntryname) ); SG_ERR_CHECK( SG_treenode_entry__get_entry_type(pCtx, pTreenodeEntry, &tneType) ); SG_ERR_CHECK( SG_treenode_entry__get_attribute_bits(pCtx, pTreenodeEntry, &attrbits) ); #if TRACE_WC_ATTRBITS SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "TNE: bind_insert (%d) %s\n", ((SG_uint32)attrbits), pszEntryname) ); #endif SG_ERR_CHECK( sg_sqlite__reset(pCtx, pStmt) ); SG_ERR_CHECK( sg_sqlite__clear_bindings(pCtx, pStmt) ); SG_ERR_CHECK( sg_sqlite__bind_int64( pCtx, pStmt, 1, uiAliasGid) ); SG_ERR_CHECK( sg_sqlite__bind_int64( pCtx, pStmt, 2, uiAliasGidParent) ); SG_ERR_CHECK( sg_sqlite__bind_text__transient(pCtx, pStmt, 3, pszHid) ); SG_ERR_CHECK( sg_sqlite__bind_int( pCtx, pStmt, 4, tneType) ); SG_ERR_CHECK( sg_sqlite__bind_int64( pCtx, pStmt, 5, attrbits) ); SG_ERR_CHECK( sg_sqlite__bind_text__transient(pCtx, pStmt, 6, pszEntryname) ); fail: return; }