Ejemplo n.º 1
0
/**
 * @brief	Fetch a user's config collection from the database.
 * @param	collection	a pointer to the specified user config collection object (with usernum field set by the caller) to be populated from the database.
 * @return	true on success or false on failure.
 */
bool_t user_config_fetch(user_config_t *collection) {

	row_t *row;
	table_t *result;
	MYSQL_BIND parameters[1];
	user_config_entry_t *record;
	multi_t key = { .type = M_TYPE_STRINGER, .val.st = NULL };

	mm_wipe(parameters, sizeof(parameters));

	if (!collection || !collection->usernum) {
		log_pedantic("Invalid data passed to user config fetch.");
		return false;
	}

	// User Number
	parameters[0].buffer_type = MYSQL_TYPE_LONGLONG;
	parameters[0].buffer_length = sizeof(uint64_t);
	parameters[0].buffer = &(collection->usernum);
	parameters[0].is_unsigned = true;

	if (!(result = stmt_get_result(stmts.select_user_config, parameters))) {
		log_pedantic("Unable to fetch the user config entries.");
		return false;
	}

	// Loop through each row and create a user config entry.
	while ((row = res_row_next(result))) {

		if (!(record = user_config_entry_alloc(PLACER(res_field_block(row, 0), res_field_length(row, 0)),
			PLACER(res_field_block(row, 1), res_field_length(row, 1)), res_field_uint64(row, 2))) ||
			!(key.val.st = record->key) || !inx_insert(collection->entries, key, record)) {
			log_info("The index refused to accept a user config entry. { user  = %lu }", res_field_uint64(row, 0));

			if (record) {
				user_config_entry_free(record);
			}

			res_table_free(result);
			return false;
		}

	}

	res_table_free(result);

	return true;
}
Ejemplo n.º 2
0
/**
 * @brief	Populate a contact entry with its details from the database.
 * @param	contact		a pointer to the contact entry object that will be updated.
 * @return	-1 on failure or 1 on success.
 */
int_t contact_details_fetch(contact_t *contact) {

	row_t *row;
	table_t *result;
	MYSQL_BIND parameters[1];
	contact_detail_t *record;
	multi_t key = { .type = M_TYPE_STRINGER, .val.st = NULL };

	mm_wipe(parameters, sizeof(parameters));

	if (!contact || !contact->contactnum) {
		log_pedantic("Invalid data passed to contact details fetch.");
		return -1;
	}

	// Contact Number
	parameters[0].buffer_type = MYSQL_TYPE_LONGLONG;
	parameters[0].buffer_length = sizeof(uint64_t);
	parameters[0].buffer = &(contact->contactnum);
	parameters[0].is_unsigned = true;

	if (!(result = stmt_get_result(stmts.select_contact_details, parameters))) {
		log_pedantic("Unable to fetch the contact details.");
		return -1;
	}

	// Loop through each of the row and create a contact record. When were finished we'll fetch the contact details for each record found.
	while ((row = res_row_next(result))) {

		if (!(record = contact_detail_alloc(PLACER(res_field_block(row, 0), res_field_length(row, 0)),
			PLACER(res_field_block(row, 1), res_field_length(row, 1)), res_field_uint64(row, 2))) ||
			!(key.val.st = record->key) || !inx_insert(contact->details, key, record)) {
			log_info("The index refused to accept a contact record. { contact = %lu }", res_field_uint64(row, 0));

			if (record) {
				contact_detail_free(record);
			}

			res_table_free(result);
			return -1;
		}

	}

	res_table_free(result);
	return 1;
}

/**
 * @brief	Retrieve all of a user's contact entries in a specified contacts folder from the database.
 * @param	usernum		the numerical id of the user whose contacts will be retrieved.
 * @param	folder		a pointer to the contact folder which will have its contents listed.
 * @return	-1 on failure or 1 on success.
 */
