Пример #1
0
        /// <summary>
        /// Gets the data.
        /// </summary>
        /// <param name="columns">The columns.</param>
        /// <param name="previousHighWatermark">The previous high watermark.</param>
        /// <returns>
        /// A streaming reader for the data.
        /// </returns>
        public IDataReader GetData(IEnumerable <string> columns, Watermark previousHighWatermark)
        {
            try
            {
                IEnumerable <IFileInfo> files = this.FindFiles(previousHighWatermark);

                if (files.Count() == 0)
                {
                    return(null);
                }

                EventPublisher.Raise(
                    new SourceFileFoundEvent
                {
                    OperationId    = this.Parent.OperationId,
                    SourceName     = this.name,
                    ConnectionName = this.ConnectionName,
                    FoundFiles     = files
                });

                return(this.fileSystem.CreateDataReader(files, this.config));
            }
            catch (IOException ex)
            {
                if (ex.IsFileLocked())
                {
                    EventPublisher.Raise(
                        new SourceFileLockedEvent
                    {
                        OperationId    = this.Parent.OperationId,
                        SourceName     = this.Name,
                        ConnectionName = this.ConnectionName,
                        Exception      = ex
                    });

                    // Back off and wait till next time.
                    return(null);
                }

                EventPublisher.Raise(
                    new SourceErrorEvent
                {
                    OperationId    = this.Parent.OperationId,
                    SourceName     = this.Name,
                    ConnectionName = this.ConnectionName,
                    Exception      = ex
                });

                throw;
            }
        }
Пример #2
0
        /// <summary>
        /// Updates the high watermark.
        /// </summary>
        /// <param name="table">The table.</param>
        /// <param name="newValue">The new value.</param>
        public void UpdateHighWatermark(string table, Watermark newValue)
        {
            var watermarkFile = this.FormatWatermarkFileName(table);

            if (!File.Exists(watermarkFile))
            {
                File.Delete(watermarkFile);
            }

            using (var file = new StreamWriter(watermarkFile))
            {
                var json = JsonConvert.SerializeObject(newValue);
                file.Write(json);
            }
        }
Пример #3
0
        /// <summary>
        /// Gets the command text.
        /// </summary>
        /// <param name="columns">The target columns.</param>
        /// <param name="previousHighWatermark">The previous high watermark.</param>
        /// <returns>
        /// A SQL query.
        /// </returns>
        protected override string GetCommandText(IEnumerable <string> columns, Watermark previousHighWatermark)
        {
            var query = new StringBuilder();

            query
            .Append("select ")
            .Append(columns.Aggregate(string.Empty, (a, v) => a + (a.Length == 0 ? v : ", " + v)))
            .Append(columns.Count() == 0 ? "*" : string.Empty)
            .AppendFormat(CultureInfo.InvariantCulture, " from {0}", this.tableName);

            if (previousHighWatermark != null)
            {
                query.AppendFormat(CultureInfo.InvariantCulture, " where {0} > @highWatermark", previousHighWatermark.WatermarkColumn);
            }

            return(query.ToString());
        }
Пример #4
0
        /// <summary>
        /// Gets the columns.
        /// </summary>
        /// <param name="previousHighWatermark">The previous high watermark.</param>
        /// <returns>
        /// A sequence of columns.
        /// </returns>
        public IEnumerable <string> GetColumns(Watermark previousHighWatermark)
        {
            // The CSV source is a little complex because we derive the column list from real
            // source data. If there are files we need to use the actual one that is going to be
            // imported. If not then any file will do - even ones below the watermark.
            using (var latestData = this.GetData(Enumerable.Empty <string>(), previousHighWatermark))
                using (var sampleData = this.GetData(Enumerable.Empty <string>(), null))
                {
                    var columnData = latestData ?? sampleData;

                    if (columnData == null)
                    {
                        yield break;
                    }

                    for (int i = 0; i < columnData.FieldCount; ++i)
                    {
                        yield return(columnData.GetName(i));
                    }
                }
        }
Пример #5
0
        /// <summary>
        /// Updates the high watermark using the current value from the staging table.
        /// </summary>
        /// <returns>
        /// A watermark instance.
        /// </returns>
        public Watermark UpdateHighWatermark()
        {
            if (this.highWatermarkColumn == null)
            {
                return(null);
            }

            var sql = string.Format(CultureInfo.CurrentCulture, "select max({0}) from {1};", this.highWatermarkColumn, this.tableName);

            var result = this.connectionFactory.ExecuteScalar(sql, this.OperationId);

            if (result == null || result == DBNull.Value)
            {
                return(null);
            }

            var newHighwaterMark = new Watermark(this.highWatermarkColumn, (DateTime)result);

            this.watermarkService.UpdateHighWatermark(this.tableName, newHighwaterMark);

            return(newHighwaterMark);
        }
