Ejemplo n.º 1
0
        /// <summary>
        /// Updates data from the specified <see cref="LogTableRecord" /> into the table designated by the <see cref="LogTableDefinition" />.
        /// </summary>
        /// <param name="table">The <see cref="LogTableDefinition" />.</param>
        /// <param name="record">The <see cref="LogTableRecord" />.</param>
        /// <returns><c>true</c> if submission was successful, <c>false</c> otherwise.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="table" /> is null.
        /// <para>or</para>
        /// <paramref name="record" /> is null.
        /// </exception>
        public bool Update(LogTableDefinition table, LogTableRecord record)
        {
            if (table == null)
            {
                throw new ArgumentNullException(nameof(table));
            }

            if (record == null)
            {
                throw new ArgumentNullException(nameof(record));
            }

            LogTrace($"UPDATE request received for {table.Name} (primary key = {record[table.PrimaryKey]})");
            DataLogDatabaseResult result = _writer.Update(table, record);
            bool updateSuccessful        = result.Success;

            // If the operation failed, try the alternate (if one exists)
            if (!updateSuccessful && _alternateWriter != null)
            {
                LogTrace($"UPDATE failed.  Attempting update to alternate database.");
                DataLogDatabaseResult alternateResult = _alternateWriter.Update(table, record);
                updateSuccessful = alternateResult.Success;
            }

            // If the operation hasn't succeeded, check to see if we should add this to the cache.
            if (!updateSuccessful)
            {
                _cache?.Add(table, record, false);
            }

            return(updateSuccessful);
        }