int_t contacts_fetch(uint64_t usernum, contact_folder_t *folder) {

	row_t *row;
	table_t *result;
	contact_t *record;
	inx_cursor_t *cursor;
	MYSQL_BIND parameters[2];
	multi_t key = { .type = M_TYPE_UINT64, .val.u64 = 0 };

	mm_wipe(parameters, sizeof(parameters));

	if (!usernum || !folder || !folder->foldernum) {
		log_pedantic("Invalid data passed for contact fetch.");
		return -1;
	}

	// Usernum
	parameters[0].buffer_type = MYSQL_TYPE_LONGLONG;
	parameters[0].buffer_length = sizeof(uint64_t);
	parameters[0].buffer = &(usernum);
	parameters[0].is_unsigned = true;

	// Folder Number
	parameters[1].buffer_type = MYSQL_TYPE_LONGLONG;
	parameters[1].buffer_length = sizeof(uint64_t);
	parameters[1].buffer = &(folder->foldernum);
	parameters[1].is_unsigned = true;

	if (!(result = stmt_get_result(stmts.select_contacts, parameters))) {
		log_pedantic("Unable to fetch the folder contacts.");
		return -1;
	}

	// Loop through each of the row and create a contact record. When were finished we'll fetch the contact details for each record found.
	while ((row = res_row_next(result))) {
		if (!(record = contact_alloc(res_field_uint64(row, 0), PLACER(res_field_block(row, 1), res_field_length(row, 1)))) ||
			!(key.val.u64 = record->contactnum) || !inx_insert(folder->records, key, record)) {
			log_info("The index refused to accept a contact record. { contact = %lu }", res_field_uint64(row, 0));
			if (record) contact_free(record);
			res_table_free(result);
			return -1;
		}
	}

	res_table_free(result);

	/// LOW: Should we bother with error checking?
	if ((cursor = inx_cursor_alloc(folder->records))) {
		while ((record = inx_cursor_value_next(cursor))) {
			contact_details_fetch(record);
		}

		inx_cursor_free(cursor);
	}

	return 1;
}
Ejemplo n.º 3
0
/**
 * @brief	Load all magma configuration options present in the database.
 * @note	Each key/value pair extracted from the database is submitted to the following logic:
 *	 			If a config option was loaded from the database, the key must allow it to be configurable via the database.
 *	 			Check to see that any key that has previously been set is allowed to be overwritten.
 * 				If the key is required, it may not contain an empty value.
 * 			Finally, this function sets the appropriate magma key corresponding to the config key.
 * 			All leftover keys not matched to global magma keys will be configured via servers, relay, and cache server options.
 * @return	true if all database config options were parsed and evaluated successfully, or false on failure.
 */
bool_t config_load_database_settings(void) {

	row_t *row;
	uint64_t rows;
	magma_keys_t *key;
	table_t *database_pairs;
	stringer_t *value, *name;

	if (!(magma.host.number = config_fetch_host_number()) || !(database_pairs = config_fetch_settings())) {
		return false;
	}

	// Loop through each of the row returned.
	rows = res_row_count(database_pairs);
	for (uint64_t i = 0; i < rows && (row = res_row_get(database_pairs, i)); i++) {

			name = PLACER(res_field_block(row, 0), res_field_length(row, 0));
			value = PLACER(res_field_block(row, 1), res_field_length(row, 1));

			if ((key = config_key_lookup(name))) {
				// Make sure the setting can be provided via the database.
				if (!key->database) {
					log_critical("%s cannot be changed using the database.", key->name);
					res_table_free(database_pairs);
					return false;
				}

				// Make sure the setting can be provided via the database.
				else if (key->set && !key->overwrite) {
					log_critical("%s has already been set and cannot be overwritten.", key->name);
					res_table_free(database_pairs);
					return false;
				}

				// Make sure the required magma_keys are not set to NULL.
				else if (key->required && st_empty(value)) {
					log_critical("%s requires a legal value.", key->name);
					res_table_free(database_pairs);
					return false;
				}

				// Attempt to set the value.
				else if (!config_value_set(key, value)) {
					res_table_free(database_pairs);
					return false;
				}

				// Record that we've set this parameter.
				key->set = true;
			}

			// If we haven't had a match yet, check if its a server param.
			else if (!st_cmp_ci_starts(name, CONSTANT("magma.servers"))) {
				servers_config(name, value);
			}

			// If we haven't had a match yet, check if its a relay instance.
			else if (!st_cmp_ci_starts(name, CONSTANT("magma.relay"))) {
				relay_config(name, value);
			}

			else if (!st_cmp_ci_starts(name, CONSTANT("magma.iface.cache.host"))) {
				cache_config(name, value);
			}

			// Otherwise if we still haven't matched a value, report an error.
			else {
				log_critical("%.*s is not a valid setting.", st_length_int(name), st_char_get(name));
				res_table_free(database_pairs);
				return false;
			}

	}

	res_table_free(database_pairs);
	return true;
}