Пример #1
0
        public void Can_generate_csv()
        {
            var data = new List <string[]>
            {
                new[] { "A number", "another number here", "#¤%i" },
                new[] { "1", "2", "3" },
                new[] { "2", "12", "14" },
                new[] { "3", "12", "13" },
                new[] { "4", "2", "3" }
            };
            var csvSettings = new CsvSettings(',')
            {
                HasHeader = true
            };
            var ctypes = new CsvColumnTypes(data, csvSettings);

            var tableName = this.DataStorage.SaveData(new IntPtr(10), data, ctypes);

            var result = this.DataStorage.ExecuteQueryToDataTable("SELECT * FROM " + tableName, new IntPtr(10));

            Assert.AreEqual("Anumber", result.Columns[0].ColumnName);

            string csv;

            using (var memStream = new MemoryStream())
            {
                var lookup = this.DataStorage.GetUnsafeColumnMaps(new IntPtr(10));
                csvSettings.GenerateToStream(result, memStream, lookup);
                csv = Encoding.UTF8.GetString(memStream.GetBuffer());
            }
            Assert.IsTrue(csv.StartsWith("A number,another number here,#¤%i"));
        }
Пример #2
0
        private void Parse(CsvSettings csvSettings, DiagnosticTimer watch, string text, IntPtr bufferId)
        {
            var data = csvSettings.Parse(text);

            watch.Checkpoint("Parse");

            var columnTypes = new CsvColumnTypes(data, csvSettings);

            try
            {
                Main.DataStorage.SaveData(bufferId, data, columnTypes);
            }
            catch (Exception ex)
            {
                this.ErrorMessage("Error when saving data to database:\n" + ex.Message);
                return;
            }
            watch.Checkpoint("Saved to DB");
            this.UiThread(() => txbQuery.Text = "SELECT * FROM THIS");
            Execute(bufferId, watch);

            var diagnostic = watch.LastCheckpoint("Resize");

            Trace.TraceInformation(diagnostic);
            if (Main.Settings.DebugMode)
            {
                this.Message(diagnostic);
            }
        }
Пример #3
0
        public void CanReadFiles()
        {
            var data = CsvSettings.Semicolon.Parse(File.ReadAllText(@"TestFiles\Headers.csv")).ToList();

            var result = new CsvColumnTypes(data, null);

            Assert.AreEqual(true, result.HasHeader);
        }
Пример #4
0
        public void CanDetectColumnTypes()
        {
            var data = CsvSettings.Comma.Parse(File.ReadAllText(@"TestFiles\random100x10.csv")).ToList();

            var result = new CsvColumnTypes(data, null);

            // AaoboInteger,LebhxShortString,GftghLongString,VnsbqChar,NzgubDate,TuyceDateAndTime,6VrnpkDecimal,AnpcfDecimal,LbncsShortString,QofayDate

            Assert.AreEqual(true, result.HasHeader);
            Assert.IsTrue(result.Columns[0].DataType == ColumnType.Integer);
            Assert.IsTrue(result.Columns[1].DataType == ColumnType.String);
            Assert.IsTrue(result.Columns[6].DataType == ColumnType.Decimal);
        }
Пример #5
0
            public void DangerousCharsRemoved()
            {
                var data = new List <string[]>
                {
                    new[] { "Col:3", "muu\\\"", "\r\n" },
                    new[] { "4", "2", "3", "meh" }
                };
                var columnTypes = new CsvColumnTypes(data, new CsvSettings {
                    HasHeader = true
                });

                Assert.IsTrue(columnTypes.Columns.Select(x => x.Name).SequenceEqual(new[] { "Col3", "muu", "Col32", "Col4" }));
            }
Пример #6
0
            public void NamesNotEmpty()
            {
                var data = new List <string[]>
                {
                    new[] { "Col3", " \t", "" },
                    new[] { "4", "2", "3", "meh" }
                };
                var columnTypes = new CsvColumnTypes(data, new CsvSettings {
                    HasHeader = true
                });

                Assert.IsTrue(columnTypes.Columns.TrueForAll(x => !string.IsNullOrWhiteSpace(x.Name)));
            }
Пример #7
0
            public void CanNameColumnsUniqly()
            {
                var data = new List <string[]>
                {
                    new[] { "Col3", "Col3", "Col3" },
                    new[] { "4", "2", "3" }
                };
                var columnTypes = new CsvColumnTypes(data, new CsvSettings {
                    HasHeader = true
                });

                Assert.IsTrue(columnTypes.Columns.Select(x => x.Name).SequenceEqual(new [] { "Col3", "Col32", "Col33" }));
            }
