<commit_before>﻿// Copyright 2013 Serilog Contributors 
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using Serilog.Debugging;
using Serilog.Events;
using Serilog.Sinks.PeriodicBatching;
namespace Serilog.Sinks.MSSqlServer
{
	/// <summary>
	///     Writes log events as rows in a table of MSSqlServer database.
	/// </summary>
	public class MSSqlServerSink : PeriodicBatchingSink
	{
		/// <summary>
		///     A reasonable default for the number of events posted in
		///     each batch.
		/// </summary>
		public const int DefaultBatchPostingLimit = 50;

		/// <summary>
		///     A reasonable default time to wait between checking for event batches.
		/// </summary>
		public static readonly TimeSpan DefaultPeriod = TimeSpan.FromSeconds(5);

		readonly string _connectionString;

		readonly DataTable _eventsTable;
		readonly IFormatProvider _formatProvider;
		readonly bool _includeProperties;
		readonly string _tableName;
		readonly CancellationTokenSource _token = new CancellationTokenSource();
		readonly bool _storeTimestampInUtc;

		private DataColumn[] _additionalDataColumns;

		/// <summary>
		///     Construct a sink posting to the specified database.
		/// </summary>
		/// <param name="connectionString">Connection string to access the database.</param>
		/// <param name="tableName">Name of the table to store the data in.</param>
		/// <param name="includeProperties">Specifies if the properties need to be saved as well.</param>
		/// <param name="batchPostingLimit">The maximum number of events to post in a single batch.</param>
		/// <param name="period">The time to wait between checking for event batches.</param>
		/// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
		/// <param name="storeTimestampInUtc">Store Timestamp In UTC</param>
		/// <param name="additionalDataColumns">Additional columns for data storage.</param>
		/// <param name="autoCreateSqlTable">Create log table with the provided name on destination sql server.</param>
		public MSSqlServerSink(string connectionString, string tableName, bool includeProperties, int batchPostingLimit,
			TimeSpan period, IFormatProvider formatProvider, bool storeTimestampInUtc, DataColumn[] additionalDataColumns = null,
			bool autoCreateSqlTable = false)
			: base(batchPostingLimit, period)
		{
			if (string.IsNullOrWhiteSpace(connectionString))
				throw new ArgumentNullException("connectionString");

			if (string.IsNullOrWhiteSpace(tableName))
				throw new ArgumentNullException("tableName");

			_connectionString = connectionString;
			_tableName = tableName;
			_includeProperties = includeProperties;
			_formatProvider = formatProvider;
			_storeTimestampInUtc = storeTimestampInUtc;
			_additionalDataColumns = additionalDataColumns;

			// Prepare the data table
			_eventsTable = CreateDataTable();

			if (autoCreateSqlTable)
			{
				try
				{
					SqlTableCreator tableCreator = new SqlTableCreator(connectionString);
					tableCreator.CreateTable(_eventsTable);
					throw  new Exception("Test exception");
				}
				catch (Exception ex)
				{					
					SelfLog.WriteLine("Exception {0} caught while creating table {1} to the database specified in the Connection string.", (object)ex, (object)tableName);					
				}
				
			}
		}

		/// <summary>
		///     Emit a batch of log events, running asynchronously.
		/// </summary>
		/// <param name="events">The events to emit.</param>
		/// <remarks>
		///     Override either <see cref="PeriodicBatchingSink.EmitBatch" /> or <see cref="PeriodicBatchingSink.EmitBatchAsync" />
		///     ,
		///     not both.
		/// </remarks><commit_msg>Removed test exception line which was added for test purpose only.<commit_after>﻿// Copyright 2013 Serilog Contributors 
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using Serilog.Debugging;
using Serilog.Events;
using Serilog.Sinks.PeriodicBatching;
namespace Serilog.Sinks.MSSqlServer
{
	/// <summary>
	///     Writes log events as rows in a table of MSSqlServer database.
	/// </summary>
	public class MSSqlServerSink : PeriodicBatchingSink
	{
		/// <summary>
		///     A reasonable default for the number of events posted in
		///     each batch.
		/// </summary>
		public const int DefaultBatchPostingLimit = 50;

		/// <summary>
		///     A reasonable default time to wait between checking for event batches.
		/// </summary>
		public static readonly TimeSpan DefaultPeriod = TimeSpan.FromSeconds(5);

		readonly string _connectionString;

		readonly DataTable _eventsTable;
		readonly IFormatProvider _formatProvider;
		readonly bool _includeProperties;
		readonly string _tableName;
		readonly CancellationTokenSource _token = new CancellationTokenSource();
		readonly bool _storeTimestampInUtc;

		private DataColumn[] _additionalDataColumns;

		/// <summary>
		///     Construct a sink posting to the specified database.
		/// </summary>
		/// <param name="connectionString">Connection string to access the database.</param>
		/// <param name="tableName">Name of the table to store the data in.</param>
		/// <param name="includeProperties">Specifies if the properties need to be saved as well.</param>
		/// <param name="batchPostingLimit">The maximum number of events to post in a single batch.</param>
		/// <param name="period">The time to wait between checking for event batches.</param>
		/// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
		/// <param name="storeTimestampInUtc">Store Timestamp In UTC</param>
		/// <param name="additionalDataColumns">Additional columns for data storage.</param>
		/// <param name="autoCreateSqlTable">Create log table with the provided name on destination sql server.</param>
		public MSSqlServerSink(string connectionString, string tableName, bool includeProperties, int batchPostingLimit,
			TimeSpan period, IFormatProvider formatProvider, bool storeTimestampInUtc, DataColumn[] additionalDataColumns = null,
			bool autoCreateSqlTable = false)
			: base(batchPostingLimit, period)
		{
			if (string.IsNullOrWhiteSpace(connectionString))
				throw new ArgumentNullException("connectionString");

			if (string.IsNullOrWhiteSpace(tableName))
				throw new ArgumentNullException("tableName");

			_connectionString = connectionString;
			_tableName = tableName;
			_includeProperties = includeProperties;
			_formatProvider = formatProvider;
			_storeTimestampInUtc = storeTimestampInUtc;
			_additionalDataColumns = additionalDataColumns;

			// Prepare the data table
			_eventsTable = CreateDataTable();

			if (autoCreateSqlTable)
			{
				try
				{
					SqlTableCreator tableCreator = new SqlTableCreator(connectionString);
					tableCreator.CreateTable(_eventsTable);					
				}
				catch (Exception ex)
				{					
					SelfLog.WriteLine("Exception {0} caught while creating table {1} to the database specified in the Connection string.", (object)ex, (object)tableName);					
				}
				
			}
		}

		/// <summary>
		///     Emit a batch of log events, running asynchronously.
		/// </summary>
		/// <param name="events">The events to emit.</param>
		/// <remarks>
		///     Override either <see cref="PeriodicBatchingSink.EmitBatch" /> or <see cref="PeriodicBatchingSink.EmitBatchAsync" />
		///     ,
		///     not both.
		/// </remarks>
{'fraction_non_alphanumeric': 0.10037385295117254, 'fraction_numerical': 0.0029455081001472753, 'mean_word_length': 3.795219989136339, 'pattern_counts': {'":': 0, '<': 71, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5629048', 'n_tokens_mistral': 2630, 'n_tokens_neox': 2341, 'n_words': 791}