bool TRI_RegisterFunctionAql (TRI_associative_pointer_t* functions, const char* const externalName, const char* const internalName, const bool isDeterministic, const bool isGroup, const char* const argPattern, void (*optimise)(const TRI_aql_node_t* const, TRI_aql_context_t* const, TRI_aql_field_access_t*)) { TRI_aql_function_t* function; function = (TRI_aql_function_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_aql_function_t), false); if (function == NULL) { return false; } function->_externalName = TRI_UpperAsciiStringZ(TRI_UNKNOWN_MEM_ZONE, externalName); if (function->_externalName == NULL) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, function); return false; } // normalize name by upper-casing it function->_internalName = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, internalName); if (function->_internalName == NULL) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, function->_externalName); TRI_Free(TRI_UNKNOWN_MEM_ZONE, function); return false; } function->_argPattern = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, argPattern); if (function->_argPattern == NULL) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, function->_internalName); TRI_Free(TRI_UNKNOWN_MEM_ZONE, function->_externalName); TRI_Free(TRI_UNKNOWN_MEM_ZONE, function); return false; } if (TRI_InsertKeyAssociativePointer(functions, function->_externalName, function, false)) { // function already registered TRI_Free(TRI_UNKNOWN_MEM_ZONE, function->_externalName); TRI_Free(TRI_UNKNOWN_MEM_ZONE, function->_internalName); TRI_Free(TRI_UNKNOWN_MEM_ZONE, function); return false; } function->_isDeterministic = isDeterministic; function->_isGroup = isGroup; function->optimise = optimise; // set minArgs and maxArgs SetArgumentCount(function); return true; }
TRI_index_t* TRI_CreateGeo2Index (TRI_document_collection_t* document, TRI_idx_iid_t iid, char const* latitudeName, TRI_shape_pid_t latitude, char const* longitudeName, TRI_shape_pid_t longitude, bool unique, bool ignoreNull) { char* lat; char* lon; TRI_geo_index_t* geo = static_cast<TRI_geo_index_t*>(TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(TRI_geo_index_t), false)); TRI_index_t* idx = &geo->base; TRI_InitVectorString(&idx->_fields, TRI_CORE_MEM_ZONE); TRI_InitIndex(idx, iid, TRI_IDX_TYPE_GEO2_INDEX, document, unique); idx->_ignoreNull = ignoreNull; idx->memory = MemoryGeoIndex; idx->json = JsonGeo2Index; idx->insert = InsertGeoIndex; idx->remove = RemoveGeoIndex; lat = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, latitudeName); lon = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, longitudeName); TRI_PushBackVectorString(&idx->_fields, lat); TRI_PushBackVectorString(&idx->_fields, lon); geo->_geoIndex = GeoIndex_new(); // oops, out of memory? if (geo->_geoIndex == NULL) { TRI_DestroyVectorString(&idx->_fields); TRI_Free(TRI_CORE_MEM_ZONE, geo); return NULL; } geo->_variant = INDEX_GEO_INDIVIDUAL_LAT_LON; geo->_location = 0; geo->_latitude = latitude; geo->_longitude = longitude; GeoIndex_assignMethod(&(idx->indexQuery), TRI_INDEX_METHOD_ASSIGNMENT_QUERY); GeoIndex_assignMethod(&(idx->indexQueryFree), TRI_INDEX_METHOD_ASSIGNMENT_FREE); GeoIndex_assignMethod(&(idx->indexQueryResult), TRI_INDEX_METHOD_ASSIGNMENT_RESULT); return idx; }
char* TRI_GetErrorMessageAql (const TRI_aql_error_t* const error) { char* message; char buffer[256]; int code; TRI_ASSERT(error); code = TRI_GetErrorCodeAql(error); if (code == TRI_ERROR_NO_ERROR) { return NULL; } message = error->_message; if (message == NULL) { return NULL; } if (error->_data && (NULL != strstr(message, "%s"))) { int written = snprintf(buffer, sizeof(buffer), message, error->_data); return TRI_DuplicateString2Z(TRI_UNKNOWN_MEM_ZONE, (const char*) &buffer, (size_t) written); } return TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, message); }
static int SetError (TRI_replication_applier_t* applier, int errorCode, char const* msg) { TRI_replication_applier_state_t* state; char const* realMsg; if (msg == NULL || strlen(msg) == 0) { realMsg = TRI_errno_string(errorCode); } else { realMsg = msg; } // log error message if (errorCode != TRI_ERROR_REPLICATION_APPLIER_STOPPED) { LOG_ERROR("replication applier error for database '%s': %s", applier->_databaseName, realMsg); } state = &applier->_state; state->_lastError._code = errorCode; TRI_GetTimeStampReplication(state->_lastError._time, sizeof(state->_lastError._time) - 1); if (state->_lastError._msg != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, state->_lastError._msg); } state->_lastError._msg = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, realMsg); return errorCode; }
void TRI_SetProgressReplicationApplier (TRI_replication_applier_t* applier, char const* msg, bool lock) { char* copy; copy = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, msg); if (copy == NULL) { return; } if (lock) { TRI_WriteLockReadWriteLock(&applier->_statusLock); } if (applier->_state._progressMsg != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, applier->_state._progressMsg); } applier->_state._progressMsg = copy; // write time in buffer TRI_GetTimeStampReplication(applier->_state._progressTime, sizeof(applier->_state._progressTime) - 1); if (lock) { TRI_WriteUnlockReadWriteLock(&applier->_statusLock); } }
void TRI_SetProcessTitle (char const* title) { #if TRI_TAMPER_WITH_ENVIRON if (! IsEnvironmentEnlarged) { size_t size; int envLen = -1; if (environ) { while (environ[++envLen]) { ; } } if (envLen > 0) { size = environ[envLen - 1] + strlen(environ[envLen - 1]) - ARGV[0]; } else { size = ARGV[ARGC - 1] + strlen(ARGV[ARGC - 1]) - ARGV[0]; } if (environ) { char** newEnviron = TRI_Allocate(TRI_CORE_MEM_ZONE, (envLen + 1) * sizeof(char*), false); size_t i = 0; while (environ[i]) { newEnviron[i] = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, environ[i]); ++i; } // pad with a null pointer so we know the end of the array newEnviron[i] = NULL; environ = newEnviron; MustFreeEnvironment = true; } IsEnvironmentEnlarged = true; MaximalProcessTitleSize = size; } #else MaximalProcessTitleSize = ARGV[ARGC - 1] + strlen(ARGV[ARGC - 1]) - ARGV[0]; #endif if (0 < MaximalProcessTitleSize) { char* args = ARGV[0]; memset(args, '\0', MaximalProcessTitleSize); snprintf(args, MaximalProcessTitleSize - 1, "%s", title); } #ifdef TRI_HAVE_SYS_PRCTL_H prctl(PR_SET_NAME, title, 0, 0, 0); #endif }
void TRI_InitMasterInfoReplication (TRI_replication_master_info_t* info, const char* endpoint) { TRI_ASSERT(endpoint != nullptr); info->_endpoint = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, endpoint); info->_serverId = 0; info->_majorVersion = 0; info->_minorVersion = 0; info->_lastLogTick = 0; info->_active = false; }
TRI_vector_string_t* TRI_CopyVectorString (TRI_memory_zone_t* zone, TRI_vector_string_t* vector) { TRI_vector_string_t* copy; char** ptr; char** end; char** qtr; copy = TRI_Allocate(zone, sizeof(TRI_vector_t), false); if (copy == NULL) { return NULL; } copy->_memoryZone = zone; if (vector->_capacity == 0) { copy->_buffer = NULL; copy->_length = 0; copy->_capacity = 0; } else { copy->_buffer = TRI_Allocate(zone, vector->_length * sizeof(char*), false); if (copy->_buffer == NULL) { TRI_Free(zone, copy); return NULL; } copy->_capacity = vector->_length; copy->_length = vector->_length; ptr = vector->_buffer; end = vector->_buffer + vector->_length; qtr = copy->_buffer; for (; ptr < end; ++ptr, ++qtr) { *qtr = TRI_DuplicateStringZ(zone, *ptr); if (*qtr == NULL) { char** xtr = copy->_buffer; for (; xtr < qtr; ++xtr) { TRI_Free(zone, *xtr); } TRI_Free(zone, copy->_buffer); TRI_Free(zone, copy); return NULL; } } } return copy; }
TRI_replication_applier_t* TRI_CreateReplicationApplier (TRI_vocbase_t* vocbase) { TRI_replication_applier_t* applier; int res; applier = TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(TRI_replication_applier_t), false); if (applier == NULL) { return NULL; } TRI_InitConfigurationReplicationApplier(&applier->_configuration); TRI_InitStateReplicationApplier(&applier->_state); res = LoadConfiguration(vocbase, &applier->_configuration); if (res != TRI_ERROR_NO_ERROR && res != TRI_ERROR_FILE_NOT_FOUND) { TRI_set_errno(res); TRI_DestroyStateReplicationApplier(&applier->_state); TRI_DestroyConfigurationReplicationApplier(&applier->_configuration); TRI_Free(TRI_CORE_MEM_ZONE, applier); return NULL; } res = TRI_LoadStateReplicationApplier(vocbase, &applier->_state); if (res != TRI_ERROR_NO_ERROR && res != TRI_ERROR_FILE_NOT_FOUND) { TRI_set_errno(res); TRI_DestroyStateReplicationApplier(&applier->_state); TRI_DestroyConfigurationReplicationApplier(&applier->_configuration); TRI_Free(TRI_CORE_MEM_ZONE, applier); return NULL; } TRI_InitReadWriteLock(&applier->_statusLock); TRI_InitSpin(&applier->_threadLock); TRI_InitCondition(&applier->_runStateChangeCondition); applier->_vocbase = vocbase; applier->_databaseName = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, vocbase->_name); SetTerminateFlag(applier, false); assert(applier->_databaseName != NULL); TRI_SetProgressReplicationApplier(applier, "applier created", false); return applier; }
void TRI_CopyConfigurationReplicationApplier (TRI_replication_applier_configuration_t const* src, TRI_replication_applier_configuration_t* dst) { if (src->_endpoint != NULL) { dst->_endpoint = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, src->_endpoint); } else { dst->_endpoint = NULL; } if (src->_database != NULL) { dst->_database = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, src->_database); } else { dst->_database = NULL; } if (src->_username != NULL) { dst->_username = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, src->_username); } else { dst->_username = NULL; } if (src->_password != NULL) { dst->_password = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, src->_password); } else { dst->_password = NULL; } dst->_requestTimeout = src->_requestTimeout; dst->_connectTimeout = src->_connectTimeout; dst->_ignoreErrors = src->_ignoreErrors; dst->_maxConnectRetries = src->_maxConnectRetries; dst->_sslProtocol = src->_sslProtocol; dst->_chunkSize = src->_chunkSize; dst->_autoStart = src->_autoStart; dst->_adaptivePolling = src->_adaptivePolling; }
int TRI_StateReplicationApplier (TRI_replication_applier_t* applier, TRI_replication_applier_state_t* state) { TRI_InitStateReplicationApplier(state); TRI_ReadLockReadWriteLock(&applier->_statusLock); state->_active = applier->_state._active; state->_lastAppliedContinuousTick = applier->_state._lastAppliedContinuousTick; state->_lastProcessedContinuousTick = applier->_state._lastProcessedContinuousTick; state->_lastAvailableContinuousTick = applier->_state._lastAvailableContinuousTick; state->_serverId = applier->_state._serverId; state->_lastError._code = applier->_state._lastError._code; state->_failedConnects = applier->_state._failedConnects; state->_totalRequests = applier->_state._totalRequests; state->_totalFailedConnects = applier->_state._totalFailedConnects; state->_totalEvents = applier->_state._totalEvents; memcpy(&state->_lastError._time, &applier->_state._lastError._time, sizeof(state->_lastError._time)); if (applier->_state._progressMsg != NULL) { state->_progressMsg = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, applier->_state._progressMsg); } else { state->_progressMsg = NULL; } memcpy(&state->_progressTime, &applier->_state._progressTime, sizeof(state->_progressTime)); if (applier->_state._lastError._msg != NULL) { state->_lastError._msg = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, applier->_state._lastError._msg); } else { state->_lastError._msg = NULL; } TRI_ReadUnlockReadWriteLock(&applier->_statusLock); return TRI_ERROR_NO_ERROR; }
static char* GetIndexIdString (TRI_aql_collection_hint_t* const hint) { TRI_string_buffer_t buffer; char* result; TRI_InitStringBuffer(&buffer, TRI_UNKNOWN_MEM_ZONE); TRI_AppendUInt64StringBuffer(&buffer, hint->_collection->_collection->_cid); TRI_AppendCharStringBuffer(&buffer, '/'); TRI_AppendUInt64StringBuffer(&buffer, hint->_index->_idx->_iid); result = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, buffer._buffer); TRI_DestroyStringBuffer(&buffer); return result; }
char* TRI_GetErrorMessageAql (const TRI_aql_error_t* const error) { char* message = NULL; char buffer[1024]; int code; assert(error); code = TRI_GetErrorCodeAql(error); if (!code) { return NULL; } message = error->_message; if (!message) { return NULL; } if (error->_data && (NULL != strstr(message, "%s"))) { snprintf(buffer, sizeof(buffer), message, error->_data); return TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, (const char*) &buffer); } return TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, message); }
TRI_index_t* TRI_CreateGeo1Index (TRI_document_collection_t* document, TRI_idx_iid_t iid, char const* locationName, TRI_shape_pid_t location, bool geoJson, bool unique, bool ignoreNull) { char* ln; TRI_geo_index_t* geo = static_cast<TRI_geo_index_t*>(TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(TRI_geo_index_t), false)); TRI_index_t* idx = &geo->base; TRI_InitVectorString(&idx->_fields, TRI_CORE_MEM_ZONE); TRI_InitIndex(idx, iid, TRI_IDX_TYPE_GEO1_INDEX, document, unique, false); idx->_ignoreNull = ignoreNull; idx->memory = MemoryGeoIndex; idx->json = JsonGeo1Index; idx->insert = InsertGeoIndex; idx->remove = RemoveGeoIndex; ln = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, locationName); TRI_PushBackVectorString(&idx->_fields, ln); geo->_geoIndex = GeoIndex_new(); // oops, out of memory? if (geo->_geoIndex == NULL) { TRI_DestroyVectorString(&idx->_fields); TRI_Free(TRI_CORE_MEM_ZONE, geo); return NULL; } geo->_variant = geoJson ? INDEX_GEO_COMBINED_LAT_LON : INDEX_GEO_COMBINED_LON_LAT; geo->_location = location; geo->_latitude = 0; geo->_longitude = 0; geo->_geoJson = geoJson; return idx; }
TRI_aql_variable_t* TRI_CreateVariableAql (char const* name, TRI_aql_node_t* definingNode) { TRI_aql_variable_t* variable; variable = (TRI_aql_variable_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_aql_variable_t), false); if (variable == nullptr) { return nullptr; } variable->_name = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, name); if (variable->_name == nullptr) { TRI_FreeVariableAql(variable); return nullptr; } variable->_definingNode = definingNode; variable->_isUpdated = false; TRI_ASSERT(definingNode); return variable; }
char* ShellImplementation::prompt (char const* the_prompt) { string dotdot; char const* p = the_prompt; size_t len1 = strlen(the_prompt); size_t len2 = len1; size_t lineno = 0; if (len1 < 3) { dotdot = "> "; len2 = 2; } else { dotdot = string(len1 - 2, '.') + "> "; } char const* sep = ""; while (true) { // calling concrete implmentation of the shell char* result = getLine(p); p = dotdot.c_str(); if (result == 0) { // give up, if the user pressed control-D on the top-most level if (_current.empty()) { return 0; } // otherwise clear current content _current.clear(); break; } _current += sep; sep = "\n"; ++lineno; // remove any the_prompt at the beginning of the line char* originalLine = result; bool c1 = strncmp(result, the_prompt, len1) == 0; bool c2 = strncmp(result, dotdot.c_str(), len2) == 0; while (c1 || c2) { if (c1) { result += len1; } else if (c2) { result += len2; } c1 = strncmp(result, the_prompt, len1) == 0; c2 = strncmp(result, dotdot.c_str(), len2) == 0; } // extend line and check _current += result; bool ok = _completer->isComplete(_current, lineno, strlen(result)); // cannot use TRI_Free, because it was allocated by the system call readline TRI_SystemFree(originalLine); // stop if line is complete if (ok) { break; } } char* line = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, _current.c_str()); _current.clear(); return line; }
static int LoadConfiguration (TRI_vocbase_t* vocbase, TRI_replication_applier_configuration_t* config) { TRI_json_t* json; TRI_json_t* value; char* filename; int res; TRI_DestroyConfigurationReplicationApplier(config); TRI_InitConfigurationReplicationApplier(config); filename = GetConfigurationFilename(vocbase); if (! TRI_ExistsFile(filename)) { TRI_FreeString(TRI_CORE_MEM_ZONE, filename); return TRI_ERROR_FILE_NOT_FOUND; } json = TRI_JsonFile(TRI_CORE_MEM_ZONE, filename, NULL); TRI_FreeString(TRI_CORE_MEM_ZONE, filename); if (! TRI_IsArrayJson(json)) { if (json != NULL) { TRI_FreeJson(TRI_CORE_MEM_ZONE, json); } return TRI_ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION; } res = TRI_ERROR_NO_ERROR; if (config->_endpoint != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, config->_endpoint); config->_endpoint = NULL; } if (config->_database != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, config->_database); config->_database = NULL; } if (config->_username != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, config->_username); config->_username = NULL; } if (config->_password != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, config->_password); config->_password = NULL; } // read the endpoint value = TRI_LookupArrayJson(json, "endpoint"); if (! TRI_IsStringJson(value)) { res = TRI_ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION; } else { config->_endpoint = TRI_DuplicateString2Z(TRI_CORE_MEM_ZONE, value->_value._string.data, value->_value._string.length - 1); } // read the database name value = TRI_LookupArrayJson(json, "database"); if (! TRI_IsStringJson(value)) { config->_database = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, vocbase->_name); } else { config->_database = TRI_DuplicateString2Z(TRI_CORE_MEM_ZONE, value->_value._string.data, value->_value._string.length - 1); } // read username / password value = TRI_LookupArrayJson(json, "username"); if (TRI_IsStringJson(value)) { config->_username = TRI_DuplicateString2Z(TRI_CORE_MEM_ZONE, value->_value._string.data, value->_value._string.length - 1); } value = TRI_LookupArrayJson(json, "password"); if (TRI_IsStringJson(value)) { config->_password = TRI_DuplicateString2Z(TRI_CORE_MEM_ZONE, value->_value._string.data, value->_value._string.length - 1); } value = TRI_LookupArrayJson(json, "requestTimeout"); if (TRI_IsNumberJson(value)) { config->_requestTimeout = value->_value._number; } value = TRI_LookupArrayJson(json, "connectTimeout"); if (TRI_IsNumberJson(value)) { config->_connectTimeout = value->_value._number; } value = TRI_LookupArrayJson(json, "maxConnectRetries"); if (TRI_IsNumberJson(value)) { config->_maxConnectRetries = (uint64_t) value->_value._number; } value = TRI_LookupArrayJson(json, "chunkSize"); if (TRI_IsNumberJson(value)) { config->_chunkSize = (uint64_t) value->_value._number; } value = TRI_LookupArrayJson(json, "autoStart"); if (TRI_IsBooleanJson(value)) { config->_autoStart = value->_value._boolean; } value = TRI_LookupArrayJson(json, "adaptivePolling"); if (TRI_IsBooleanJson(value)) { config->_adaptivePolling = value->_value._boolean; } TRI_FreeJson(TRI_CORE_MEM_ZONE, json); return res; }
static void DropDatafileCallback (TRI_datafile_t* datafile, void* data) { TRI_primary_collection_t* primary; TRI_voc_fid_t fid; char* filename; char* name; char* number; char* copy; bool ok; primary = data; fid = datafile->_fid; copy = NULL; number = TRI_StringUInt64(fid); name = TRI_Concatenate3String("deleted-", number, ".db"); filename = TRI_Concatenate2File(primary->base._directory, name); TRI_FreeString(TRI_CORE_MEM_ZONE, number); TRI_FreeString(TRI_CORE_MEM_ZONE, name); if (datafile->isPhysical(datafile)) { copy = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, datafile->_filename); ok = TRI_RenameDatafile(datafile, filename); if (! ok) { LOG_ERROR("cannot rename obsolete datafile '%s' to '%s': %s", copy, filename, TRI_last_error()); } } LOG_DEBUG("finished compacting datafile '%s'", datafile->getName(datafile)); ok = TRI_CloseDatafile(datafile); if (! ok) { LOG_ERROR("cannot close obsolete datafile '%s': %s", datafile->getName(datafile), TRI_last_error()); } else if (datafile->isPhysical(datafile)) { if (primary->base._vocbase->_settings.removeOnCompacted) { int res; LOG_DEBUG("wiping compacted datafile from disk"); res = TRI_UnlinkFile(filename); if (res != TRI_ERROR_NO_ERROR) { LOG_ERROR("cannot wipe obsolete datafile '%s': %s", datafile->getName(datafile), TRI_last_error()); } // check for .dead files if (copy != NULL) { // remove .dead file for datafile char* deadfile = TRI_Concatenate2String(copy, ".dead"); if (deadfile != NULL) { // check if .dead file exists, then remove it if (TRI_ExistsFile(deadfile)) { TRI_UnlinkFile(deadfile); } TRI_FreeString(TRI_CORE_MEM_ZONE, deadfile); } } } } TRI_FreeDatafile(datafile); TRI_FreeString(TRI_CORE_MEM_ZONE, filename); if (copy != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, copy); } }