/* caller must free the memory */ csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx, uint64_t inode) { csync_file_stat_t *st = NULL; int rc; if (!inode) { return NULL; } if( !ctx || ctx->db_is_empty ) { return NULL; } if( ctx->statedb.by_inode_stmt == NULL ) { const char *inode_query = "SELECT * FROM metadata WHERE inode=?1"; SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, inode_query, strlen(inode_query), &ctx->statedb.by_inode_stmt, NULL)); ctx->statedb.lastReturnValue = rc; if( rc != SQLITE_OK ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for inode query."); return NULL; } } if( ctx->statedb.by_inode_stmt == NULL ) { return NULL; } sqlite3_bind_int64(ctx->statedb.by_inode_stmt, 1, (long long signed int)inode); rc = _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_inode_stmt); ctx->statedb.lastReturnValue = rc; if( !(rc == SQLITE_ROW || rc == SQLITE_DONE) ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata by inode: %d!", rc); } sqlite3_reset(ctx->statedb.by_inode_stmt); return st; }
csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx, const char *file_id ) { csync_file_stat_t *st = NULL; int rc = 0; if (!file_id) { return 0; } if (c_streq(file_id, "")) { return 0; } if( !ctx || ctx->db_is_empty ) { return NULL; } if( ctx->statedb.by_fileid_stmt == NULL ) { const char *query = "SELECT * FROM metadata WHERE fileid=?1"; SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, query, strlen(query), &ctx->statedb.by_fileid_stmt, NULL)); ctx->statedb.lastReturnValue = rc; if( rc != SQLITE_OK ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for file id query."); return NULL; } } /* bind the query value */ sqlite3_bind_text(ctx->statedb.by_fileid_stmt, 1, file_id, -1, SQLITE_STATIC); rc = _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_fileid_stmt); ctx->statedb.lastReturnValue = rc; if( !(rc == SQLITE_ROW || rc == SQLITE_DONE) ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata: %d!", rc); } // clear the resources used by the statement. sqlite3_reset(ctx->statedb.by_fileid_stmt); return st; }
int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) { int rc; sqlite3_stmt *stmt = NULL; int64_t cnt = 0; if( !path ) { return -1; } if( !ctx || ctx->db_is_empty ) { return -1; } /* Select the entries for anything that starts with (path+'/') * In other words, anything that is between path+'/' and path+'0', * (because '0' follows '/' in ascii) */ const char *below_path_query = "SELECT phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote FROM metadata WHERE path > (?||'/') AND path < (?||'0')"; SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, below_path_query, -1, &stmt, NULL)); ctx->statedb.lastReturnValue = rc; if( rc != SQLITE_OK ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for below path query."); return -1; } if (stmt == NULL) { return -1; } sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 2, path, -1, SQLITE_STATIC); cnt = 0; ctx->statedb.lastReturnValue = rc; do { csync_file_stat_t *st = NULL; rc = _csync_file_stat_from_metadata_table( &st, stmt); if( st ) { /* Check for exclusion from the tree. * Note that this is only a safety net in case the ignore list changes * without a full remote discovery being triggered. */ CSYNC_EXCLUDE_TYPE excluded = csync_excluded_traversal(ctx->excludes, st->path, st->type); if (excluded != CSYNC_NOT_EXCLUDED) { CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", st->path, excluded); if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE || excluded == CSYNC_FILE_SILENTLY_EXCLUDED) { SAFE_FREE(st); continue; } st->instruction = CSYNC_INSTRUCTION_IGNORE; } /* store into result list. */ if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) { SAFE_FREE(st); ctx->status_code = CSYNC_STATUS_TREE_ERROR; break; } cnt++; } } while( rc == SQLITE_ROW ); ctx->statedb.lastReturnValue = rc; if( rc != SQLITE_DONE ) { ctx->status_code = CSYNC_STATUS_TREE_ERROR; } else { CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "%" PRId64 " entries read below path %s from db.", cnt, path); } sqlite3_finalize(stmt); return 0; }
// This funciton parses a line from the metadata table into the given csync_file_stat // structure which it is also allocating. // Note that this function calls laso sqlite3_step to actually get the info from db and // returns the sqlite return type. static int _csync_file_stat_from_metadata_table( csync_file_stat_t **st, sqlite3_stmt *stmt ) { int rc = SQLITE_ERROR; int column_count; int len; if( ! stmt ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Fatal: Statement is NULL."); return SQLITE_ERROR; } column_count = sqlite3_column_count(stmt); SQLITE_BUSY_HANDLED( sqlite3_step(stmt) ); if( rc == SQLITE_ROW ) { if(column_count > 7) { const char *name; /* phash, pathlen, path, inode, uid, gid, mode, modtime */ len = sqlite3_column_int(stmt, 1); *st = c_malloc(sizeof(csync_file_stat_t) + len + 1); /* clear the whole structure */ ZERO_STRUCTP(*st); /* The query suceeded so use the phash we pass to the function. */ (*st)->phash = sqlite3_column_int64(stmt, 0); (*st)->pathlen = sqlite3_column_int(stmt, 1); name = (const char*) sqlite3_column_text(stmt, 2); memcpy((*st)->path, (len ? name : ""), len + 1); (*st)->inode = sqlite3_column_int64(stmt,3); (*st)->mode = sqlite3_column_int(stmt, 6); (*st)->modtime = strtoul((char*)sqlite3_column_text(stmt, 7), NULL, 10); if(*st && column_count > 8 ) { (*st)->type = sqlite3_column_int(stmt, 8); } if(column_count > 9 && sqlite3_column_text(stmt, 9)) { (*st)->etag = c_strdup( (char*) sqlite3_column_text(stmt, 9) ); } if(column_count > 10 && sqlite3_column_text(stmt,10)) { csync_vio_set_file_id((*st)->file_id, (char*) sqlite3_column_text(stmt, 10)); } if(column_count > 11 && sqlite3_column_text(stmt,11)) { strncpy((*st)->remotePerm, (char*) sqlite3_column_text(stmt, 11), REMOTE_PERM_BUF_SIZE); } if(column_count > 12 && sqlite3_column_int64(stmt,12)) { (*st)->size = sqlite3_column_int64(stmt, 12); } if(column_count > 13) { (*st)->has_ignored_files = sqlite3_column_int(stmt, 13); } } } else { if( rc != SQLITE_DONE ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "WARN: Query results in %d", rc); } } return rc; }
int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) { int rc; sqlite3_stmt *stmt = NULL; int64_t cnt = 0; char *likepath; int asp; int min_path_len; if( !path ) { return -1; } if( !ctx || ctx->db_is_empty ) { return -1; } SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, BELOW_PATH_QUERY, -1, &stmt, NULL)); ctx->statedb.lastReturnValue = rc; if( rc != SQLITE_OK ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for below path query."); return -1; } if (stmt == NULL) { return -1; } asp = asprintf( &likepath, "%s/%%%%", path); if (asp < 0) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!"); return -1; } min_path_len = strlen(path); sqlite3_bind_int(stmt, 1, min_path_len); sqlite3_bind_text(stmt, 2, likepath, -1, SQLITE_STATIC); cnt = 0; ctx->statedb.lastReturnValue = rc; do { csync_file_stat_t *st = NULL; rc = _csync_file_stat_from_metadata_table( &st, stmt); if( st ) { /* Check for exclusion from the tree. * Note that this is only a safety net in case the ignore list changes * without a full remote discovery being triggered. */ CSYNC_EXCLUDE_TYPE excluded = csync_excluded(ctx, st->path, st->type); if (excluded != CSYNC_NOT_EXCLUDED) { CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", st->path, excluded); if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE || excluded == CSYNC_FILE_SILENTLY_EXCLUDED) { SAFE_FREE(st); continue; } st->instruction = CSYNC_INSTRUCTION_IGNORE; } /* store into result list. */ if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) { SAFE_FREE(st); ctx->status_code = CSYNC_STATUS_TREE_ERROR; break; } cnt++; } } while( rc == SQLITE_ROW ); ctx->statedb.lastReturnValue = rc; if( rc != SQLITE_DONE ) { ctx->status_code = CSYNC_STATUS_TREE_ERROR; } else { CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "%" PRId64 " entries read below path %s from db.", cnt, path); } sqlite3_finalize(stmt); SAFE_FREE(likepath); return 0; }