Пример #8
0
        public void CanDetectNoHeader()
        {
            var data = CsvSettings.Comma.Parse(File.ReadAllText(@"TestFiles\random100x10.csv")).ToList();

            data.RemoveAt(0);

            var result = new CsvColumnTypes(data, null);

            Assert.AreEqual(false, result.HasHeader);
            Assert.IsTrue(result.Columns[0].DataType == ColumnType.Integer);
            Assert.IsTrue(result.Columns[1].DataType == ColumnType.String);
            Assert.IsTrue(result.Columns[6].DataType == ColumnType.Decimal);
        }
Пример #9
0
        private static void PerformanceTest()
        {
            var timer = new DiagnosticTimer();
            var data  = new List <string[]>();

            var row = new[] { "12,34", "string", "321.23" };

            for (int i = 0; i < 2000000; i++)
            {
                data.Add(row);
            }
            timer.Checkpoint("data creation");

            var result = new CsvColumnTypes(data, null);

            Console.WriteLine(timer.LastCheckpoint("Anlyzed"));
            Console.WriteLine(result);
            Console.WriteLine("Column 1: " + result.Columns[0].DataType);
        }
Пример #10
0
        public void SaveToDbAndReadItBack()
        {
            var data = new List <string[]>
            {
                new[] { "hej", "du", "där" },
                new[] { "1", "2", "3" },
                new[] { "2", "12", "14" },
                new[] { "3", "12", "13" },
                new[] { "4", "2", "3" }
            };
            var ctypes = new CsvColumnTypes(data, new CsvSettings {
                HasHeader = false
            });

            var tableName = this.DataStorage.SaveData(new IntPtr(10), data, ctypes);

            var result = this.DataStorage.ExecuteQuery("SELECT * FROM " + tableName, false);

            this.AssertDataEqual(data, result);
        }
Пример #11
0
        public void SaveDecimalsToDbAndReadItBack()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
            var data = new List <string[]>
            {
                new[] { "hej", "du", "där" },
                new[] { "1", "2,44", "3" },
                new[] { "2", "12,300", "14" },
                new[] { "3", "12,000", "13" },
                new[] { "4", "2,010", "3" }
            };
            var ctypes = new CsvColumnTypes(data, new CsvSettings {
                HasHeader = true
            });

            var tableName = this.DataStorage.SaveData(new IntPtr(10), data, ctypes);

            var result = this.DataStorage.ExecuteQuery("SELECT * FROM " + tableName, true);

            this.AssertDataEqualAfterTypeConversion(data, result);
        }
Пример #12
0
        public void PerformanceTest()
        {
            var timer = new DiagnosticTimer();
            var data  = new List <string[]>();

            var row = new[] { "12,34", "string" };

            for (int i = 0; i < 1000000; i++)
            {
                data.Add(row);
            }
            timer.Checkpoint("data creation");

            var result = new CsvColumnTypes(data, null);

            Console.WriteLine(timer.LastCheckpoint("Anlyzed"));

            Assert.AreEqual(false, result.HasHeader);
            Assert.AreEqual(ColumnType.Decimal, result.Columns[0].DataType);
            Assert.AreEqual(ColumnType.String, result.Columns[1].DataType);
        }
Пример #13
0
        public void CanHandleOneRowWithMoreData()
        {
            var data = new List <string[]>
            {
                new[] { "hej", "du", "där" },
                new[] { "1", "2", "3" },
                new[] { "2", "12", "14", "extra" },
                new[] { "3", "12", "13" },
                new[] { "4", "2", "3" }
            };

            var columnTypes = new CsvColumnTypes(data, null);

            this.DataStorage.SaveData(new IntPtr(11), data, columnTypes);
            this.DataStorage.SetActiveTab(new IntPtr(11));

            var result = this.DataStorage.ExecuteQuery("SELECT * FROM this", true);

            Assert.AreEqual(5, result.Count);
            Assert.IsTrue(result.TrueForAll(x => x.Length == 4));
        }
Пример #14
0
        public void Generated_csv_get_safe_headers_when_setting_off()
        {
            var dataStorage = new SQLiteDataStorage();

            Main.Settings = new Settings {
                UseOriginalColumnHeadersOnGeneratedCsv = false
            };

            var data = new List <string[]>
            {
                new[] { "A number", "another number here", "#¤%i" },
                new[] { "1", "2", "3" },
                new[] { "2", "12", "14" },
                new[] { "3", "12", "13" },
                new[] { "4", "2", "3" }
            };
            var csvSettings = new CsvSettings(',')
            {
                HasHeader = true
            };
            var ctypes = new CsvColumnTypes(data, csvSettings);

            var tableName = dataStorage.SaveData(new IntPtr(10), data, ctypes);

            var result = dataStorage.ExecuteQueryToDataTable("SELECT * FROM " + tableName, new IntPtr(10));

            Assert.AreEqual("Anumber", result.Columns[0].ColumnName);

            string csv;

            using (var memStream = new MemoryStream())
            {
                csvSettings.GenerateToStream(result, memStream);
                csv = Encoding.UTF8.GetString(memStream.GetBuffer());
            }
            Assert.IsTrue(csv.StartsWith("Anumber,anothernumberhere,i"));
        }
