/// <summary>Creates a new table with the specified layout.</summary>
        /// <typeparam name="TStruct">Row structure type.</typeparam>
        /// <param name="database">The database to create the table at.</param>
        /// <param name="tableName">The name of the table.</param>
        /// <param name="flags">Flags for table creation.</param>
        /// <param name="excludedFields">Fields at <typeparamref name="TStruct" /> to be excluded.</param>
        /// <returns>Returns an <see cref="ITable{TStruct}" /> instance for the specified table.</returns>
        public static ITable <TStruct> CreateTable <TStruct>(this IDatabase database, string tableName = null, TableFlags flags = default,
                                                             params string[] excludedFields)
            where TStruct : struct
        {
            var layout = RowLayout.CreateTyped(typeof(TStruct), tableName, database.Storage, excludedFields);
            var table  = database.CreateTable(layout, flags);

            return(new Table <TStruct>(table));
        }
示例#2
0
        /// <summary>Reads a whole list from the specified csv file.</summary>
        /// <param name="properties">Properties of the csv file.</param>
        /// <param name="fileName">File name of the csv file.</param>
        /// <returns>Returns a new <see cref="List{TStruct}" />.</returns>
        /// <typeparam name="TStruct">Structure type.</typeparam>
        public static List <TStruct> ReadList <TStruct>(CsvProperties properties, string fileName)
            where TStruct : struct
        {
            var layout = RowLayout.CreateTyped(typeof(TStruct));

            using (var reader = new CsvReader(layout, fileName, properties))
            {
                return(reader.ReadList <TStruct>());
            }
        }
示例#3
0
        /// <summary>Parses a single row of data from the specified string.</summary>
        /// <typeparam name="TStruct">The structure type.</typeparam>
        /// <param name="data">The buffer to parse.</param>
        /// <param name="provider">The format provider (optional).</param>
        /// <returns>Returns a new structure.</returns>
        public static TStruct ParseRow <TStruct>(string data, IFormatProvider provider)
            where TStruct : struct
        {
            var properties = CsvProperties.Default;

            if (provider != null)
            {
                properties.Format = provider;
            }

            var layout = RowLayout.CreateTyped(typeof(TStruct));
            var row    = ParseRow(properties, layout, data);

            return(row.GetStruct <TStruct>(layout));
        }
示例#4
0
        /// <summary>
        /// Creates a new table with the specified layout.
        /// </summary>
        /// <typeparam name="TKey">Key identifier type.</typeparam>
        /// <typeparam name="TStruct">Row structure type.</typeparam>
        /// <param name="database">The database to create the table at.</param>
        /// <param name="tableName">The name of the table.</param>
        /// <param name="flags">Flags for table creation.</param>
        /// <param name="excludedFields">Fields at <typeparamref name="TStruct"/> to be excluded.</param>
        /// <returns>Returns an <see cref="ITable{TKey, TStruct}"/> instance for the specified table.</returns>
        public static ITable <TKey, TStruct> CreateTable <TKey, TStruct>(this IDatabase database, string tableName = null, TableFlags flags = default,
                                                                         params string[] excludedFields)
            where TKey : IComparable <TKey>
            where TStruct : struct
        {
            if (database == null)
            {
                throw new ArgumentNullException(nameof(database));
            }

            var layout = RowLayout.CreateTyped(typeof(TStruct), tableName, database.Storage, excludedFields);
            var table  = database.CreateTable(layout, flags);

            return(new Table <TKey, TStruct>(table));
        }
示例#5
0
        /// <summary>Creates a new csv file with the specified name and writes the whole table.</summary>
        /// <param name="rows">Rows to write to the csv file.</param>
        /// <param name="fileName">File name of the csv file.</param>
        /// <param name="properties">Properties of the csv file.</param>
        /// <typeparam name="TStruct">Structure type.</typeparam>
        public static void WriteRows <TStruct>(IEnumerable <TStruct> rows, string fileName, CsvProperties properties = default)
            where TStruct : struct
        {
            var layout = RowLayout.CreateTyped(typeof(TStruct));
            var writer = new CsvWriter(layout, fileName, properties);

            try
            {
                writer.Write(rows);
            }
            finally
            {
                writer.Close();
            }
        }
        /// <summary>Opens or creates the table with the specified type.</summary>
        /// <typeparam name="TStruct">Row structure type.</typeparam>
        /// <param name="database">The database instance.</param>
        /// <param name="tableName">The name of the table.</param>
        /// <param name="flags">Flags for table loading.</param>
        /// <param name="excludedFields">Fields at <typeparamref name="TStruct" /> to be excluded.</param>
        /// <returns>Returns an <see cref="ITable{TValue}" /> instance for the specified table.</returns>
        public static ITable <TStruct> GetTable <TStruct>(this IDatabase database, string tableName = null, TableFlags flags = default,
                                                          params string[] excludedFields)
            where TStruct : struct
        {
            var layout = RowLayout.CreateTyped(typeof(TStruct), tableName, database.Storage, excludedFields);

            if (flags.HasFlag(TableFlags.IgnoreMissingFields))
            {
                return(new Table <TStruct>(database.GetTable(tableName ?? layout.Name)));
            }

            var table = database.GetTable(layout, flags);

            return(new Table <TStruct>(table));
        }
示例#7
0
        /// <summary>Initializes a new instance of the <see cref="Table{TStruct}" /> class.</summary>
        /// <param name="table">The table instance to wrap.</param>
        public Table(ITable table)
        {
            BaseTable = table ?? throw new ArgumentNullException(nameof(table));
            if (table.Flags.HasFlag(TableFlags.IgnoreMissingFields))
            {
                var layout = RowLayout.CreateTyped(typeof(TStruct));
                Layout = layout.GetMatching(BaseTable.Layout, table.Flags);
            }
            else
            {
                Layout = RowLayout.CreateTyped(typeof(TStruct));
                RowLayout.CheckLayout(Layout, BaseTable.Layout);
            }

            BaseTable.UseLayout(Layout);
        }
        /// <summary>Initializes a new instance of the <see cref="Table{TKey, TStruct}" /> class.</summary>
        /// <param name="table">The table instance to wrap.</param>
        public Table(ITable table)
        {
            BaseTable = table ?? throw new ArgumentNullException(nameof(table));

            if (table.Flags.HasFlag(TableFlags.IgnoreMissingFields))
            {
                var comparison = table.GetFieldNameComparison();
                var result     = new List <IFieldProperties>();
                var layout     = RowLayout.CreateTyped(typeof(TStruct));
                foreach (var field in layout)
                {
                    var match = BaseTable.Layout.FirstOrDefault(f => f.Equals(field, comparison));
                    if (match == null)
                    {
                        throw new InvalidDataException($"Field {field} cannot be found at table {BaseTable}");
                    }

                    var target = field.Clone();
                    target.Index = match.Index;
                    result.Add(target);
                }

                if (result.Select(i => i.Index).Distinct().Count() != result.Count)
                {
                    throw new Exception("Index assignment is not distinct!");
                }
                Layout = new(table.Name, result.OrderBy(i => i.Index).ToArray(), typeof(TStruct));
            }
            else
            {
                Layout = RowLayout.CreateTyped(typeof(TStruct));
                RowLayout.CheckLayout(Layout, BaseTable.Layout);
            }

            var keyField  = Layout.Identifier.Single();
            var dbValue   = (IConvertible)Activator.CreateInstance(keyField.ValueType);
            var converted = (IConvertible)dbValue.ToType(typeof(TKey), CultureInfo.InvariantCulture);
            var test      = (IConvertible)converted.ToType(keyField.ValueType, CultureInfo.InvariantCulture);

            if (!Equals(test, dbValue))
            {
                throw new ArgumentException($"Type (local) {nameof(TKey)} can not be converted from and to (database) {keyField.ValueType}!");
            }

            KeyField = keyField;
            table.UseLayout(Layout);
        }
        /// <summary>Initializes a new instance of the <see cref="Table{TKey, TStruct}" /> class.</summary>
        /// <param name="table">The table instance to wrap.</param>
        public Table(ITable table)
        {
            BaseTable = table;
            var layout = RowLayout.CreateTyped(typeof(TStruct));

            if (table.Flags.HasFlag(TableFlags.IgnoreMissingFields))
            {
                var result = new List <IFieldProperties>();
                foreach (var field in layout)
                {
                    var match = table.Layout.FirstOrDefault(f => f.Equals(field));
                    if (match == null)
                    {
                        throw new InvalidDataException($"Field {field} cannot be found at table {table}");
                    }

                    var target = match.Clone();
                    target.FieldInfo = field.FieldInfo;
                    result.Add(target);
                }

                layout = new RowLayout(table.Name, result.ToArray(), typeof(TStruct));
            }
            else
            {
                RowLayout.CheckLayout(layout, table.Layout);
            }

            Layout = layout;
            var keyField = layout.Identifier.Single();

            if (keyField.ValueType != typeof(TKey))
            {
                throw new ArgumentException($"{nameof(TKey)} needs to be of type {keyField.ValueType}!");
            }

            KeyField = keyField;
            table.UseLayout(layout);
        }
示例#10
0
        /// <summary>Reads the whole file to a new list.</summary>
        /// <typeparam name="TStruct">Structure type.</typeparam>
        /// <returns>A new <see cref="List{TStruct}" />.</returns>
        public List <TStruct> ReadList <TStruct>()
            where TStruct : struct
        {
            var layout = RowLayout.CreateTyped(typeof(TStruct));

            RowLayout.CheckLayout(Layout, layout);
            if (!Layout.IsTyped)
            {
                Layout = layout;
            }

            var result = new List <TStruct>();

            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                var row = ReadCurrentRow(reader, Version, layout);
                if (row != null)
                {
                    result.Add(row.GetStruct <TStruct>(layout));
                }
            }

            return(result);
        }