void sg_wc_db__gid__get_alias_from_gid(SG_context * pCtx, sg_wc_db * pDb, const char * pszGid, SG_uint64 * puiAliasGid) { sqlite3_stmt * pStmt = NULL; SG_uint64 uiAliasGid = 0; int rc; SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("SELECT alias_gid FROM tbl_gid WHERE gid = ?")) ); SG_ERR_CHECK( sg_sqlite__bind_text(pCtx, pStmt, 1, ((pszGid && *pszGid) ? pszGid : SG_WC_DB__GID__NULL_ROOT)) ); if ((rc=sqlite3_step(pStmt)) != SQLITE_ROW) SG_ERR_THROW2( SG_ERR_SQLITE(rc), (pCtx, "sg_wc_db:tbl_gid can't find gid %s.", pszGid) ); uiAliasGid = (SG_uint64)sqlite3_column_int64(pStmt, 0); SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); *puiAliasGid = uiAliasGid; return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); }
void SG_treendx__get_all_paths(SG_context* pCtx, SG_treendx* pTreeNdx, const char* psz_gid, SG_stringarray ** ppResults) { sqlite3_stmt* pStmt = NULL; SG_stringarray * pResults = NULL; int rc; SG_ERR_CHECK_RETURN( SG_gid__argcheck(pCtx, psz_gid) ); SG_ERR_CHECK( SG_STRINGARRAY__ALLOC(pCtx,&pResults, 1) ); SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pTreeNdx->psql, &pStmt, "SELECT strpath FROM treendx WHERE gid='%s' ORDER BY strpath;", psz_gid) ); while ((rc = sqlite3_step(pStmt)) == SQLITE_ROW) { const char* pszPath = (const char*) sqlite3_column_text(pStmt, 0); SG_ERR_CHECK( SG_stringarray__add(pCtx, pResults, pszPath) ); } if (rc != SQLITE_DONE) { SG_ERR_THROW(SG_ERR_SQLITE(rc)); } SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); *ppResults = pResults; return; fail: if (pStmt) { SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); } }
void sg_wc_db__gid__delete_all_tmp(SG_context * pCtx, sg_wc_db * pDb) { sqlite3_stmt * pStmt = NULL; #if TRACE_WC_DB SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "sg_wc_db__gid__delete_all_tmp: had %d tmp gids.\n", pDb->nrTmpGids) ); #endif if (pDb->nrTmpGids == 0) return; SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("DELETE FROM tbl_gid WHERE tmp != 0")) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); pDb->nrTmpGids = 0; return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); }
void sg_wc_db__gid__prepare_toggle_tmp_stmt(SG_context * pCtx, sg_wc_db * pDb, SG_uint64 uiAliasGid, SG_bool bIsTmp, sqlite3_stmt ** ppStmt) { sqlite3_stmt * pStmt = NULL; #if TRACE_WC_DB { SG_int_to_string_buffer bufui64; SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "sg_wc_db__gid__prepare_toggle_tmp_stmt: %s --> %c\n", SG_uint64_to_sz(uiAliasGid, bufui64), ((bIsTmp) ? 'T' : 'F')) ); } #endif SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("UPDATE tbl_gid SET tmp = ? WHERE alias_gid = ?")) ); SG_ERR_CHECK( sg_sqlite__bind_int( pCtx, pStmt, 1, bIsTmp) ); SG_ERR_CHECK( sg_sqlite__bind_int64(pCtx, pStmt, 2, uiAliasGid) ); *ppStmt = pStmt; return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); }
/** * Find the alias-gid for the root "@/" (aka "@b/"). Unlike the null-root, * this is not a compile-time constant. (perhaps it should be.) * * Since neither the GID nor repo-path of the root directory * can ever change, the TX-layer caller can just ask us for * the alias of the root directory and not have to bother with * TNE/PC and/or the prescan/liveview stuff. * * We could/should use sg_wc_db__tne__foreach_in_dir_by_parent_alias() * and pass __NULL_ROOT and set up a callback to get the first result * rather than duplicating parts of that routine, but that felt like * too much trouble. (But we could also verify that there is exactly * one row and it has the correct entryname.) * */ void sg_wc_db__tne__get_alias_of_root(SG_context * pCtx, sg_wc_db * pDb, const sg_wc_db__cset_row * pCSetRow, SG_uint64 * puiAliasGid_Root) { sqlite3_stmt * pStmt = NULL; int rc; SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("SELECT" " alias_gid" // 0 " FROM %s" " WHERE (alias_gid_parent = ?)"), pCSetRow->psz_tne_table_name) ); SG_ERR_CHECK( sg_sqlite__bind_int64(pCtx, pStmt, 1, SG_WC_DB__ALIAS_GID__NULL_ROOT) ); if ((rc=sqlite3_step(pStmt)) != SQLITE_ROW) { SG_ERR_THROW2( SG_ERR_SQLITE(rc), (pCtx, "sg_wc_db:%s can't find tne row for '@/' (aka '@b/').", pCSetRow->psz_tne_table_name) ); } *puiAliasGid_Root = (SG_uint64)sqlite3_column_int64(pStmt, 0); fail: SG_ERR_IGNORE( sg_sqlite__nullfinalize(pCtx, &pStmt) ); }
// 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); }
/** * Iterate over all items that list the given gid as * their parent directory. * * Warning: if you give a bogus directory gid, we can't * tell -- our SELECT just won't find any. * */ void sg_wc_db__tne__foreach_in_dir_by_parent_alias(SG_context * pCtx, sg_wc_db * pDb, const sg_wc_db__cset_row * pCSetRow, SG_uint64 uiAliasGidParent, sg_wc_db__tne__foreach_cb * pfn_cb, void * pVoidData) { sqlite3_stmt * pStmt = NULL; sg_wc_db__tne_row * pTneRow = NULL; int rc; SG_ARGCHECK_RETURN( (uiAliasGidParent != SG_WC_DB__ALIAS_GID__UNDEFINED), uiAliasGidParent ); SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("SELECT" " alias_gid," // 0 " hid," // 1 " type," // 2 " attrbits," // 3 " entryname" // 4 " FROM %s" " WHERE (alias_gid_parent = ?)"), pCSetRow->psz_tne_table_name) ); SG_ERR_CHECK( sg_sqlite__bind_int64(pCtx, pStmt, 1, uiAliasGidParent) ); while ((rc=sqlite3_step(pStmt)) == SQLITE_ROW) { SG_ERR_CHECK( sg_wc_db__tne_row__alloc(pCtx, &pTneRow) ); pTneRow->p_s->uiAliasGid = (SG_uint64)sqlite3_column_int64(pStmt, 0); pTneRow->p_s->uiAliasGidParent = uiAliasGidParent; SG_ERR_CHECK( SG_STRDUP(pCtx, (const char *)sqlite3_column_text(pStmt, 1), &pTneRow->p_d->pszHid) ); pTneRow->p_s->tneType = (SG_uint32)sqlite3_column_int(pStmt, 2); pTneRow->p_d->attrbits = (SG_uint64)sqlite3_column_int64(pStmt, 3); SG_ERR_CHECK( SG_STRDUP(pCtx, (const char *)sqlite3_column_text(pStmt, 4), &pTneRow->p_s->pszEntryname) ); // pass the tne_row by address so that the caller can steal it if they want to. SG_ERR_CHECK( (*pfn_cb)(pCtx, pVoidData, &pTneRow) ); SG_WC_DB__TNE_ROW__NULLFREE(pCtx, pTneRow); } if (rc != SQLITE_DONE) { SG_ERR_THROW( SG_ERR_SQLITE(rc) ); } SG_ERR_CHECK( sg_sqlite__nullfinalize(pCtx, &pStmt) ); return; fail: SG_ERR_IGNORE( sg_sqlite__nullfinalize(pCtx, &pStmt) ); SG_WC_DB__TNE_ROW__NULLFREE(pCtx, pTneRow); }
/** * Fetch the current branch if attached. * Return NULL if detached. * */ void sg_wc_db__branch__get_branch(SG_context * pCtx, sg_wc_db * pDb, char ** ppszBranchName) { sqlite3_stmt * pStmt = NULL; int rc; SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("SELECT" " name" // 0 " FROM tbl_branch" " WHERE id = ?")) ); SG_ERR_CHECK( sg_sqlite__bind_int64(pCtx, pStmt, 1, ID_KEY) ); rc = sqlite3_step(pStmt); switch (rc) { case SQLITE_ROW: if (sqlite3_column_type(pStmt, 0) == SQLITE_NULL) *ppszBranchName = NULL; else SG_ERR_CHECK( SG_STRDUP(pCtx, (const char *)sqlite3_column_text(pStmt, 0), ppszBranchName) ); break; case SQLITE_DONE: *ppszBranchName = NULL; break; default: SG_ERR_THROW2( SG_ERR_SQLITE(rc), (pCtx, "sg_wc_db:tbl_branch can't get branch name.") ); } SG_ERR_CHECK( sg_sqlite__nullfinalize(pCtx, &pStmt) ); #if TRACE_WC_DB SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "sg_wc_db__branch__get_branch: %s\n", ((*ppszBranchName) ? (*ppszBranchName) : "<detached>")) ); #endif return; fail: SG_ERR_IGNORE( sg_sqlite__nullfinalize(pCtx, &pStmt) ); }
static void _sg_wc_db__gid__insert(SG_context * pCtx, sg_wc_db * pDb, const char * pszGid, SG_bool bIsTmp) { sqlite3_stmt * pStmt = NULL; SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("INSERT OR IGNORE INTO tbl_gid ( gid, tmp ) VALUES ( ?, ? )")) ); SG_ERR_CHECK( sg_sqlite__bind_text(pCtx, pStmt, 1, pszGid) ); SG_ERR_CHECK( sg_sqlite__bind_int( pCtx, pStmt, 2, bIsTmp) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); }
/** * Insert a row into the "tbl_gid" table WITH A FIXED AND KNOWN ALIAS. * We only use this for the special pseudo-gids. This overrides the * auto-increment feature on the alias_gid field. */ void sg_wc_db__gid__insert_known(SG_context * pCtx, sg_wc_db * pDb, SG_uint64 uiAliasGid, const char * pszGid) { sqlite3_stmt * pStmt = NULL; SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("INSERT OR REPLACE INTO tbl_gid ( alias_gid, gid, tmp ) VALUES (?, ?, 0)")) ); SG_ERR_CHECK( sg_sqlite__bind_int64(pCtx, pStmt, 1, uiAliasGid) ); SG_ERR_CHECK( sg_sqlite__bind_text(pCtx, pStmt, 2, pszGid) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); }
/** * DROP and CREATE a fresh tbl_L[k] table and populate it with * the contents of the CSET with the given SuperRoot HID. */ void sg_wc_db__tne__populate_named_table(SG_context * pCtx, sg_wc_db * pDb, const sg_wc_db__cset_row * pCSetRow, const char * pszHidSuperRoot, SG_bool bCreateIndex) { sqlite3_stmt * pStmt = NULL; // drop/create the TNE table for this cset. SG_ERR_CHECK_RETURN( sg_wc_db__tx__assert(pCtx, pDb) ); SG_ERR_CHECK( sg_wc_db__tne__drop_named_table(pCtx, pDb, pCSetRow) ); SG_ERR_CHECK( sg_wc_db__tne__create_named_table(pCtx, pDb, pCSetRow) ); // start populating the table pair with the entire CSET. SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("INSERT INTO %s" " (" " alias_gid," " alias_gid_parent," " hid," " type," " attrbits," " entryname" " )" " VALUES" " (?, ?, ?, ?, ?, ?)"), pCSetRow->psz_tne_table_name) ); SG_ERR_CHECK( sg_wc_db__tne__process_super_root(pCtx, pDb, pCSetRow, pStmt, pszHidSuperRoot) ); if (bCreateIndex) SG_ERR_CHECK( sg_wc_db__tne__create_index(pCtx, pDb, pCSetRow) ); SG_ERR_CHECK( sg_sqlite__nullfinalize(pCtx, &pStmt) ); return; fail: SG_ERR_IGNORE( sg_sqlite__nullfinalize(pCtx, &pStmt) ); }
void sg_wc_db__tne__prepare_delete_stmt(SG_context * pCtx, sg_wc_db * pDb, sg_wc_db__cset_row * pCSetRow, SG_uint64 uiAliasGid, sqlite3_stmt ** ppStmt) { sqlite3_stmt * pStmt = NULL; SG_ERR_CHECK_RETURN( sg_wc_db__tx__assert(pCtx, pDb) ); SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("DELETE FROM %s WHERE alias_gid = ?"), pCSetRow->psz_tne_table_name) ); SG_ERR_CHECK( sg_sqlite__bind_int64(pCtx, pStmt, 1, uiAliasGid) ); *ppStmt = pStmt; return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); }
void sg_wc_db__tne__prepare_insert_stmt(SG_context * pCtx, sg_wc_db * pDb, sg_wc_db__cset_row * pCSetRow, SG_uint64 uiAliasGid, SG_uint64 uiAliasGid_Parent, const SG_treenode_entry * pTNE, sqlite3_stmt ** ppStmt) { sqlite3_stmt * pStmt = NULL; SG_ERR_CHECK_RETURN( sg_wc_db__tx__assert(pCtx, pDb) ); // Note: This pStmt is used by wc5queue/wc5apply so we can't // cache this statement and reset/re-bind the fields // like we do during a __load_named_cset(). SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("INSERT OR REPLACE INTO %s" " (" " alias_gid," " alias_gid_parent," " hid," " type," " attrbits," " entryname" " )" " VALUES" " (?, ?, ?, ?, ?, ?)"), pCSetRow->psz_tne_table_name) ); SG_ERR_CHECK( sg_wc_db__tne__bind_insert(pCtx, pStmt, uiAliasGid, uiAliasGid_Parent, pTNE) ); *ppStmt = pStmt; return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); }
void sg_wc_db__branch__detach(SG_context * pCtx, sg_wc_db * pDb) { sqlite3_stmt * pStmt = NULL; #if TRACE_WC_DB SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "sg_wc_db__branch__detach:\n") ); #endif SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("INSERT OR REPLACE INTO tbl_branch ( id, name ) VALUES ( ?, ? )")) ); SG_ERR_CHECK( sg_sqlite__bind_int(pCtx, pStmt, 1, ID_KEY) ); SG_ERR_CHECK( sg_sqlite__bind_null(pCtx, pStmt, 2) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); }
/** * Attach/tie the WD to the given branch. * * We optionally validate the name (so that they can attach to * old pre-2.0 branches that allowed punctuation characters). * * We optionally verify that the branch name does/does not exist * (corresponding to --attach or --attach-new). * * We don't care one way or the other and only provide these * options as a service to the caller. You probably don't need * to use them since the caller should have already validated/verified * all this before while they were parsing the user's input. * */ void sg_wc_db__branch__attach(SG_context * pCtx, sg_wc_db * pDb, const char * pszBranchName, SG_vc_branches__check_attach_name__flags flags, SG_bool bValidateName) { sqlite3_stmt * pStmt = NULL; char * pszNormalizedBranchName = NULL; // however, we always normalize the name SG_NONEMPTYCHECK_RETURN( pszBranchName ); #if TRACE_WC_DB SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "sg_wc_db__branch__attach: [flags %d][validate %d] %s\n", (SG_uint32)flags, bValidateName, pszBranchName) ); #endif SG_ERR_CHECK( SG_vc_branches__check_attach_name(pCtx, pDb->pRepo, pszBranchName, flags, bValidateName, &pszNormalizedBranchName) ); SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("INSERT OR REPLACE INTO tbl_branch ( id, name ) VALUES ( ?, ? )")) ); SG_ERR_CHECK( sg_sqlite__bind_int(pCtx, pStmt, 1, ID_KEY) ); // probably unnecessary since __check_attach_name should have thrown. if (pszNormalizedBranchName && *pszNormalizedBranchName) SG_ERR_CHECK( sg_sqlite__bind_text(pCtx, pStmt, 2, pszNormalizedBranchName) ); else SG_ERR_CHECK( sg_sqlite__bind_null(pCtx, pStmt, 2) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); SG_NULLFREE(pCtx, pszNormalizedBranchName); return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); SG_NULLFREE(pCtx, pszNormalizedBranchName); }
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); }
void sg_wc_db__gid__get_gid_from_alias2(SG_context * pCtx, sg_wc_db * pDb, SG_uint64 uiAliasGid, char ** ppszGid, SG_bool * pbIsTmp) { sqlite3_stmt * pStmt = NULL; char * pszGid = NULL; int rc; SG_bool bIsTmp; // TODO 2011/08/01 Should this check for "*null*" and offer to return NULL ? SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("SELECT gid,tmp FROM tbl_gid WHERE alias_gid = ?")) ); SG_ERR_CHECK( sg_sqlite__bind_int64(pCtx, pStmt, 1, uiAliasGid) ); if ((rc=sqlite3_step(pStmt)) != 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(pStmt, 0), &pszGid) ); bIsTmp = (sqlite3_column_int(pStmt, 1) != 0); SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); *ppszGid = pszGid; *pbIsTmp = bIsTmp; return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); SG_NULLFREE(pCtx, pszGid); }
/** * Get the TNE Row for the (uiAliasGirParent, pszEntryname) pair. * This should not have any of the entryname ambiguity problems * that such a request on the live view might have. * */ void sg_wc_db__tne__get_row_by_parent_alias_and_entryname(SG_context * pCtx, sg_wc_db * pDb, const sg_wc_db__cset_row * pCSetRow, SG_uint64 uiAliasGidParent, const char * pszEntryname, SG_bool * pbFound, sg_wc_db__tne_row ** ppTneRow) { sqlite3_stmt * pStmt = NULL; sg_wc_db__tne_row * pTneRow = NULL; int rc; SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("SELECT" " alias_gid," // 0 " hid," // 1 " type," // 2 " attrbits" // 3 " FROM %s" " WHERE alias_gid_parent = ?" " AND entryname = ?"), pCSetRow->psz_tne_table_name) ); SG_ERR_CHECK( sg_sqlite__bind_int64(pCtx, pStmt, 1, uiAliasGidParent) ); SG_ERR_CHECK( sg_sqlite__bind_text(pCtx, pStmt, 2, pszEntryname) ); if ((rc=sqlite3_step(pStmt)) != SQLITE_ROW) { SG_int_to_string_buffer bufui64; if ((rc == SQLITE_DONE) && pbFound) { *pbFound = SG_FALSE; *ppTneRow = NULL; goto done; } SG_ERR_THROW2( SG_ERR_SQLITE(rc), (pCtx, "sg_wc_db:%s can't find tne row for parent alias %s and entryname '%s'.", pCSetRow->psz_tne_table_name, SG_uint64_to_sz(uiAliasGidParent, bufui64), pszEntryname) ); } SG_ERR_CHECK( sg_wc_db__tne_row__alloc(pCtx, &pTneRow) ); pTneRow->p_s->uiAliasGid = (SG_uint64)sqlite3_column_int64(pStmt, 0); pTneRow->p_s->uiAliasGidParent = uiAliasGidParent; SG_ERR_CHECK( SG_STRDUP(pCtx, (const char *)sqlite3_column_text(pStmt, 1), &pTneRow->p_d->pszHid) ); pTneRow->p_s->tneType = (SG_uint32)sqlite3_column_int(pStmt, 2); pTneRow->p_d->attrbits = (SG_uint64)sqlite3_column_int64(pStmt, 3); SG_ERR_CHECK( SG_STRDUP(pCtx, pszEntryname, &pTneRow->p_s->pszEntryname) ); SG_ERR_CHECK( sg_sqlite__nullfinalize(pCtx, &pStmt) ); #if TRACE_WC_DB SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "sg_wc_db__tne__get_row_by_parent_alias_and_entryname: found:\n") ); SG_ERR_IGNORE( sg_wc_db__debug__tne_row__print(pCtx, pTneRow) ); #endif if (pbFound) *pbFound = SG_TRUE; *ppTneRow = pTneRow; return; fail: SG_WC_DB__TNE_ROW__NULLFREE(pCtx, pTneRow); done: SG_ERR_IGNORE( sg_sqlite__nullfinalize(pCtx, &pStmt) ); }