Ejemplo n.º 2
0
        public DataLogDatabaseResult Insert(LogTableDefinition table, LogTableRecord record)
        {
            if (table == null)
            {
                throw new ArgumentNullException(nameof(table));
            }

            if (record == null)
            {
                throw new ArgumentNullException(nameof(record));
            }

            LogTrace($"INSERT {table.Name} (primary key = {record[table.PrimaryKey]})");

            DataLogDatabaseResult result;

            using (SqlCommand insert = DataLogSqlBuilder.BuildInsert(table, record))
            {
                result = new DataLogDatabaseResult(table.Name, insert);
                try
                {
                    using (SqlConnection connection = new SqlConnection(_connectionString.ToString()))
                    {
                        connection.Open();
                        insert.Connection = connection;

                        try
                        {
                            insert.ExecuteNonQuery();
                        }
                        catch (SqlException ex) when(ex.Message.Contains("Invalid object"))
                        {
                            // Table doesn't exist - create it and try again
                            LogDebug($"Generating new table {table.Name}");
                            if (CreateTable(connection, table))
                            {
                                LogDebug($"Table {table.Name} created.");
                                LogTrace($"Retrying INSERT {table.Name}");
                                insert.ExecuteNonQuery();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    result.Error = ex.Message;
                }
            }

            if (!result.Success)
            {
                LogWarn($"INSERT {table.Name} failed: {result.Error}");
                LogTrace($"SQL command: " + result.Command);
                LogTrace($"SQL parameters: {string.Join("; ", result.Parameters.Select(n => $"{n.Key}={n.Value}"))}");
            }

            return(result);
        }
Ejemplo n.º 3
0
        public DataLogDatabaseResult Update(LogTableDefinition table, LogTableRecord record)
        {
            if (table == null)
            {
                throw new ArgumentNullException(nameof(table));
            }

            if (record == null)
            {
                throw new ArgumentNullException(nameof(record));
            }

            LogTrace($"UPDATE {table.Name} (primary key = {record[table.PrimaryKey]})");

            DataLogDatabaseResult result;

            using (SqlCommand update = DataLogSqlBuilder.BuildUpdate(table, record))
            {
                result = new DataLogDatabaseResult(table.Name, update);
                try
                {
                    using (SqlConnection connection = new SqlConnection(_connectionString.ToString()))
                    {
                        connection.Open();
                        update.Connection = connection;

                        int affectedRows = update.ExecuteNonQuery();
                        if (affectedRows == 0)
                        {
                            result.Error = "No rows were affected.";
                        }
                    }
                }
                catch (Exception ex)
                {
                    result.Error = ex.Message;
                }
            }

            if (!result.Success)
            {
                LogWarn($"UPDATE {table.Name} failed: {result.Error}");
                LogTrace($"SQL command: " + result.Command);
                LogTrace($"SQL parameters: {string.Join("; ", result.Parameters.Select(n => $"{n.Key}={n.Value}"))}");
            }

            return(result);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Inserts data from the specified <see cref="LogTableRecord" /> into the table designated by the <see cref="LogTableDefinition" />.
        /// </summary>
        /// <param name="table">The <see cref="LogTableDefinition" />.</param>
        /// <param name="record">The <see cref="LogTableRecord" />.</param>
        /// <returns><c>true</c> if submission was successful, <c>false</c> otherwise.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="table" /> is null.
        /// <para>or</para>
        /// <paramref name="record" /> is null.
        /// </exception>
        public bool Insert(LogTableDefinition table, LogTableRecord record)
        {
            if (table == null)
            {
                throw new ArgumentNullException(nameof(table));
            }

            if (record == null)
            {
                throw new ArgumentNullException(nameof(record));
            }

            LogTrace($"INSERT request received for {table.Name} (primary key = {record[table.PrimaryKey]})");
            DataLogDatabaseResult result = _writer.Insert(table, record);
            bool insertSuccessful        = result.Success;

            // If the operation failed, try the alternate (if one exists)
            if (!insertSuccessful && _alternateWriter != null)
            {
                LogTrace($"INSERT failed.  Attempting insert to alternate database.");
                DataLogDatabaseResult alternateResult = _alternateWriter.Insert(table, record);
                insertSuccessful = alternateResult.Success;
            }

            // If the operation hasn't succeeded, check to see if we should add this to the cache.
            if (!insertSuccessful && _cache != null)
            {
                if (result.Error.Contains("Violation of PRIMARY KEY constraint", StringComparison.OrdinalIgnoreCase))
                {
                    // Bypass the cache for primary key violations
                    result.Retries = -1;
                    CacheOperationsRetried?.Invoke(this, new DataLogCacheEventArgs(new[] { result }));
                }
                else
                {
                    _cache.Add(table, record, true);
                }
            }

            return(insertSuccessful);
        }
Ejemplo n.º 5
0
        public IEnumerable <DataLogDatabaseResult> RetryFromCache()
        {
            if (!Directory.Exists(_cacheLocation.FullName))
            {
                return(Enumerable.Empty <DataLogDatabaseResult>());
            }

            // Ignore files that have exceeded the maximum retry time.
            DateTime cutoff = DateTime.Now - _maximumRetryTime;

            bool loggedStart = false;
            int  fileErrors  = 0;
            List <DataLogDatabaseResult> results = new List <DataLogDatabaseResult>();

            foreach (FileInfo file in _cacheLocation.EnumerateFiles("*.xml").Where(n => n.CreationTime > cutoff).OrderBy(n => n.CreationTime))
            {
                if (!loggedStart)
                {
                    LogDebug("Retrying from cache...");
                    loggedStart = true;
                }

                try
                {
                    LogTrace($"Reading cache file {file.Name}");
                    DataLogCacheData data = ReadCacheData(file);
                    data.Retries++;

                    DataLogDatabaseResult result = data.IsInsert ?
                                                   _databaseWriter.Insert(data.Table, data.Record) :
                                                   _databaseWriter.Update(data.Table, data.Record);
                    bool operationSuccessful = result.Success;

                    if (!operationSuccessful && _alternateWriter != null)
                    {
                        DataLogDatabaseResult alternateResult = data.IsInsert ?
                                                                _alternateWriter.Insert(data.Table, data.Record) :
                                                                _alternateWriter.Update(data.Table, data.Record);
                        operationSuccessful = alternateResult.Success;
                    }

                    if (operationSuccessful)
                    {
                        LogTrace($"Cache operation successful.  Deleting file {file.Name}.");
                        try
                        {
                            Retry.WhileThrowing <IOException>(() => file.Delete(), 5, TimeSpan.FromSeconds(1));
                        }
                        catch (IOException ex)
                        {
                            LogDebug($"File {file.Name} could not be deleted: {ex.Message}");
                        }
                    }
                    else
                    {
                        LogTrace($"Cache operation failed.  {file.Name} has been retried {data.Retries} times.");
                        WriteCacheData(file, data);
                    }

                    result.Retries = data.Retries;
                    results.Add(result);
                }
                catch (Exception ex)
                {
                    // Do nothing - could be a fluke, or a file that we can't read
                    LogTrace($"Unknown error: {ex.Message}");
                    fileErrors++;
                }
            }

            if (results.Any())
            {
                LogDebug($"Cache retry results: {results.Count(n => n.Success)} succeeded, {results.Count(n => !n.Success)} failed, {fileErrors} cache errors.");
            }
            return(results);
        }