/// <summary> /// creates a database visualizer, must be disposed to release resources /// </summary> /// <param name="db">database</param> /// <param name="query">parsed sql query</param> /// <param name="options">visualize options</param> public DbVisualizer(CsvDb db, DbQuery query, DbVisualize options = DbVisualize.Paged) { //reader = DbRecordReader.Create(db, query); handler = new DbQueryHandler(db, query); Options = options; }
/// <summary> /// creates a default sql query validator for a Csv database /// </summary> /// <param name="db">database</param> public CsvDbDefaultValidator(CsvDb db) { if ((Database = db) == null) { throw new ArgumentException("database undefined for validator"); } }
/// <summary> /// Creates a database generator for everything, generate text data and compiling /// </summary> /// <param name="db">database</param> /// <param name="zipfilepath">zZIP file with database data</param> /// <param name="removeAll">start from scratch, clean database directory</param> public DbGenerator(CsvDb db, string zipfilepath, bool removeAll = true) : this(db, removeAll : removeAll) { if (!io.File.Exists(ZipFile = zipfilepath) || !zipfilepath.EndsWith(".zip")) { throw new ArgumentException($"ZIP file path doesnot exists: {zipfilepath}"); } }
/// <summary> /// Creates a database generator for compiling only /// </summary> /// <param name="db">database</param> /// <param name="removeAll">start from scratch, clean database directory</param> public DbGenerator(CsvDb db, bool removeAll = true) { if ((Database = db) == null) { throw new ArgumentException($"Csv Database not provided"); } ZipFile = null; Sufix = IsBinary ? ".bin" : String.Empty; // remove all but the __tables.json file //this's for cleaning, start from scratch }
public DbClassGenerator(CsvDb db) { if ((Database = db) == null) { throw new ArgumentException("cannot generate database class(es) without a database"); } Generated = io.File.Exists(Path = $"{db.BinaryPath}{(AssemblyName = $"{db.Name}.dll")}"); tableTypes = new Dictionary <string, DbClass>(); if (!Compile()) { throw new ArgumentException($"cnnot compile database: {db.Name}"); } }
/// <summary> /// Creates a database data table reader /// </summary> /// <param name="db">database</param> /// <param name="table">table</param> /// <param name="handler">query handler</param> /// <returns></returns> public static DbTableDataReader Create(CsvDb db, DbTable table, DbQueryHandler handler = null) { if (db == null || table == null) { return(null); } if ((db.Flags & DbSchemaConfigType.Binary) != 0) { return(new DbTableBinDataReader(table, handler)); } else { return(new DbTableCsvDataReader(table, handler)); } }
static CsvDb.CsvDb OpenDatabase(Config.ConfigSettings appConfig, string dbName = null, bool logTimes = true) { var basePath = appConfig.Database.BasePath; if (string.IsNullOrWhiteSpace(dbName)) { dbName = "data-bin\\"; } string rootPath = $"{basePath}{dbName}"; if (!rootPath.EndsWith('\\')) { rootPath += "\\"; } System.Diagnostics.Stopwatch sw = null; if (logTimes) { sw = new System.Diagnostics.Stopwatch(); sw.Start(); } CsvDb.CsvDb db = null; try { db = new CsvDb.CsvDb(rootPath); if (logTimes) { sw.Stop(); Console.WriteLine(" opened on {0} ms", sw.ElapsedMilliseconds); } } catch (Exception ex) { db = null; Console.WriteLine($"error: {ex.Message}"); } return(db); }
/// <summary> /// /// </summary> /// <param name="db"></param> /// <param name="query"></param> public DbQueryHandler(CsvDb db, DbQuery query) { if ((Database = db) == null || (Query = query) == null) { throw new ArgumentException("Cannot create query executer handler"); } //set index transformers to table columns SelectIndexColumns = new SelectColumnHandler(query.Select.Columns); //WhereColumns = new Dictionary<string, DbColumn>(); TableReaders = new List <DbTableDataReader>(); //get table data reader from FROM tables too, in case WHERE has no column foreach (var table in query.From) { if (!TableReaders.Any(t => t.Table.Name == table.Name)) { TableReaders.Add(DbTableDataReader.Create(db, table.Name, this)); } } }
//public static CompilerResults CreateType(string name, IDictionary<string, Type> props) //{ // var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } }); // var parameters = new CompilerParameters(new[] { // "mscorlib.dll", // "System.Core.dll" // }, "CsvDb.Dynamic.dll", false); // parameters.GenerateExecutable = false; // var compileUnit = new CodeCompileUnit(); // var ns = new CodeNamespace("CsvDb.Dynamic"); // compileUnit.Namespaces.Add(ns); // ns.Imports.Add(new CodeNamespaceImport("System")); // var classType = new CodeTypeDeclaration(name); // classType.Attributes = MemberAttributes.Public; // ns.Types.Add(classType); // foreach (var prop in props) // { // var fieldName = "_" + prop.Key; // var field = new CodeMemberField(prop.Value, fieldName); // classType.Members.Add(field); // var property = new CodeMemberProperty(); // property.Attributes = MemberAttributes.Public | MemberAttributes.Final; // property.Type = new CodeTypeReference(prop.Value); // property.Name = prop.Key; // property.GetStatements.Add( // new CodeMethodReturnStatement( // new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName))); // property.SetStatements.Add( // new CodeAssignStatement(new CodeFieldReferenceExpression( // new CodeThisReferenceExpression(), fieldName), new CodePropertySetValueReferenceExpression())); // classType.Members.Add(property); // } // var results = csc.CompileAssemblyFromDom(parameters, compileUnit); // results.Errors.Cast<CompilerError>().ToList().ForEach(error => Console.WriteLine(error.ErrorText)); // return results; //} /// <summary> /// testings /// </summary> /// <param name="db"></param> /// <returns></returns> public static Assembly CreateDbClasses(CsvDb db) { try { var sb = new StringBuilder(); sb.AppendLine("using System;"); sb.AppendLine("using System.Collections.Generic;"); sb.AppendLine("using CsvDb;"); sb.AppendLine(); sb.AppendLine("namespace CsvDb.Dynamic"); sb.AppendLine("{"); //interface sb.AppendLine(@" public interface IDbColumnClass { bool Unique { get; } IEnumerable<KeyValuePair<string,int>> Keys { get; } DbTable Table { get; } } "); foreach (var table in db.Tables) { sb.AppendLine($" public class {table.Name}: IDbColumnClass"); sb.AppendLine(" {"); //column properties foreach (var col in table.Columns) { sb.AppendLine($" public {col.Type} {col.Name} {{get; set; }}"); } //custom properties var keys = table.Columns.Where(col => col.Key).ToList(); var oneKey = keys.Count == 1; sb.AppendLine($" public bool Unique => {oneKey.ToString().ToLower()};"); var keyStr = String.Join(", ", keys.Select(col => $"new KeyValuePair<string,int>(\"{col.Name}\", {col.Index} )")); sb.AppendLine(@" public IEnumerable<KeyValuePair<string,int>> Keys { get { return new KeyValuePair<string,int>[] { " + keyStr + @" }; } }" ); sb.AppendLine(" public DbTable Table { get; private set; }"); //link method sb.AppendLine(" public void Link(DbTable table)"+ @" { Table = table; }" ); sb.AppendLine(" }"); sb.AppendLine(""); } sb.AppendLine("}"); Console.WriteLine($"class(es) to be generated:\r\n{sb.ToString()}"); SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sb.ToString()); string assemblyName = Path.GetRandomFileName(); var assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location); MetadataReference[] references = new MetadataReference[] { //MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "mscorlib.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Runtime.dll")), MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location), //MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location), MetadataReference.CreateFromFile(typeof(CsvDb).Assembly.Location) // Path.Combine( Environment.CurrentDirectory,"CsvDb.dll")) }; CSharpCompilation compilation = CSharpCompilation.Create( assemblyName, syntaxTrees: new[] { syntaxTree }, references: references, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); using (var ms = new MemoryStream()) { EmitResult result = compilation.Emit(ms); if (!result.Success) { IEnumerable <Diagnostic> failures = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error); foreach (Diagnostic diagnostic in failures) { Console.Error.WriteLine("{0}: {1}", diagnostic.Id, diagnostic.GetMessage()); } return(null); } else { ms.Seek(0, SeekOrigin.Begin); Assembly assembly = Assembly.Load(ms.ToArray()); //Type type = assembly.GetType("RoslynCompileSample.Writer"); //object obj = Activator.CreateInstance(type); //type.InvokeMember("Write", // BindingFlags.Default | BindingFlags.InvokeMethod, // null, // obj, // new object[] { "Hello World" }); return(assembly); } } } catch (Exception ex) { Console.WriteLine($"class compile error:\r\n{ex.Message}"); return(null); } }
static bool SqlQueryExecute() { var availableDatabases = new string[] { "data-full", //"data", //"data-light", //"data-extra-light", "data-bin" }; var sw = new System.Diagnostics.Stopwatch(); CsvDb.CsvDb db = null; bool IsObjectNull(object obj, string msg, bool testFor = true) { if ((obj == null) == testFor) { con.WriteLine(msg); return(true); } return(false); } object CreateClass(Type type, object[] parameters) { if (type == null) { return(null); } try { object obj = Activator.CreateInstance(type, parameters ?? new object[] { }); return(obj); } catch (Exception ex) { con.WriteLine($"error: {ex.Message}"); return(null); } } //Action displayHelp = () => void displayHelp() { con.WriteLine(" ┌────────────────────────────────┬────────────────────────────────┬──────────────────────────────────┐"); con.WriteLine(" │ Help h help │ Clear c clear │ Quit q quit │"); con.WriteLine(" ├────────────────────────────────┴────────┬───────────────────────┴──────────────────────────────────┤"); con.WriteLine(" │ Mount database m|use|mount 'db name' │ Display database(s) display │"); con.WriteLine(" │ Kill/close database k kill │ Display Tables Info display /tables │"); con.WriteLine(" │ Search Database search │ Display Index Tree Structure │"); con.WriteLine(" │ Eexecute Queries execute │ display 'table.column' /i │"); con.WriteLine(" │ Xtreme class x │ Display Index Tree Node Structure │"); con.WriteLine(" │ │ display 'table.column' /n │"); con.WriteLine(" │ │ Non-indexed search │"); con.WriteLine(" │ │ display 'table.column' /oper:> constant │"); con.WriteLine(" │ │ Page display 'table.column' /p /offset:int │"); con.WriteLine(" │ │ Visualize recs display 'table.column' /r count │"); con.WriteLine(" ├─────────────────────────────────────────┴──────────────────────────────────────────────────────────┤"); con.WriteLine(" │ SELECT [*] | [t0.col0, t0.col1,..] | [COUNT|AVG|SUM](col) │"); con.WriteLine(" │ FROM table [t0] │"); con.WriteLine(" │ WHERE │"); con.WriteLine(" │ [INNER|CROSS|(LEFT|RIGHT|FULL) OUTER] JOIN table0 t0 ON expr:<left> oper <right> │"); con.WriteLine(" └────────────────────────────────────────────────────────────────────────────────────────────────────┘"); // ORDER BY // SELECT * FROM [table] t // WHERE t.Name == "" // // *\t[table]\t[[column],==,[value]>] //SELECT route_id, rout_short_name FROM routes r // WHERE r.agency_id == "NJT" AND // r.route_type == 2 // route_id,route_short_name\t[routes]\t[agency_id],==,"NJT"\tAND\t[route_type],==,2 // SELECT * | column0,column1,... // | a.agency_id, b.serice_id,... // // FROM table [descriptor] // // WHERE [descriptor].column = constant AND|OR ... // SKIP number // LIMIT number // } System.Reflection.Assembly assembly = null; var nl = Environment.NewLine; bool end = false; //this's the matched rule CommandArgRulesAction matchedRule = null; //con.TreatControlCAsInput = true; var ruleCollection = new CommandArgRules( new CommandArgRulesAction[] { new CommandArgRulesAction( CommandArgRule.Command("q", "quit"), () => { end = true; if (db != null) { db.Dispose(); } } ), new CommandArgRulesAction(CommandArgRule.Command("h", "help"), () => displayHelp()), new CommandArgRulesAction(CommandArgRule.Command("c", "clear"), () => con.Clear()), new CommandArgRulesAction( CommandArgRule.Command("k", "kill"), () => { if (!IsObjectNull(db, $" no database to close")) { con.WriteLine($" closing database [{db.Name}]"); db.Dispose(); db = null; } } ), new CommandArgRulesAction( CommandArgRule.Command("m", "mount", "use"), () => { //m "data-bin" if (!IsObjectNull(db, $"\r\nplease first unmount current database", testFor: false)) { if ((db = OpenDatabase( dbName: matchedRule[1].Arg.GetKey(), logTimes: true)) != null) { con.WriteLine($"\r\nUsing database: {db.Name}{db.IsBinary.IfTrue(" [Binary]")}{db.IsCsv.IfTrue(" [Csv]")}"); } } } ).Add(CommandArgRule.KeyTypeAs(CommandArgItemType.Identifier | CommandArgItemType.String)), new CommandArgRulesAction( CommandArgRule.Command("s", "search"), () => { if (!IsObjectNull(db, " there's no database in use")) { con.Write(" query >"); var query = con.In.ReadLine(); con.WriteLine(); sw.Restart(); var dbQuery = DbQuery.Parse(query, new CsvDbDefaultValidator(db)); sw.Stop(); con.WriteLine(" query parsed on {0} ms", sw.ElapsedMilliseconds); con.WriteLine($" {dbQuery}"); var visualizer = new DbVisualizer( db, dbQuery, DbVisualize.Paged | DbVisualize.UnderlineHeader | DbVisualize.Framed | DbVisualize.LineNumbers); visualizer.Display(); visualizer.Dispose(); } } ), new CommandArgRulesAction( CommandArgRule.Command("execute"), () => { if (!IsObjectNull(db, " there's no database in use")) { con.WriteLine("Execute database queries:\r\n -empty query ends"); string query = null; bool finish = false; do { con.Write("\r\n query: "); query = con.ReadLine(); if (!(finish = String.IsNullOrWhiteSpace(query))) { try { sw.Restart(); var dbQuery = DbQuery.Parse(query, new CsvDbDefaultValidator(db)); sw.Stop(); con.WriteLine(" query parsed on {0} ms", sw.ElapsedMilliseconds); con.WriteLine($" {dbQuery}"); } catch (Exception ex) { con.WriteLine($" error: {ex.Message}"); } } } while (!finish); } } ), new CommandArgRulesAction( CommandArgRule.Command("x"), () => { if (!IsObjectNull(db, " there's no database in use")) { con.Write("\r\n database table as class: "); var tbleName = con.ReadLine(); DbTable table = db.Table(tbleName); // if (table == null) { con.WriteLine($"cannot find table [{tbleName}]"); } else { if (assembly == null) { assembly = Utils.CreateDbClasses(db); if (assembly == null) { con.WriteLine("Cannot generate database table classes"); } else { con.WriteLine("database table classes generated succesfully!"); } } if (assembly != null) { //I can compile code once and load assembly at start // just recompile when database table changes //var an = System.Reflection.AssemblyName.GetAssemblyName(filePath); //System.Reflection.Assembly.Load(an); //AppDomain.CurrentDomain.Load(assembly.GetName()); //get it OK! //Type type = assembly.GetType($"CsvDb.Dynamic.{tbleName}"); //object obj = Activator.CreateInstance(type); //this was a test, constructor must be parameterless so CsvHelper can create it Type dynTbleClass = assembly.GetType($"CsvDb.Dynamic.{tbleName}"); object obj = CreateClass( dynTbleClass, new object[] { //table } ); var mthd = dynTbleClass.GetMethod("Link"); mthd.Invoke(obj, new object[] { table }); //now I can use CsvHelper to parse CSV rows using this classes if needed //don't get it var classType = Type.GetType($"CsvDb.Dynamic.{tbleName}"); con.WriteLine("ok"); } } } } ), new CommandArgRulesAction( CommandArgRule.Command("display"), () => { //compare //display "routes.route_id" /oper:>= 250 if (!IsObjectNull(db, " there's no database in use")) { var dbTblCol = matchedRule[1].Arg.GetKey(); var operArg = matchedRule[2].Arg as CommandArgKeypair; var constArg = matchedRule[3].Arg; DbColumn column = null; if ((column = db.Index(dbTblCol)) != null && operArg.Value.TryParseToken(out TokenType token)) { var reader = DbTableDataReader.Create(db, column.Table); object value = column.TypeEnum.ToObject(constArg.Key); var collection = (IEnumerable <int>)Utils.CallGeneric( reader, nameof(DbTableDataReader.Compare), column.TypeEnum, new object[] { column, token, value }, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance ); var lista = collection.ToList(); con.WriteLine($" ({lista.Count}) match(es)"); } } }
/// <summary> /// Creates a database table data reader /// </summary> /// <param name="db">database</param> /// <param name="tableName">table name</param> /// <param name="handler">query handler</param> /// <returns></returns> public static DbTableDataReader Create(CsvDb db, string tableName, DbQueryHandler handler = null) { return(Create(db, db?.Table(tableName), handler)); }
/// <summary> /// creates a database visualizer, must be disposed to release resources /// </summary> /// <param name="db">database</param> /// <param name="query">query string text</param> /// <param name="validator">query validator</param> /// <param name="options">visualize options</param> public DbVisualizer(CsvDb db, string query, IQueryValidation validator, DbVisualize options = DbVisualize.Paged) : this(db, DbQuery.Parse(query, validator), options) { }
public Visualizer(db.CsvDb db) { Database = db; }
public DbIndexItems(CsvDb db, string tableName, string columnName) { if ((Database = db) == null) { throw new ArgumentException("Database is undefined"); } Index = Database.Index(tableName, columnName); if (Index == null) { throw new ArgumentException($"Column [{columnName}] does not exists in table [{tableName}]."); } //load structure PathToItems = io.Path.Combine(Database.BinaryPath, $"{Index.Indexer}.bin"); if (!io.File.Exists(PathToItems)) { throw new ArgumentException($"Could not find indexer in database"); } Hash = new Dictionary <int, MetaItemsPage <T> >(); //read main structure of item pages using (reader = new io.BinaryReader(io.File.OpenRead(PathToItems))) { //Header PageCount = reader.ReadInt32(); Int32 keyTypeValue = reader.ReadInt32(); KeyType = (DbColumnType)keyTypeValue; //read all pages main info for (var pi = 0; pi < PageCount; pi++) { var flags = reader.ReadInt32(); var pageType = flags & 0b011; if (pageType != Consts.BTreePageItemsFlag) { throw new ArgumentException("Invalid indexer"); } var uniqueKeyValue = (flags & Consts.BTreeUniqueKeyValueFlag) != 0; var offset = reader.ReadInt32(); var pageSize = reader.ReadInt32(); var itemsCount = reader.ReadInt32(); //skip keys and values //sizeof: flags, offset, pageSize, itemsCount var sizeOfInt32 = sizeof(Int32); var dataStart = 4 * sizeOfInt32; var skip = pageSize - dataStart; reader.BaseStream.Seek(skip, io.SeekOrigin.Current); var page = new MetaItemsPage <T>() { Flags = flags, UniqueKeyValue = uniqueKeyValue, Offset = offset, PageSize = pageSize, ItemsCount = itemsCount, DataStart = dataStart, Parent = this, Frequency = 0.0, Number = pi }; //add to hash dictionary for fast retrieval Hash.Add(page.Offset, page); } } //update item page count Index.ItemPages = Hash.Count; }
static bool CsvToBinTable(CsvDb.CsvDb db, string tableName) { ////FIND THIS //// "stops" table row count csv doesn't match with bin file //var showPer = tableName.StartsWith('-'); //if (showPer) //{ // tableName = tableName.Substring(1); //} //var table = db.Table(tableName); //if (table == null) //{ // Console.WriteLine($"cannot find table: {tableName} in database"); // return false; //} ////get file size of csv file //var csvPath = io.Path.Combine(db.BinaryPath, $"{table.Name}.csv"); //var csvFileInfo = new io.FileInfo(csvPath); //var binPath = io.Path.Combine(db.BinaryPath, $"{table.Name}.bin"); //if (!showPer) //{ // //calculate bytes needed to store null flags for every column in every record // // this way reduce space for many null values on columns // // and support nulls for any field type // int bytes = Math.DivRem(table.Columns.Count, 8, out int remainder); // int bits = bytes * 8 + remainder; // UInt64 mask = (UInt64)Math.Pow(2, bits - 1); // if (remainder != 0) // { // bytes++; // } // var stream = new io.MemoryStream(); // var bufferWriter = new io.BinaryWriter(stream); // using (var writer = new io.BinaryWriter(io.File.Create(binPath))) // //using (var reader = new io.StreamReader(csvPath)) // { // //placeholder for row count // Int32 value = 0; // writer.Write(value); // //write mask 32-bits unsigned int 64 bits UInt64, so max table columns is 64 // writer.Write(mask); // //var buffer = new io.MemoryStream(5 * 1024); // var queryText = $"SELECT * FROM {table.Name}"; // var reader = DbRecordReader.Create(db, DbQuery.Parse(queryText, new CsvDbDefaultValidator(db))); // int rowCount = 0; // foreach (var record in reader.Rows()) // { // rowCount++; // //start with mask, first column, leftmost // UInt64 flags = 0; // // // var columnBit = mask; // stream.Position = 0; // for (var index = 0; index < reader.ColumnCount; index++) // { // string textValue = (string)record[index]; // var colType = reader.ColumnTypes[index]; // if (textValue == null) // { // //signal only the null flag as true // flags |= columnBit; // } // else // { // switch (colType) // { // case DbColumnType.String: // bufferWriter.Write(textValue); // break; // case DbColumnType.Char: // char charValue = (char)0; // if (!Char.TryParse(textValue, out charValue)) // { // throw new ArgumentException($"unable to cast: {textValue} to: {colType}"); // } // //write // bufferWriter.Write(charValue); // break; // case DbColumnType.Byte: // byte byteValue = 0; // if (!Byte.TryParse(textValue, out byteValue)) // { // throw new ArgumentException($"unable to cast: {textValue} to: {colType}"); // } // //write // bufferWriter.Write(byteValue); // break; // case DbColumnType.Int16: // Int16 int16Value = 0; // if (!Int16.TryParse(textValue, out int16Value)) // { // throw new ArgumentException($"unable to cast: {textValue} to: {colType}"); // } // //write // bufferWriter.Write(int16Value); // break; // case DbColumnType.Int32: // Int32 int32Value = 0; // if (!Int32.TryParse(textValue, out int32Value)) // { // throw new ArgumentException($"unable to cast: {textValue} to: {colType}"); // } // //write // bufferWriter.Write(int32Value); // break; // case DbColumnType.Single: // float floatValue = 0.0f; // if (!float.TryParse(textValue, out floatValue)) // { // throw new ArgumentException($"unable to cast: {textValue} to: {colType}"); // } // //write // bufferWriter.Write(floatValue); // break; // case DbColumnType.Double: // Double doubleValue = 0.0; // if (!Double.TryParse(textValue, out doubleValue)) // { // throw new ArgumentException($"unable to cast: {textValue} to: {colType}"); // } // //write // bufferWriter.Write(doubleValue); // break; // case DbColumnType.Decimal: // Decimal decimalValue = 0; // if (!Decimal.TryParse(textValue, out decimalValue)) // { // throw new ArgumentException($"unable to cast: {textValue} to: {colType}"); // } // //write // bufferWriter.Write(decimalValue); // break; // default: // throw new ArgumentException($"unsupported type: {colType}"); // } // } // //shift right column Bit until it reaches 0 -the last column rightmost // columnBit >>= 1; // } // if (columnBit != 0) // { // Console.WriteLine("Error on column bit flags"); // } // //write true binary record // var flagsBuffer = BitConverter.GetBytes(flags); // writer.Write(flagsBuffer, 0, bytes); // //write non-null records // var recBinary = stream.ToArray(); // writer.Write(recBinary, 0, recBinary.Length); // } // //write row count // writer.BaseStream.Position = 0; // writer.Write(rowCount); // Console.WriteLine($"writen {rowCount} row(s)"); // reader.Dispose(); // } //} //var binFileInfo = new io.FileInfo(binPath); //var percent = ((double)binFileInfo.Length / csvFileInfo.Length); //Console.WriteLine("binary file is {0:P2}", percent); return(true); }
public DbIndexTree(CsvDb db, string tableName, string columnName) : this(db?.Index(tableName, columnName)) { }