Exemplo n.º 1
0
/*
 * returns:
 * -EINVAL: invalid arg, cid is not set
 * OSD_ERROR: in case of any error, cid is not set
 * OSD_OK: success, cid is set to proper collection id
 */
int coll_get_cid(void *ohandle, uint64_t pid, uint64_t oid, 
		 uint32_t number, uint64_t *cid)
{
  struct db_context *dbc = ((struct handle*)ohandle)->dbc;
	int ret = 0;
	int bound = 0;

	assert(dbc && dbc->db && dbc->coll && dbc->coll->getcid);

repeat:
	ret = 0;
	ret |= sqlite3_bind_int64(dbc->coll->getcid, 1, pid);
	ret |= sqlite3_bind_int64(dbc->coll->getcid, 2, oid);
	ret |= sqlite3_bind_int64(dbc->coll->getcid, 3, number);
	bound = (ret == SQLITE_OK);
	if (!bound) {
		error_sql(dbc->db, "%s: bind failed", __func__);
		goto out_reset;
	}

	while ((ret = sqlite3_step(dbc->coll->getcid)) == SQLITE_BUSY);
	if (ret == SQLITE_ROW)
		*cid = sqlite3_column_int64(dbc->coll->getcid, 0);

out_reset:
	ret = db_reset_stmt(dbc, dbc->coll->getcid, bound, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;
out:
	return ret;
}
Exemplo n.º 2
0
/*
 * tests whether partition is empty. 
 *
 * returns:
 * -EINVAL: invalid arg
 * OSD_ERROR: in case of other errors, ignore value of *isempty
 * OSD_OK: success, *isempty set to:
 * 	==1: if partition is empty or absent or in case of sqlite error
 * 	==0: if partition is not empty
 */
int obj_isempty_pid(void *ohandle, char *root, uint64_t pid, int *isempty)
{
  struct db_context *dbc = ((struct handle*)ohandle)->dbc;
	int ret = 0;
	int bound = 0;
	*isempty = 0;

	assert(dbc && dbc->db && dbc->obj && dbc->obj->emptypid);

repeat:
	ret = sqlite3_bind_int64(dbc->obj->emptypid, 1, pid);
	bound = (ret == SQLITE_OK);
	if (!bound) {
		error_sql(dbc->db, "%s: bind failed", __func__);
		goto out_reset;
	}

	while ((ret = sqlite3_step(dbc->obj->emptypid)) == SQLITE_BUSY);
	if (ret == SQLITE_ROW)
		*isempty = (0 == sqlite3_column_int(dbc->obj->emptypid, 0));

out_reset:
	ret = db_reset_stmt(dbc, dbc->obj->emptypid, bound, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;
out:
	return ret;
}
Exemplo n.º 3
0
/*
 * return the type of the object
 *
 * returns:
 * -EINVAL: invalid arg, ignore value of obj_type
 * OSD_ERROR: any other error, ignore value of obj_type
 * OSD_OK: success in determining the type, either valid or invalid. 
 * 	obj_types set to the determined type.
 */
int obj_get_type(void *ohandle, uint64_t pid, uint64_t oid, 
		 uint8_t *obj_type)
{
  struct db_context *dbc = ((struct handle*)ohandle)->dbc;
	int ret = 0;
	int bound = 0;
	*obj_type = ILLEGAL_OBJ;

	assert(dbc && dbc->db && dbc->obj && dbc->obj->gettype);

repeat:
	ret = 0;
	ret |= sqlite3_bind_int64(dbc->obj->gettype, 1, pid);
	ret |= sqlite3_bind_int64(dbc->obj->gettype, 2, oid);
	bound = (ret == SQLITE_OK);
	if (!bound) {
		error_sql(dbc->db, "%s: bind failed", __func__);
		goto out_reset;
	}

	while ((ret = sqlite3_step(dbc->obj->gettype)) == SQLITE_BUSY);
	if (ret == SQLITE_ROW) {
		*obj_type = sqlite3_column_int(dbc->obj->gettype, 0);
	} else if (ret == SQLITE_DONE) {
		osd_debug("%s: object (%llu %llu) doesn't exist", __func__, 
			  llu(pid), llu(oid));
	} 

out_reset:
	ret = db_reset_stmt(dbc, dbc->obj->gettype, bound, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;
out:
	return ret;
}
Exemplo n.º 4
0
Arquivo: coll.c Projeto: snsl/osc-osd
/*
 * return the max object pointer for a particular pid,cid
 *
 * returns:
 * -EINVAL: invalid arg, ignore value of isempty
 * OSD_ERROR: in case of other errors, ignore value of isempty
 * OSD_OK: success, isempty is set to:
 * 	==1: if collection is empty or absent 
 * 	==0: if not empty
 */
int coll_max_pointer(struct db_context *dbc, uint64_t pid, uint64_t cid,
		     uint32_t *number)
{
	int ret = 0;
	int bound = 0;
	*number = 0;

	assert(dbc && dbc->db && dbc->coll && dbc->coll->max);

repeat:
	ret = 0;
	ret |= sqlite3_bind_int64(dbc->coll->max, 1, pid);
	ret |= sqlite3_bind_int64(dbc->coll->max, 2, cid);
	bound = (ret == SQLITE_OK);
	if (!bound) {
		error_sql(dbc->db, "%s: bind failed", __func__);
		goto out_reset;
	}

	while ((ret = sqlite3_step(dbc->coll->max)) == SQLITE_BUSY);
	if (ret == SQLITE_ROW)
		*number = (0 == sqlite3_column_int(dbc->coll->max, 0));

out_reset:
	ret = db_reset_stmt(dbc, dbc->coll->max, bound, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;
out:
	return ret;
}
Exemplo n.º 5
0
Arquivo: coll.c Projeto: snsl/osc-osd
/*
 * tests whether collection is empty. 
 *
 * returns:
 * -EINVAL: invalid arg, ignore value of isempty
 * OSD_ERROR: in case of other errors, ignore value of isempty
 * OSD_OK: success, isempty is set to:
 * 	==1: if collection is empty or absent 
 * 	==0: if not empty
 */
int coll_isempty_cid(struct db_context *dbc, uint64_t pid, uint64_t cid,
		     int *isempty)
{
	int ret = 0;
	int bound = 0;
	*isempty = 0;

	assert(dbc && dbc->db && dbc->coll && dbc->coll->emptycid);

repeat:
	ret = 0;
	ret |= sqlite3_bind_int64(dbc->coll->emptycid, 1, pid);
	ret |= sqlite3_bind_int64(dbc->coll->emptycid, 2, cid);
	bound = (ret == SQLITE_OK);
	if (!bound) {
		error_sql(dbc->db, "%s: bind failed", __func__);
		goto out_reset;
	}

	while ((ret = sqlite3_step(dbc->coll->emptycid)) == SQLITE_BUSY);
	if (ret == SQLITE_ROW)
		*isempty = (0 == sqlite3_column_int(dbc->coll->emptycid, 0));

out_reset:
	ret = db_reset_stmt(dbc, dbc->coll->emptycid, bound, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;
out:
	return ret;
}
Exemplo n.º 6
0
/*
 * this function executes id retrieval statement. Only the functions
 * retireiving a list of oids, cids or pids may use this function
 *
 * returns:
 * OSD_ERROR: in case of any error
 * OSD_OK: on success
 * OSD_REPEAT: in case of sqlite_schema error, statements are prepared again,
 * 	hence values need to be bound again.
 */
int db_exec_id_rtrvl_stmt(struct db_context *dbc, sqlite3_stmt *stmt,
                          int ret, const char *func, uint64_t alloc_len,
                          uint8_t *outdata, uint64_t *used_outlen,
                          uint64_t *add_len, uint64_t *cont_id)
{
    uint64_t len = 0;
    int bound = (ret == SQLITE_OK);

    if (!bound) {
        error_sql(dbc->db, "%s: bind failed", func);
        goto out_reset;
    }

    len = 0;
    *add_len = 0;
    *cont_id = 0;
    *used_outlen = 0;
    while (1) {
        ret = sqlite3_step(stmt);
        if (ret == SQLITE_ROW) {
            if ((alloc_len - len) >= 8) {
                set_htonll(outdata,
                           sqlite3_column_int64(stmt, 0));
                outdata += 8;
                len += 8;
            } else if (*cont_id == 0) {
                *cont_id = sqlite3_column_int64(stmt, 0);
            }
            /* handle overflow: osd2r01 Sec 6.14.2 */
            if (*add_len + 8 > *add_len) {
                *add_len += 8;
            } else {
                /* terminate since add_len overflew */
                *add_len = (uint64_t) -1;
                break;

            }
        } else if (ret == SQLITE_BUSY) {
            continue;
        } else {
            break;
        }
    }

out_reset:
    ret = db_reset_stmt(dbc, stmt, bound, func);
    if (ret == OSD_OK)
        *used_outlen = len;
    return ret;
}
Exemplo n.º 7
0
/*
 * return values
 * -EINVAL: invalid args
 * OSD_ERROR: some other sqlite error
 * OSD_OK: success
 * 	pid = next pid if OSD has some pids
 * 	pid = 1 if pid not in db. caller must assign correct pid.
 */
int obj_get_nextpid(void *ohandle, uint64_t *pid)
{
  struct db_context *dbc = ((struct handle*)ohandle)->dbc;
	int ret = 0;

	assert(dbc && dbc->db && dbc->obj && dbc->obj->nextpid);

repeat:
	while ((ret = sqlite3_step(dbc->obj->nextpid)) == SQLITE_BUSY);
	if (ret == SQLITE_ROW)
		*pid = sqlite3_column_int64(dbc->obj->nextpid, 0) + 1;

out_reset:
	ret = db_reset_stmt(dbc, dbc->obj->nextpid, 1, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;
out:
	return ret;
}
Exemplo n.º 8
0
/*
 * exec_dms: executes prior prepared and bound data manipulation statement.
 * Only SQL statements with 'insert' or 'delete' may call this helper
 * function.
 *
 * returns:
 * OSD_ERROR: in case of error
 * OSD_OK: on success
 * OSD_REPEAT: in case of sqlite_schema error, statements are prepared again,
 * 	hence values need to be bound again.
 */
int db_exec_dms(struct db_context *dbc, sqlite3_stmt *stmt, int ret,
                const char *func)
{
    int bound;

    TICK_TRACE(db_exec_dms);
    bound = (ret == SQLITE_OK);
    if (!bound) {
        error_sql(dbc->db, "%s: bind failed", func);
        goto out_reset;
    }

    do {
        TICK_TRACE(sqlite3_step);
        ret = sqlite3_step(stmt);
    } while (ret == SQLITE_BUSY);

out_reset:
    ret = db_reset_stmt(dbc, stmt, bound, func);
    TICK_TRACE(db_exec_dms);
    return ret;
}
Exemplo n.º 9
0
Arquivo: attr.c Projeto: snsl/osc-osd
/*
 * returns:
 * -EINVAL: invalid arg or misaligned buffer
 * -ENOENT: empty result set
 * OSD_ERROR: some other error
 * OSD_OK: success, used_outlen modified
 */
static int exec_attr_rtrvl_stmt(struct db_context *dbc, sqlite3_stmt *stmt,
				int ret, const char *func, uint64_t oid, 
				uint64_t page, int rtrvl_type, uint64_t outlen,
				uint8_t *outdata, uint8_t listfmt,
				uint32_t *used_outlen)
{
	uint32_t len = 0;
	uint8_t found = 0;
	uint8_t bound = (ret == SQLITE_OK);
	uint8_t inval = 0;

	if (!bound) {
		error_sql(dbc->db, "%s: bind failed", func);
		goto out_reset;
	}

	*used_outlen = 0;
	while (1) {
		ret = sqlite3_step(stmt);
		if (ret == SQLITE_ROW) {
			if (rtrvl_type == GATHER_VAL) {
				ret = attr_gather_val(stmt, outdata, outlen);
			} else if (rtrvl_type == GATHER_ATTR) {
				ret = attr_gather_attr(stmt, outdata, outlen, 
						       oid, listfmt);
			} else if (rtrvl_type == GATHER_DIR_PAGE) {
				ret = attr_gather_dir_page(stmt, outlen,
							   outdata, oid, page,
							   listfmt);
			} else {
				ret = -EINVAL;
			}
			if (ret > 0) {
				len += ret;
				outlen -= ret;
				outdata += ret;
				if (!found)
					found = 1;
			} else {
				if (ret == -EINVAL)
					inval = 1;
				break;
			}
		} else if (ret == SQLITE_BUSY) {
			continue;
		} else {
			break;
		}
	}

out_reset:
	ret = db_reset_stmt(dbc, stmt, bound, func);
	if (inval) {
		ret = -EINVAL;
	} else if (ret == OSD_OK) {
		*used_outlen = len;
		if (!found)
			ret = -ENOENT;
	}
	return ret;
}