Пример #6
0
        public IDataReader GetData(IEnumerable <string> columns, Watermark previousHighWatermark)
        {
            try
            {
                var connection = this.connectionFactory.CreateConnection();
                connection.Open();

                var command = connection.CreateCommand();
                command.CommandText    = this.GetCommandText(columns, previousHighWatermark);
                command.CommandTimeout = 0;

                var highWatermarkParameterName = this.connectionFactory.MakeParameterName("highWatermark");

                if (command.CommandText.Contains(highWatermarkParameterName))
                {
                    var watermarkParameter = command.CreateParameter();
                    watermarkParameter.ParameterName = highWatermarkParameterName;
                    watermarkParameter.Value         = previousHighWatermark == null ? Settings.Default.DefaultHighWatermark : previousHighWatermark.WatermarkValue;
                    command.Parameters.Add(watermarkParameter);
                }

                DittoEventSource.Log.DatabaseQuery(this.connectionFactory.Name, command.CommandText, this.OperationId);

                return(command.ExecuteReader(CommandBehavior.CloseConnection));
            }
            catch (DbException ex)
            {
                EventPublisher.Raise(
                    new SourceErrorEvent
                {
                    OperationId    = this.Parent.OperationId,
                    SourceName     = this.Name,
                    ConnectionName = this.connectionFactory.Name,
                    Exception      = ex
                });

                throw;
            }
        }
Пример #7
0
        /// <summary>
        /// Finds the files.
        /// </summary>
        /// <param name="previousHighWatermark">The previous high watermark.</param>
        /// <returns>A sequence of files to import.</returns>
        private IEnumerable <IFileInfo> FindFiles(Watermark previousHighWatermark)
        {
            var allFiles = this.fileSystem.EnumerateFiles(this.connection.ConnectionString, this.filePattern)
                           .Where(f => previousHighWatermark == null || f.LastWriteTimeUtc > previousHighWatermark.WatermarkValue);

            IEnumerable <IFileInfo> importFiles = null;

            switch (this.mode)
            {
            case FolderMode.MultipleFile:
                importFiles = allFiles.OrderBy(f => f.LastWriteTimeUtc);
                break;

            case FolderMode.SingleFile:
                importFiles = allFiles.OrderBy(f => f.LastWriteTimeUtc).Take(1);
                break;

            case FolderMode.LastFileOnly:
                importFiles = allFiles.OrderByDescending(f => f.LastWriteTimeUtc).Take(1);
                break;
            }

            return(importFiles);
        }
Пример #8
0
 /// <summary>
 /// Determines whether the specified previous high watermark has data.
 /// </summary>
 /// <param name="previousHighWatermark">The previous high watermark.</param>
 /// <returns>
 /// True if there is data.
 /// </returns>
 /// <remarks>
 /// This allows a shortcut for sources that may not exist e.g. files.
 /// </remarks>
 public bool HasData(Watermark previousHighWatermark)
 {
     return(this.FindFiles(previousHighWatermark).Any());
 }
Пример #9
0
 /// <summary>
 /// Gets the command text.
 /// </summary>
 /// <param name="columns">The target columns.</param>
 /// <param name="previousHighWatermark">The previous high watermark.</param>
 /// <returns>
 /// A SQL query.
 /// </returns>
 protected override string GetCommandText(IEnumerable<string> columns, Watermark previousHighWatermark)
 {
     return this.query;
 }
Пример #10
0
 /// <summary>
 /// Gets the command text.
 /// </summary>
 /// <param name="columns">The target columns.</param>
 /// <param name="previousHighWatermark">The previous high watermark.</param>
 /// <returns>
 /// A SQL query.
 /// </returns>
 protected abstract string GetCommandText(IEnumerable <string> columns, Watermark previousHighWatermark);
Пример #11
0
 /// <summary>
 /// Determines whether the specified previous high watermark has data.
 /// </summary>
 /// <param name="previousHighWatermark">The previous high watermark.</param>
 /// <returns>
 /// True if there is data.
 /// </returns>
 /// <remarks>
 /// This allows a shortcut for sources that may not exist e.g. files.
 /// </remarks>
 public bool HasData(Watermark previousHighWatermark)
 {
     // Databases always "have" data even if there are no rows.
     return(true);
 }