Exemplo n.º 1
0
/*
 * returns:
 * -EINVAL: invalid arg
 * OSD_ERROR: some other error
 * OSD_OK: success
 */
int obj_delete_pid(void *ohandle, uint64_t pid)
{
  struct db_context *dbc = ((struct handle*)ohandle)->dbc;
	int ret = 0;

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

repeat:
	ret = sqlite3_bind_int64(dbc->obj->delpid, 1, pid);
	ret = db_exec_dms(dbc, dbc->obj->delpid, ret, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;

	return ret;
}
Exemplo n.º 2
0
Arquivo: attr.c Projeto: snsl/osc-osd
/*
 * returns:
 * -EINVAL: invalid arg
 * OSD_ERROR: some other error
 * OSD_OK: success
 */
int attr_delete_all(struct db_context *dbc, uint64_t pid, uint64_t oid)
{
	int ret = 0;

	assert(dbc && dbc->db && dbc->attr && dbc->attr->delall);

repeat:
	ret = 0;
	ret |= sqlite3_bind_int64(dbc->attr->delall, 1, pid);
	ret |= sqlite3_bind_int64(dbc->attr->delall, 2, oid);
	ret = db_exec_dms(dbc, dbc->attr->delall, ret, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;

	return ret;
}
Exemplo n.º 3
0
Arquivo: coll.c Projeto: snsl/osc-osd
/* 
 * returns:
 * -EINVAL: invalid arg
 * OSD_ERROR: some other error
 * OSD_OK: success
 */
int coll_delete_oid(struct db_context *dbc, uint64_t pid, uint64_t oid)
{
	int ret = 0;

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

repeat:
	ret = 0;
	ret |= sqlite3_bind_int64(dbc->coll->deloid, 1, pid);
	ret |= sqlite3_bind_int64(dbc->coll->deloid, 2, oid);
	ret = db_exec_dms(dbc, dbc->coll->deloid, ret, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;

	return ret;
}
Exemplo n.º 4
0
Arquivo: coll.c Projeto: snsl/osc-osd
/* 
 * @pid: partition id 
 * @dest_cid: destination collection id (typically user tracking collection)
 * @source_cid: source collection id (whose objects will be tracked)
 *
 * returns:
 * -EINVAL: invalid arg
 * OSD_ERROR: some other error
 * OSD_OK: success
 */
int coll_copyoids(struct db_context *dbc, uint64_t pid, uint64_t dest_cid,
		  uint64_t source_cid)
{
	int ret = 0;

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

repeat:
	ret = 0;
	ret |= sqlite3_bind_int64(dbc->coll->copyoids, 1, pid);
	ret |= sqlite3_bind_int64(dbc->coll->copyoids, 2, dest_cid);
	ret |= sqlite3_bind_int64(dbc->coll->copyoids, 3, pid);
	ret |= sqlite3_bind_int64(dbc->coll->copyoids, 4, source_cid);
	ret = db_exec_dms(dbc, dbc->coll->copyoids, ret, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;

	return ret;
}
Exemplo n.º 5
0
Arquivo: coll.c Projeto: snsl/osc-osd
/* 
 * @pid: partition id 
 * @cid: collection id
 * @oid: userobject id
 * @number: attribute number of cid in CAP of oid
 *
 * returns:
 * -EINVAL: invalid arg
 * OSD_ERROR: some other error
 * OSD_OK: success
 */
int coll_insert(struct db_context *dbc, uint64_t pid, uint64_t cid,
		uint64_t oid, uint32_t number)
{
	int ret = 0;

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

repeat:
	ret = 0;
	ret |= sqlite3_bind_int64(dbc->coll->insert, 1, pid);
	ret |= sqlite3_bind_int64(dbc->coll->insert, 2, cid);
	ret |= sqlite3_bind_int64(dbc->coll->insert, 3, oid);
	ret |= sqlite3_bind_int(dbc->coll->insert, 4, number);
	ret = db_exec_dms(dbc, dbc->coll->insert, ret, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;

	return ret;
}
Exemplo n.º 6
0
Arquivo: attr.c Projeto: snsl/osc-osd
/*
 * returns:
 * -EINVAL: invalid arg
 * OSD_ERROR: some other error
 * OSD_OK: success
 */
int attr_delete_attr(struct db_context *dbc, uint64_t pid, uint64_t oid, 
		     uint32_t page, uint32_t number)
{
	int ret = 0;
	sqlite3_stmt *stmt = NULL;

	assert(dbc && dbc->db && dbc->attr && dbc->attr->delattr);

repeat:
	ret = 0;
	stmt = dbc->attr->delattr;
	ret |= sqlite3_bind_int64(stmt, 1, pid);
	ret |= sqlite3_bind_int64(stmt, 2, oid);
	ret |= sqlite3_bind_int(stmt, 3, page);
	ret |= sqlite3_bind_int(stmt, 4, number);
	ret = db_exec_dms(dbc, stmt, ret, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;

	return ret;
}
Exemplo n.º 7
0
/*
 * returns:
 * -EINVAL: invalid arg
 * OSD_ERROR: some other error
 * OSD_OK: success
 */
int obj_insert(void *ohandle, uint64_t pid, uint64_t oid, 
	       uint32_t type)
{
  struct db_context *dbc = ((struct handle*)ohandle)->dbc;
	int ret = 0;

	TICK_TRACE(obj_insert);
	assert(dbc && dbc->db && dbc->obj && dbc->obj->insert);

repeat:
	ret = 0;
	ret |= sqlite3_bind_int64(dbc->obj->insert, 1, pid);
	ret |= sqlite3_bind_int64(dbc->obj->insert, 2, oid);
	ret |= sqlite3_bind_int(dbc->obj->insert, 3, type);
	ret = db_exec_dms(dbc, dbc->obj->insert, ret, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;

	TICK_TRACE(obj_insert);
	return ret;
}
Exemplo n.º 8
0
Arquivo: attr.c Projeto: snsl/osc-osd
/*
 * Note: Current SQLITE INSERT syntax does not support bulk inserts in a
 * single INSERT SQL statement. Therefore this function needs to be called
 * for each table insert.
 *
 * returns:
 * -EINVAL: invalid arg
 * OSD_ERROR: some other error
 * OSD_OK: success
 */
int attr_set_attr(struct db_context *dbc, uint64_t pid, uint64_t oid, 
		  uint32_t page, uint32_t number, const void *val, 
		  uint16_t len)
{
	int ret = 0;
	sqlite3_stmt *stmt = NULL;

	assert(dbc && dbc->db && dbc->attr && dbc->attr->setattr);

repeat:
	ret = 0;
	stmt = dbc->attr->setattr;
	ret |= sqlite3_bind_int64(stmt, 1, pid);
	ret |= sqlite3_bind_int64(stmt, 2, oid);
	ret |= sqlite3_bind_int(stmt, 3, page);
	ret |= sqlite3_bind_int(stmt, 4, number);
	ret |= sqlite3_bind_blob(stmt, 5, val, len, SQLITE_TRANSIENT);
	ret = db_exec_dms(dbc, stmt, ret, __func__);
	if (ret == OSD_REPEAT)
		goto repeat;

	return ret;
}
Exemplo n.º 9
0
Arquivo: mtq.c Projeto: snsl/osc-osd
/*
 * return values:
 * -EINVAL: invalid argument
 * -EIO: prepare or some other sqlite function failed
 * OSD_ERROR: some other error
 * OSD_OK: success
 */
int mtq_run_query(struct db_context *dbc, uint64_t pid, uint64_t cid, 
		  struct query_criteria *qc, void *outdata, 
		  uint32_t alloc_len, uint64_t *used_outlen,
		  uint64_t matches_cid)
{
	int ret = 0;
	int pos = 0;
	char *cp = NULL;
	char *SQL = NULL;
	uint8_t *p = NULL;
	uint32_t i = 0;
	uint32_t sqlen = 0;
	uint32_t number;
	uint32_t factor = 2; /* this query fills space quickly */
	uint64_t len = 0;
	const char *op = NULL;
	sqlite3_stmt *stmt = NULL;
	char select_stmt[MAXSQLEN];
	const char *coll = coll_getname(dbc);
	const char *attr = attr_getname(dbc);

	assert(dbc && dbc->db && qc && outdata && used_outlen && coll 
	       && attr);

	if (qc->query_type == 0) {
		op = " UNION ";
	} else if (qc->query_type == 1) {
		op = " INTERSECT ";
	} else {
		ret = -EINVAL;
		goto out;
	}

	SQL = Malloc(MAXSQLEN*factor);
	if (SQL == NULL) {
		ret = -ENOMEM;
		goto out;
	}
	cp = SQL;
	sqlen = 0;

	/*
	 * XXX:SD the spec does not mention whether min or max values have to
	 * in tested with '<' or '<='. We assume the tests are inclusive of
	 * boundaries, i.e. use '<=' for comparison.
	 */

	/* build the SQL statment */
	if (matches_cid != 0) {
		ret = coll_max_pointer(dbc, pid, cid, &number);
		if (ret != SQLITE_OK) {
			goto out;
		}
		sprintf(select_stmt, "SELECT coll.pid, %llu, attr.oid, %d "
				     "FROM %s AS coll, %s AS attr WHERE "
				     "coll.pid=coll.pid AND coll.oid=attr.oid "
				     "AND coll.pid = %llu AND coll.cid = %llu ",
			llu(matches_cid), number, coll, attr, llu(pid),
			llu(cid));
	} else {
		sprintf(select_stmt, "SELECT attr.oid FROM %s AS coll, "
				     "%s AS attr WHERE coll.pid = coll.pid AND "
				     "coll.oid = attr.oid AND coll.pid = %llu "
				     "AND coll.cid = %llu ",
			coll, attr, llu(pid), llu(cid));
	}
	strncpy(cp, select_stmt, MAXSQLEN*factor);
	sqlen += strlen(cp);
	cp += sqlen;
	for (i = 0; i < qc->qc_cnt; i++) {
		sprintf(cp, " AND attr.page = %u AND attr.number = %u ",
			qc->page[i], qc->number[i]);
		if (qc->min_len[i] > 0)
			cp = strcat(cp, " AND ? <= attr.value ");
		if (qc->max_len[i] > 0)
			cp = strcat(cp, " AND attr.value <= ? ");

		if ((i+1) < qc->qc_cnt) {
			cp = strcat(cp, op);
			cp = strcat(cp, select_stmt);
		}
		sqlen += strlen(cp);

		if (sqlen >= (MAXSQLEN*factor - 400)) {
			factor *= 2;
			SQL = realloc(SQL, MAXSQLEN*factor);
			if (!SQL) {
				ret = -ENOMEM;
				goto out;
			}
		}
		cp = SQL + sqlen;
	}
	cp = strcat(cp, " GROUP BY attr.oid ORDER BY 1;");

	if (matches_cid != 0) {
		char *SQL2 = Malloc(strlen(SQL) + 100);
		if (SQL2 == NULL) {
			ret = -ENOMEM;
			goto out;
		}
		sprintf(SQL2, "INSERT INTO %s %s", coll, SQL);
		free(SQL);
		SQL = SQL2;
	}

	ret = sqlite3_prepare(dbc->db, SQL, strlen(SQL)+1, &stmt, NULL);
	if (ret != SQLITE_OK) {
		error_sql(dbc->db, "%s: sqlite3_prepare", __func__);
		ret = -EIO;
		goto out;
	}

 repeat:
	/* bind the values */
	pos = 1;
	for (i = 0; i < qc->qc_cnt; i++) {
		if (qc->min_len[i] > 0) {
			ret = sqlite3_bind_blob(stmt, pos, qc->min_val[i],
						qc->min_len[i],
						SQLITE_TRANSIENT);
			if (ret != SQLITE_OK) {
				ret = -EIO;
				error_sql(dbc->db, "%s: bind min_val @ %d",
					  __func__, pos);
				goto out_finalize;
			}
			pos++;
		}
		if (qc->max_len[i] > 0) {
			ret = sqlite3_bind_blob(stmt, pos, qc->max_val[i],
						qc->max_len[i],
						SQLITE_TRANSIENT);
			if (ret != SQLITE_OK) {
				ret = -EIO;
				error_sql(dbc->db, "%s: bind max_val @ %d",
					  __func__, pos);
				goto out_finalize;
			}
			pos++;
		}
	}

	if (matches_cid != 0) {
		ret = db_exec_dms(dbc, stmt, ret, __func__);
		if (ret == OSD_REPEAT)
			goto repeat;
		goto out_finalize;
	}

	/* execute the query */
	p = outdata;
	p += ML_ODL_OFF; 
	len = ML_ODL_OFF - 8; /* subtract len of addition_len */
	*used_outlen = ML_ODL_OFF;
	while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		if ((alloc_len - len) > 8) {
			/* 
			 * TODO: query is a multi-object command, so delete
			 * the objects from the collection, once they are
			 * selected
			 */
			set_htonll(p, sqlite3_column_int64(stmt, 0));
			*used_outlen += 8;
		}
		p += 8; 
		/* handle overflow: osd2r01 Sec 6.18.3 */
		if (len != (uint64_t) -1 && (len + 8) > len) {
			len += 8;
		} else {
			len = (uint64_t) -1;
		}
	}
	if (ret != SQLITE_DONE) {
		error_sql(dbc->db, "%s: sqlite3_step", __func__);
		ret = -EIO;
		goto out_finalize;
	}
	set_htonll(outdata, len);
	ret = OSD_OK;

out_finalize:
	if (sqlite3_finalize(stmt) != SQLITE_OK)
		error_sql(dbc->db, "%s: finalize", __func__);

out:
	free(SQL);
	return ret;
}