terom@28: terom@28: #include terom@28: terom@29: #include "dbfs.h" terom@29: #include "../lib/log.h" terom@28: terom@28: mode_t _dbfs_mode (const char *type) { terom@28: if (!strcmp(type, "DIR")) terom@28: return S_IFDIR; terom@28: terom@28: if (!strcmp(type, "REG")) terom@28: return S_IFREG; terom@32: terom@32: if (!strcmp(type, "LNK")) terom@32: return S_IFLNK; terom@28: terom@28: else { terom@28: WARNING("[dbfs] weird mode-type: %s", type); terom@28: return 0; terom@28: } terom@28: } terom@28: terom@48: int _dbfs_check_res (struct evsql_result *res, size_t rows, size_t cols) { terom@28: int err = 0; terom@28: terom@28: // check if it failed terom@48: if (evsql_result_check(res)) terom@28: NERROR(evsql_result_error(res)); terom@28: terom@28: // not found? terom@34: if (evsql_result_rows(res) == 0 && evsql_result_affected(res) == 0) terom@28: SERROR(err = 1); terom@28: terom@28: // duplicate rows? terom@28: if (rows && evsql_result_rows(res) != rows) terom@28: ERROR("wrong number of rows returned"); terom@28: terom@28: // correct number of columns terom@28: if (evsql_result_cols(res) != cols) terom@28: ERROR("wrong number of columns: %zu", evsql_result_cols(res)); terom@28: terom@28: // good terom@28: return 0; terom@28: terom@28: error: terom@28: if (!err) terom@28: err = -1; terom@28: terom@28: return err; terom@28: } terom@28: terom@48: err_t dbfs_check_result (struct evsql_result *res, size_t rows, size_t cols) { terom@41: err_t err; terom@34: terom@36: // number of rows returned/affected terom@36: size_t nrows = evsql_result_rows(res) ? : evsql_result_affected(res); terom@36: terom@36: // did the query fail outright? terom@48: if (evsql_result_check(res)) terom@36: // dump error message terom@36: NXERROR(err = EIO, evsql_result_error(res)); terom@36: terom@36: // SELECT/DELETE/UPDATE WHERE didn't match any rows -> ENOENT terom@36: if (nrows == 0) terom@36: XERROR(err = ENOENT, "no rows returned/affected"); terom@36: terom@36: // duplicate rows where one expected? terom@36: if (rows && nrows != rows) terom@36: XERROR(err = EIO, "wrong number of rows: %zu -> %zu", rows, nrows); terom@36: terom@36: // correct number of columns terom@36: if (evsql_result_cols(res) != cols) terom@36: XERROR(err = EIO, "wrong number of columns: %zu -> %zu", cols, evsql_result_cols(res)); terom@36: terom@36: // good terom@36: return 0; terom@36: terom@36: error: terom@36: return err; terom@36: } terom@34: terom@48: int _dbfs_stat_info (struct stat *st, struct evsql_result *res, size_t row, size_t col_offset) { terom@28: int err = 0; terom@28: terom@28: uint16_t mode; terom@30: uint32_t size = 0; // NULL for non-REG inodes terom@31: uint64_t nlink = 0; // will be NULL for non-GROUP BY queries terom@28: const char *type; terom@28: terom@28: // extract the data terom@31: if ((0 terom@28: || evsql_result_string(res, row, col_offset + 0, &type, 0 ) // inodes.type terom@28: || evsql_result_uint16(res, row, col_offset + 1, &mode, 0 ) // inodes.mode terom@30: || evsql_result_uint32(res, row, col_offset + 2, &size, 1 ) // size terom@31: || evsql_result_uint64(res, row, col_offset + 3, &nlink, 1 ) // count(*) terom@31: ) && (err = EIO)) terom@31: ERROR("invalid db data"); terom@28: terom@28: INFO("\tst_mode=S_IF%s | %ho, st_nlink=%llu, st_size=%llu", type, mode, (long long unsigned int) nlink, (long long unsigned int) size); terom@28: terom@28: // convert and store terom@28: st->st_mode = _dbfs_mode(type) | mode; terom@28: st->st_nlink = nlink; terom@28: st->st_size = size; terom@28: terom@28: // good terom@28: return 0; terom@28: terom@28: error: terom@31: return err; terom@28: } terom@28: terom@28: terom@28: