Exemplo n.º 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;
}
Exemplo n.º 2
0
int SLNSessionCreateSession(SLNSessionRef const session, SLNSessionRef *const out) {
	assert(out);
	if(!session) return DB_EACCES;

	SLNSessionCacheRef const cache = session->cache;
	uint64_t const userID = session->userID;
	SLNMode const mode = session->mode;
	strarg_t const username = session->username;
	DB_env *db = NULL;
	DB_txn *txn = NULL;
	SLNSessionRef alt = NULL;

	byte_t key_raw[SESSION_KEY_LEN];
	int rc = async_random(key_raw, sizeof(key_raw));
	if(rc < 0) goto cleanup;

	byte_t key_enc[SHA256_DIGEST_LENGTH];
	SHA256(key_raw, sizeof(key_raw), key_enc);

	str_t key_str[SESSION_KEY_HEX+1];
	tohex(key_str, key_enc, SESSION_KEY_LEN);
	key_str[SESSION_KEY_HEX] = '\0';

	rc = SLNSessionDBOpen(session, SLN_RDWR, &db); // TODO: Custom permission?
	if(rc < 0) goto cleanup;
	rc = db_txn_begin(db, NULL, DB_RDWR, &txn);
	if(rc < 0) goto cleanup;

	uint64_t const sessionID = db_next_id(SLNSessionByID, txn);
	DB_val key[1], val[1];
	SLNSessionByIDKeyPack(key, txn, sessionID);
	SLNSessionByIDValPack(val, txn, userID, key_str);
	rc = db_put(txn, key, val, DB_NOOVERWRITE_FAST);
	if(rc < 0) goto cleanup;

	rc = db_txn_commit(txn); txn = NULL;
	SLNSessionDBClose(session, &db);
	if(rc < 0) goto cleanup;

	rc = SLNSessionCreateInternal(cache, sessionID, key_raw, key_enc, userID, mode, username, &alt);
	if(rc < 0) goto cleanup;

	*out = alt; alt = NULL;

cleanup:
	db_txn_abort(txn); txn = NULL;
	SLNSessionDBClose(session, &db);
	SLNSessionRelease(&alt);
	return rc;
}
Exemplo n.º 3
0
int SLNSessionAddMetaMap(SLNSessionRef const session, strarg_t const metaURI, strarg_t const targetURI) {
	uint64_t const sessionID = SLNSessionGetID(session);

	DB_env *db = NULL;
	DB_txn *txn = NULL;
	int rc = SLNSessionDBOpen(session, SLN_RDWR, &db);
	if(rc < 0) goto cleanup;
	rc = db_txn_begin(db, NULL, DB_RDWR, &txn);
	if(rc < 0) goto cleanup;

	uint64_t nextID = SLNNextMetaMapID(txn, sessionID);
	if(!nextID) rc = DB_EIO;
	if(rc < 0) goto cleanup;

	DB_val mainkey[1], mainval[1];
	SLNSessionIDAndMetaMapIDToMetaURIAndTargetURIKeyPack(mainkey, txn, sessionID, nextID);
	SLNSessionIDAndMetaMapIDToMetaURIAndTargetURIValPack(mainval, txn, metaURI, targetURI);
	rc = db_put(txn, mainkey, mainval, DB_NOOVERWRITE_FAST);
	if(rc < 0) goto cleanup;

	DB_val fwdkey[1], fwdval[1];
	SLNMetaURIAndSessionIDToMetaMapIDKeyPack(fwdkey, txn, metaURI, sessionID);
	SLNMetaURIAndSessionIDToMetaMapIDValPack(fwdval, txn, nextID);
	rc = db_put(txn, fwdkey, fwdval, DB_NOOVERWRITE_FAST);
	if(rc < 0) goto cleanup;

	DB_val revkey[1], revval[1];
	SLNTargetURISessionIDAndMetaMapIDKeyPack(revkey, txn, targetURI, sessionID, nextID);
	db_nullval(revval);
	rc = db_put(txn, revkey, revval, DB_NOOVERWRITE_FAST);
	if(rc < 0) goto cleanup;

	rc = db_txn_commit(txn); txn = NULL;
cleanup:
	db_txn_abort(txn); txn = NULL;
	SLNSessionDBClose(session, &db);
	return rc;
}
Exemplo n.º 4
0
static int db_work(EFSSyncRef const sync, struct queues *const cur) {
	EFSRepoRef const repo = EFSSessionGetRepo(sync->session);
	DB_env *db;
	EFSRepoDBOpen(repo, &db);

	DB_txn *txn;
	rc = db_txn_begin(db, NULL, DB_RDWR, &txn);
	if(DB_SUCCESS != rc) {
		EFSRepoDBClose(repo, &db);
		return rc;
	}

	// TODO: Process queues in cur.

	// TODO: Submissions should go to an EFSWriter that does its own batching
	// But two layers of batching is a bad idea...
	// Instead of using EFSWriter, do custom inter-sync batching without additional latency


	rc = db_txn_commit(txn); txn = NULL;
	EFSRepoDBClose(repo, &db);
	if(DB_SUCCESS != rc) return rc;
	return DB_SUCCESS;
}