Пример #15
0
        public void CanHandleNoHeaderDetectionWithDifferentRowLengths()
        {
            var data = new List <string[]>
            {
                new[] { "5", "7", "34" },
                new[] { "1", "2", "3", "12.2" },
                new[] { "2", "12", "14" },
                new[] { "3", "12", "13" },
                new[] { "4", "2", "3" }
            };

            var columnTypes = new CsvColumnTypes(data, null);

            this.DataStorage.SaveData(new IntPtr(11), data, columnTypes);
            this.DataStorage.SetActiveTab(new IntPtr(11));

            var result = this.DataStorage.ExecuteQuery("SELECT * FROM this", true);

            Assert.AreEqual(6, result.Count);
            Assert.AreEqual(result[0][3], "Col4");
            Assert.IsNull(result[1][3]);
            Assert.IsNotNull(result[2][3]);
            Assert.IsNull(result[3][3]);
        }
Пример #16
0
 protected void SaveUnsafeColumnNames(IntPtr bufferId, CsvColumnTypes columnTypes)
 {
     this.UnsafeColumnNames[bufferId] = columnTypes.ColumnUnsafeNames;
 }
Пример #17
0
        private void Parse(CsvSettings csvSettings, DiagnosticTimer watch, TextReader text, IntPtr bufferId)
        {
            IEnumerable <string[]> data;

            try
            {
                data = csvSettings.Parse(text);
            }
            catch (Exception e)
            {
                this.ErrorMessage("Error when parsing text:\n" + e.Message);
                return;
            }
            watch.Checkpoint("Parse");

            var count = 0;

            try
            {
                var       first         = true;
                const int partitionSize = DataSettings.ChunkSize;
                foreach (var chunk in data.Partition(partitionSize))
                {
                    if (first)
                    {
                        var wholeChunk  = chunk.ToList();
                        var columnTypes = new CsvColumnTypes(wholeChunk, csvSettings);
                        Main.DataStorage.SaveData(bufferId, wholeChunk, columnTypes);
                        first = false;
                        watch.Checkpoint("Saved first chunk to DB");
                    }
                    else
                    {
                        count += partitionSize;
                        var msg = $"Read lines: {count}";
                        this.UiThread(() => this.txbQuery.Text = msg);
                        Main.DataStorage.SaveMore(bufferId, chunk);
                    }
                }
            }
            catch (Exception ex)
            {
                this.ErrorMessage("Error when saving data to database:\n" + ex.Message);
                return;
            }
            watch.Checkpoint("Saved to DB");
            var selectQuery = "SELECT * FROM THIS";

            if (count > 10000)
            {
                selectQuery = Main.DataStorage.CreateLimitedSelect(10000);
            }
            this.UiThread(() => this.txbQuery.Text = selectQuery);
            this.Execute(bufferId, watch);

            var diagnostic = watch.LastCheckpoint("Resize");

            Trace.TraceInformation(diagnostic);
            if (Main.Settings.DebugMode)
            {
                this.Message(diagnostic);
            }
        }
