Exemple #1
0
int SLNSubmissionStoreBatch(SLNSubmissionRef const *const list, size_t const count) {
	if(!count) return 0;
	// Session permissions were already checked when the sub was created.

	SLNRepoRef const repo = SLNSessionGetRepo(list[0]->session);
	DB_env *db = NULL;
	SLNRepoDBOpen(repo, &db);
	DB_txn *txn = NULL;
	int rc = db_txn_begin(db, NULL, DB_RDWR, &txn);
	if(rc < 0) {
		SLNRepoDBClose(repo, &db);
		return rc;
	}
	uint64_t sortID = 0;
	rc = DB_NOTFOUND;
	for(size_t i = 0; i < count; i++) {
		if(!list[i]) continue;
		assert(repo == SLNSessionGetRepo(list[i]->session));
		rc = SLNSubmissionStore(list[i], txn);
		if(rc < 0) break;
		uint64_t const metaFileID = list[i]->metaFileID;
		if(metaFileID > sortID) sortID = metaFileID;
	}
	if(rc >= 0) {
		rc = db_txn_commit(txn); txn = NULL;
	} else {
		db_txn_abort(txn); txn = NULL;
	}
	SLNRepoDBClose(repo, &db);
	if(rc >= 0) SLNRepoSubmissionEmit(repo, sortID);
	return rc;
}
Exemple #2
0
int SLNSessionGetFileInfo(SLNSessionRef const session, strarg_t const URI, SLNFileInfo *const info) {
	if(!SLNSessionHasPermission(session, SLN_RDONLY)) return DB_EACCES;
	if(!URI) return DB_EINVAL;

	SLNRepoRef const repo = SLNSessionGetRepo(session);
	DB_env *db = NULL;
	SLNRepoDBOpen(repo, &db);
	DB_txn *txn = NULL;
	int rc = db_txn_begin(db, NULL, DB_RDONLY, &txn);
	if(rc < 0) {
		SLNRepoDBClose(repo, &db);
		return rc;
	}

	DB_cursor *cursor;
	rc = db_txn_cursor(txn, &cursor);
	assert(!rc);

	DB_range fileIDs[1];
	SLNURIAndFileIDRange1(fileIDs, txn, URI);
	DB_val URIAndFileID_key[1];
	rc = db_cursor_firstr(cursor, fileIDs, URIAndFileID_key, NULL, +1);
	DB_val file_val[1];
	if(rc >= 0) {
		strarg_t URI2;
		uint64_t fileID;
		SLNURIAndFileIDKeyUnpack(URIAndFileID_key, txn, &URI2, &fileID);
		assert(0 == strcmp(URI, URI2));
		if(info) {
			DB_val fileID_key[1];
			SLNFileByIDKeyPack(fileID_key, txn, fileID);
			rc = db_get(txn, fileID_key, file_val);
		}
	}
	if(rc < 0) {
		db_txn_abort(txn); txn = NULL;
		SLNRepoDBClose(repo, &db);
		return rc;
	}

	if(info) {
		strarg_t const internalHash = db_read_string(file_val, txn);
		strarg_t const type = db_read_string(file_val, txn);
		uint64_t const size = db_read_uint64(file_val);
		info->hash = strdup(internalHash);
		info->path = SLNRepoCopyInternalPath(repo, internalHash);
		info->type = strdup(type);
		info->size = size;
		if(!info->hash || !info->path || !info->type) {
			SLNFileInfoCleanup(info);
			db_txn_abort(txn); txn = NULL;
			SLNRepoDBClose(repo, &db);
			return DB_ENOMEM;
		}
	}

	db_txn_abort(txn); txn = NULL;
	SLNRepoDBClose(repo, &db);
	return 0;
}
Exemple #3
0
int SLNSessionGetValueForField(SLNSessionRef const session, str_t value[], size_t const max, strarg_t const fileURI, strarg_t const field) {
	if(!SLNSessionHasPermission(session, SLN_RDONLY)) return DB_EACCES;
	if(!field) return DB_EINVAL;

	if(max) value[0] = '\0';
	int rc = 0;
	DB_cursor *metafiles = NULL;
	DB_cursor *values = NULL;

	SLNRepoRef const repo = SLNSessionGetRepo(session);
	DB_env *db = NULL;
	SLNRepoDBOpen(repo, &db);
	DB_txn *txn = NULL;
	rc = db_txn_begin(db, NULL, DB_RDONLY, &txn);
	if(rc < 0) goto done;

	rc = db_cursor_open(txn, &metafiles);
	if(rc < 0) goto done;
	rc = db_cursor_open(txn, &values);
	if(rc < 0) goto done;

	DB_range metaFileIDs[1];
	SLNTargetURIAndMetaFileIDRange1(metaFileIDs, txn, fileURI);
	DB_val metaFileID_key[1];
	rc = db_cursor_firstr(metafiles, metaFileIDs, metaFileID_key, NULL, +1);
	if(rc < 0 && DB_NOTFOUND != rc) goto done;
	for(; rc >= 0; rc = db_cursor_nextr(metafiles, metaFileIDs, metaFileID_key, NULL, +1)) {
		strarg_t u;
		uint64_t metaFileID;
		SLNTargetURIAndMetaFileIDKeyUnpack(metaFileID_key, txn, &u, &metaFileID);
		assert(0 == strcmp(fileURI, u));
		DB_range vrange[1];
		SLNMetaFileIDFieldAndValueRange2(vrange, txn, metaFileID, field);
		DB_val value_val[1];
		rc = db_cursor_firstr(values, vrange, value_val, NULL, +1);
		if(rc < 0 && DB_NOTFOUND != rc) goto done;
		for(; rc >= 0; rc = db_cursor_nextr(values, vrange, value_val, NULL, +1)) {
			uint64_t m;
			strarg_t f, v;
			SLNMetaFileIDFieldAndValueKeyUnpack(value_val, txn, &m, &f, &v);
			assert(metaFileID == m);
			assert(0 == strcmp(field, f));
			if(!v) continue;
			if(0 == strcmp("", v)) continue;
			size_t const len = strlen(v);
			memcpy(value, v, MIN(len, max-1));
			value[MIN(len, max-1)] = '\0';
			goto done;
		}
	}

done:
	db_cursor_close(values); values = NULL;
	db_cursor_close(metafiles); metafiles = NULL;

	db_txn_abort(txn); txn = NULL;
	SLNRepoDBClose(repo, &db);
	return rc;
}
Exemple #4
0
ssize_t SLNFilterCopyURIs(SLNFilterRef const filter, SLNSessionRef const session, SLNFilterPosition *const pos, int const dir, bool const meta, str_t *URIs[], size_t const max) {
	assert(URIs);
	if(!SLNSessionHasPermission(session, SLN_RDONLY)) return DB_EACCES;
	if(0 == pos->dir) return DB_EINVAL;
	if(0 == dir) return DB_EINVAL;
	if(0 == max) return 0;

	DB_env *db = NULL;
	DB_txn *txn = NULL;
	ssize_t rc = 0;

	SLNRepoRef const repo = SLNSessionGetRepo(session);
	SLNRepoDBOpen(repo, &db);
	rc = db_txn_begin(db, NULL, DB_RDONLY, &txn);
	if(rc < 0) goto cleanup;

	rc = SLNFilterPrepare(filter, txn);
	if(rc < 0) goto cleanup;
	rc = SLNFilterSeekToPosition(filter, pos, txn);
	if(rc < 0) goto cleanup;

	int const stepdir = pos->dir * dir;
	size_t i = 0;
	for(; i < max; i++) {
		size_t const x = stepdir > 0 ? i : max-1-i;
		rc = SLNFilterGetPosition(filter, pos, txn);
		if(DB_NOTFOUND == rc) {
			rc = 0;
			break;
		}
		rc = SLNFilterCopyURI(filter, pos->fileID, meta, txn, &URIs[x]);
		if(rc < 0) goto cleanup;
		assert(URIs[x]);
		SLNFilterStep(filter, pos->dir);
	}

	// The results should always be in the first `i` slots, even when
	// filling them in reverse order.
	if(stepdir < 0) {
		memmove(URIs+0, URIs+(max-i), sizeof(*URIs) * i);
	}

	assert(rc >= 0);
	rc = i;

cleanup:
	db_txn_abort(txn); txn = NULL;
	SLNRepoDBClose(repo, &db);

	return rc;
}