Пример #18
0
        public override string SaveData(IntPtr bufferId, List <string[]> data, CsvColumnTypes columnTypes)
        {
            var tableName = GetOrAllocateTableName(bufferId);

            // Create SQL by string concat - look out for SQL injection! (although rather harmless since it's all your own data)
            var createQuery = new StringBuilder("CREATE TABLE [" + tableName + "] (");
            var first       = true;
            var columns     = columnTypes.Columns.Count;

            foreach (var column in columnTypes.Columns)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    createQuery.Append(", ");
                }

                if (Main.Settings.DetectDbColumnTypes)
                {
                    createQuery.Append('[').Append(column.Name).Append("] ");
                    createQuery.Append(ToLocalType(column));
                    createQuery.Append(column.Nullable ? " NULL" : " NOT NULL");
                }
                else
                {
                    var stringSize = Math.Max(1, column.MaxSize);
                    createQuery.AppendFormat("[{0}] NVARCHAR({1})", column.Name, stringSize > 2000?"MAX":stringSize.ToString());
                }
            }

            createQuery.Append(")");
            ExecuteNonQuery(createQuery.ToString());

            // Convert to datatable - bulk insert via datatable is fast
            var table = new DataTable();

            table.Columns.AddRange(columnTypes.Columns.Select(r => new DataColumn(r.Name)).ToArray());
            var datalist = columnTypes.HasHeader ? data.Skip(1) : data;

            foreach (var row in datalist)
            {
                var objects = new object[columns];
                for (var j = 0; j < row.Length; j++)
                {
                    objects[j] = columnTypes.Columns[j].Parse(row[j]);
                }
                table.Rows.Add(objects);
            }
            Trace.TraceInformation($"Converted {table.Rows.Count} rows to data table");

            using (var connection = new SqlConnection(_connectionString))
            {
                connection.Open();
                var transaction = connection.BeginTransaction();

                using (var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.Default, transaction))
                {
                    bulkCopy.BatchSize            = 100;
                    bulkCopy.DestinationTableName = tableName;
                    try
                    {
                        bulkCopy.WriteToServer(table);
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError($"Error in MSSQL bulk copy: {ex.Message}");
                        transaction.Rollback();
                        connection.Close();
                        throw;
                    }
                }

                transaction.Commit();
            }

            SaveUnsafeColumnNames(bufferId, columnTypes);
            return(tableName);
        }
Пример #19
0
 public abstract string SaveData(IntPtr bufferId, List <string[]> data, CsvColumnTypes columnTypes);
Пример #20
0
 protected void SaveUnsafeColumnNames(IntPtr bufferId, CsvColumnTypes columnTypes)
 {
     UnsafeColumnNames[bufferId] = columnTypes.Columns.Where(c => c.CreationString != c.Name)
                                   .ToDictionary(c => c.Name, c => c.CreationString);
 }
Пример #21
0
        /// <summary>
        /// Saves parsed data into SQLite database.
        /// This function currently does a little too much, it detects headers and column types (which it then pretty much ignore)
        /// </summary>
        /// <param name="bufferId"></param>
        /// <param name="data"></param>
        /// <param name="columnTypes"></param>
        /// <returns></returns>
        public override string SaveData(IntPtr bufferId, List <string[]> data, CsvColumnTypes columnTypes)
        {
            string tableName = GetOrAllocateTableName(bufferId);

            // Create SQL by string concat - look out for SQL injection! (although rather harmless since it's all your own data)
            var createQuery = new StringBuilder("CREATE TABLE [" + tableName + "] (");

            bool first = true;

            foreach (var column in columnTypes.Columns)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    createQuery.Append(", ");
                }

                if (Main.Settings.DetectDbColumnTypes)
                {
                    createQuery.Append('[').Append(column.Name).Append("] ");
                    switch (column.DataType)
                    {
                    case ColumnType.Empty:
                        createQuery.Append(" CHAR");
                        break;

                    case ColumnType.Integer:
                        createQuery.Append(" INT");
                        break;

                    case ColumnType.Decimal:
                        createQuery.Append(" FLOAT");
                        break;

                    case ColumnType.String:
                        createQuery.Append(" CHAR");
                        break;
                    }
                    createQuery.Append(column.Nullable ? " NULL" : " NOT NULL");
                }
                else
                {
                    createQuery.AppendFormat("[{0}] CHAR", column.Name);
                }
            }

            createQuery.Append(")");
            ExecuteNonQuery("BEGIN EXCLUSIVE");
            ExecuteNonQuery(createQuery.ToString());
            ExecuteNonQuery("END");

            var columns     = columnTypes.Columns.Count;
            var insertQuery = new StringBuilder("INSERT INTO ");

            insertQuery.Append(tableName);
            insertQuery.Append(" VALUES (?");
            for (int i = 1; i < columns; i++)
            {
                insertQuery.Append(",?");
            }
            insertQuery.Append(")");

            ExecuteNonQuery("BEGIN EXCLUSIVE");
            var stmt = new SQLiteVdbe(Db, insertQuery.ToString());

            first = true;
            foreach (var stringse in data)
            {
                if (first)
                {
                    first = false;
                    if (columnTypes.HasHeader)
                    {
                        continue;
                    }
                }
                stmt.Reset();
                int index = 0;
                foreach (var s in stringse)
                {
                    stmt.BindText(++index, s);
                }
                while (index < columns)
                {
                    stmt.BindText(++index, null);
                }
                stmt.ExecuteStep();
            }
            stmt.Close();
            ExecuteNonQuery("END");

            SaveUnsafeColumnNames(bufferId, columnTypes);
            return(tableName);
        }