commit 1f1079a71cfec7425e162cfde20384de41efb7ab Author: Sean Kessler Date: Fri Feb 23 00:41:24 2024 -0500 Initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3e759b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,330 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ diff --git a/App.config b/App.config new file mode 100644 index 0000000..db20d91 --- /dev/null +++ b/App.config @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Assemblies/MySql.Data.dll b/Assemblies/MySql.Data.dll new file mode 100644 index 0000000..2fd44b9 Binary files /dev/null and b/Assemblies/MySql.Data.dll differ diff --git a/Assemblies/MySql.Data.dll.old b/Assemblies/MySql.Data.dll.old new file mode 100644 index 0000000..20fe8e6 Binary files /dev/null and b/Assemblies/MySql.Data.dll.old differ diff --git a/Assemblies/System.Runtime.CompilerServices.Unsafe.dll b/Assemblies/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000..de9e124 Binary files /dev/null and b/Assemblies/System.Runtime.CompilerServices.Unsafe.dll differ diff --git a/Assemblies/System.Runtime.CompilerServices.Unsafe.xml b/Assemblies/System.Runtime.CompilerServices.Unsafe.xml new file mode 100644 index 0000000..6a7cfcf --- /dev/null +++ b/Assemblies/System.Runtime.CompilerServices.Unsafe.xml @@ -0,0 +1,200 @@ + + + System.Runtime.CompilerServices.Unsafe + + + + Contains generic, low-level functionality for manipulating pointers. + + + Adds an element offset to the given reference. + The reference to add the offset to. + The offset to add. + The type of reference. + A new reference that reflects the addition of offset to pointer. + + + Adds an element offset to the given reference. + The reference to add the offset to. + The offset to add. + The type of reference. + A new reference that reflects the addition of offset to pointer. + + + Adds a byte offset to the given reference. + The reference to add the offset to. + The offset to add. + The type of reference. + A new reference that reflects the addition of byte offset to pointer. + + + Determines whether the specified references point to the same location. + The first reference to compare. + The second reference to compare. + The type of reference. + true if left and right point to the same location; otherwise, false. + + + Casts the given object to the specified type. + The object to cast. + The type which the object will be cast to. + The original object, casted to the given type. + + + Reinterprets the given reference as a reference to a value of type TTo. + The reference to reinterpret. + The type of reference to reinterpret.. + The desired type of the reference. + A reference to a value of type TTo. + + + Returns a pointer to the given by-ref parameter. + The object whose pointer is obtained. + The type of object. + A pointer to the given value. + + + Reinterprets the given location as a reference to a value of type T. + The location of the value to reference. + The type of the interpreted location. + A reference to a value of type T. + + + Determines the byte offset from origin to target from the given references. + The reference to origin. + The reference to target. + The type of reference. + Byte offset from origin to target i.e. target - origin. + + + Copies a value of type T to the given location. + The location to copy to. + A reference to the value to copy. + The type of value to copy. + + + Copies a value of type T to the given location. + The location to copy to. + A pointer to the value to copy. + The type of value to copy. + + + Copies bytes from the source address to the destination address. + The destination address to copy to. + The source address to copy from. + The number of bytes to copy. + + + Copies bytes from the source address to the destination address. + The destination address to copy to. + The source address to copy from. + The number of bytes to copy. + + + Copies bytes from the source address to the destination address +without assuming architecture dependent alignment of the addresses. + The destination address to copy to. + The source address to copy from. + The number of bytes to copy. + + + Copies bytes from the source address to the destination address +without assuming architecture dependent alignment of the addresses. + The destination address to copy to. + The source address to copy from. + The number of bytes to copy. + + + Initializes a block of memory at the given location with a given initial value. + The address of the start of the memory block to initialize. + The value to initialize the block to. + The number of bytes to initialize. + + + Initializes a block of memory at the given location with a given initial value. + The address of the start of the memory block to initialize. + The value to initialize the block to. + The number of bytes to initialize. + + + Initializes a block of memory at the given location with a given initial value +without assuming architecture dependent alignment of the address. + The address of the start of the memory block to initialize. + The value to initialize the block to. + The number of bytes to initialize. + + + Initializes a block of memory at the given location with a given initial value +without assuming architecture dependent alignment of the address. + The address of the start of the memory block to initialize. + The value to initialize the block to. + The number of bytes to initialize. + + + Reads a value of type T from the given location. + The location to read from. + The type to read. + An object of type T read from the given location. + + + Reads a value of type T from the given location +without assuming architecture dependent alignment of the addresses. + The location to read from. + The type to read. + An object of type T read from the given location. + + + Reads a value of type T from the given location +without assuming architecture dependent alignment of the addresses. + The location to read from. + The type to read. + An object of type T read from the given location. + + + Returns the size of an object of the given type parameter. + The type of object whose size is retrieved. + The size of an object of type T. + + + Subtracts an element offset from the given reference. + The reference to subtract the offset from. + The offset to subtract. + The type of reference. + A new reference that reflects the subraction of offset from pointer. + + + Subtracts an element offset from the given reference. + The reference to subtract the offset from. + The offset to subtract. + The type of reference. + A new reference that reflects the subraction of offset from pointer. + + + Subtracts a byte offset from the given reference. + The reference to subtract the offset from. + + The type of reference. + A new reference that reflects the subraction of byte offset from pointer. + + + Writes a value of type T to the given location. + The location to write to. + The value to write. + The type of value to write. + + + Writes a value of type T to the given location +without assuming architecture dependent alignment of the addresses. + The location to write to. + The value to write. + The type of value to write. + + + Writes a value of type T to the given location +without assuming architecture dependent alignment of the addresses. + The location to write to. + The value to write. + The type of value to write. + + + \ No newline at end of file diff --git a/Assemblies/System.Threading.Tasks.Extensions.dll b/Assemblies/System.Threading.Tasks.Extensions.dll new file mode 100644 index 0000000..eeec928 Binary files /dev/null and b/Assemblies/System.Threading.Tasks.Extensions.dll differ diff --git a/Assemblies/System.Threading.Tasks.Extensions.xml b/Assemblies/System.Threading.Tasks.Extensions.xml new file mode 100644 index 0000000..5e02a99 --- /dev/null +++ b/Assemblies/System.Threading.Tasks.Extensions.xml @@ -0,0 +1,166 @@ + + + System.Threading.Tasks.Extensions + + + + + + + + + + + + + + + + + + + Provides a value type that wraps a and a TResult, only one of which is used. + The result. + + + Initializes a new instance of the class using the supplied task that represents the operation. + The task. + The task argument is null. + + + Initializes a new instance of the class using the supplied result of a successful operation. + The result. + + + Retrieves a object that represents this . + The object that is wrapped in this if one exists, or a new object that represents the result. + + + Configures an awaiter for this value. + true to attempt to marshal the continuation back to the captured context; otherwise, false. + The configured awaiter. + + + Creates a method builder for use with an async method. + The created builder. + + + Determines whether the specified object is equal to the current object. + The object to compare with the current object. + true if the specified object is equal to the current object; otherwise, false. + + + Determines whether the specified object is equal to the current object. + The object to compare with the current object. + true if the specified object is equal to the current object; otherwise, false. + + + Creates an awaiter for this value. + The awaiter. + + + Returns the hash code for this instance. + The hash code for the current object. + + + Gets a value that indicates whether this object represents a canceled operation. + true if this object represents a canceled operation; otherwise, false. + + + Gets a value that indicates whether this object represents a completed operation. + true if this object represents a completed operation; otherwise, false. + + + Gets a value that indicates whether this object represents a successfully completed operation. + true if this object represents a successfully completed operation; otherwise, false. + + + Gets a value that indicates whether this object represents a failed operation. + true if this object represents a failed operation; otherwise, false. + + + Compares two values for equality. + The first value to compare. + The second value to compare. + true if the two values are equal; otherwise, false. + + + Determines whether two values are unequal. + The first value to compare. + The seconed value to compare. + true if the two values are not equal; otherwise, false. + + + Gets the result. + The result. + + + Returns a string that represents the current object. + A string that represents the current object. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CommandArgs.cs b/CommandArgs.cs new file mode 100644 index 0000000..e0180de --- /dev/null +++ b/CommandArgs.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CopyDb +{ + public class CommandArgs : Dictionary + { + public CommandArgs(String[] args) + { + for(int index=0;index2) + { + StringBuilder sb=new StringBuilder(); + for(int subIndex=1;subIndex(String name) + { + T result=default(T); + try {result = (T)Convert.ChangeType(this[name].Value, typeof(T));} + catch {result = default(T);} + return result; + } + public T Coalesce(String name,T coalesce) + { + T result=default(T); + try + { + if(!Contains(name))result=coalesce; + else result = (T)Convert.ChangeType(this[name].Value, typeof(T)); + } + catch {result = default(T);} + return result; + } + public T Coalesce(String name) + { + T result=default(T); + try {result = (T)Convert.ChangeType(this[name].Value, typeof(T));} + catch {result = default(T);} + return result; + } + } +} diff --git a/CopyDB.sln b/CopyDB.sln new file mode 100644 index 0000000..6555d7d --- /dev/null +++ b/CopyDB.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CopyDb", "CopyDb.csproj", "{76844CDA-F2B2-416E-9F0F-AEC587176F33}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {76844CDA-F2B2-416E-9F0F-AEC587176F33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {76844CDA-F2B2-416E-9F0F-AEC587176F33}.Debug|Any CPU.Build.0 = Debug|Any CPU + {76844CDA-F2B2-416E-9F0F-AEC587176F33}.Release|Any CPU.ActiveCfg = Release|Any CPU + {76844CDA-F2B2-416E-9F0F-AEC587176F33}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/CopyDb.csproj b/CopyDb.csproj new file mode 100644 index 0000000..839e9a6 --- /dev/null +++ b/CopyDb.csproj @@ -0,0 +1,75 @@ + + + + + Debug + AnyCPU + {76844CDA-F2B2-416E-9F0F-AEC587176F33} + Exe + Properties + CopyDb + CopyDb + v4.6.2 + 512 + + + + x64 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + Assemblies\MySql.Data.dll + + + + + + + Assemblies\System.Runtime.CompilerServices.Unsafe.dll + + + Assemblies\System.Threading.Tasks.Extensions.dll + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NVP.cs b/NVP.cs new file mode 100644 index 0000000..6d08556 --- /dev/null +++ b/NVP.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections; +using System.Text; +using System.Collections.Generic; + +namespace CopyDb +{ + public class NVPDictionary : Dictionary + { + public NVPDictionary() + { + } + } + public class NVPCollections : List + { + public NVPCollections() + { + } + public NVPCollections(List nvpCollections) + { + foreach(String nvpCollectionString in nvpCollections)Add(new NVPCollection(nvpCollectionString)); + } + public List ToList() + { + List nvpCollections=new List(); + foreach(NVPCollection nvpCollection in this)nvpCollections.Add(nvpCollection.ToString()); + return nvpCollections; + } + } + public class NVPCollection : List + { + public NVPCollection() + { + } + public NVPCollection(String nvpCollectionString) + { + if(null==nvpCollectionString)return; + String[] nvpItems=nvpCollectionString.Split('|'); + if(null==nvpItems)return; + for(int index=0;index() + { + T result=default(T); + try {result = (T)Convert.ChangeType(Value, typeof(T));} + catch {result = default(T);} + return result; + } + public String Name{get;set;} + public String Value{get;set;} + public override String ToString() + { + StringBuilder sb=new StringBuilder(); + sb.Append(Name).Append("=").Append(Value); + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..da66245 --- /dev/null +++ b/Program.cs @@ -0,0 +1,586 @@ +using System; +using System.Collections.Generic; +using System.Collections; +using System.Text; +using System.IO; +using MySql.Data.MySqlClient; +using System.Data; + +namespace CopyDb +{ + public class Constants + { + public static String IBD_EXTENSION=".ibd"; + public static int COMMAND_TIMEOUT=0; // no timeout + public static string CHARACTER_SET="utf8mb4"; + public static string COLLATION="utf8mb4_0900_ai_ci"; + } + public class Schemas : List + { + public void Display() + { + for(int index=0;index(); + HasForeignKey=false; + } + public List SchemaLines{get;set;} + public String TableName{get;set;} + public bool HasForeignKey{get;set;} + public String ForeignKeyTable{get;set;} + public String ForeignKeyConstraint{get;set;} + } +// ****************************************************************** + + public class Config + { + public String Server{get;set;} + public int Port{get;set;} + public String Database{get;set;} + public String User{get;set;} + public String Password{get;set;} + public String PathSchemaFileName{get;set;} + public String PathIbd{get;set;} + public String Mode{get;set;} + public String DatabaseDirectory{get;set;} + public String CharacterSet{get;set;} + public String Collation{get;set;} + + public void Display() + { + Console.WriteLine(String.Format("SERVER:{0}",Server)); + Console.WriteLine(String.Format("PORT:{0}",Port)); + Console.WriteLine(String.Format("DATABASE:{0}",Database)); + Console.WriteLine(String.Format("USER:{0}",User)); + Console.WriteLine(String.Format("PASSWORD:{0}",Password)); + Console.WriteLine(String.Format("PATHSCHEMAFILE:{0}",PathSchemaFileName)); + Console.WriteLine(String.Format("PATHIBD:{0}",PathIbd)); + Console.WriteLine(String.Format("MODE:{0}",Mode)); + Console.WriteLine(String.Format("DATABASEDIRECTORY:{0}",DatabaseDirectory)); + Console.WriteLine(String.Format("CHARACTERSET:{0}",CharacterSet)); + Console.WriteLine(String.Format("COLLATION:{0}",Collation)); + } + } + class Program + { + static void Main(string[] args) + { + if(1==args.Length) + { + Console.WriteLine(String.Format("USAGE: COPYDB /SERVER:{server} /PORT:{port} /ROWCOUNTSONLY:{true|false} /CONVERTCHARSETCOLLATION:{charset@collation} /DATABASE:{databasename} /USER:{username} /PASSWORD:{password} /PATHSCHEMAFILE:{pathschemafilename} /PATHIDB:{pathibdfiles} /MODE:{LIVE|TEST} /DATABASEDIRECTORY:{path}")); + return; + } + PerformImport(args); + } + public static void PerformImport(string[] args) + { + String strResult=null; + CommandArgs commandArgs=new CommandArgs(args); + + Console.WriteLine("*********** C O N F I G ***********"); + Config config=GetConfig(commandArgs); + config.Display(); + + if(!commandArgs.Has("SERVER,PORT,DATABASE,USER,PASSWORD,PATHSCHEMAFILE")) + { + Console.WriteLine(String.Format("One or more required parameters are missing. SERVER,PORT,DATABASE,USER,PASSWORD,PATHSCHEMAFILE")); + return; + } + +// ************************************************************* S C H E M A ******************************************************* + Schemas schemas=Program.GetSchemas(config); + if(null==schemas) + { + Console.WriteLine(String.Format("Unable to read schemas")); + return; + } + Console.WriteLine("*********** S C H E M A ***********"); + schemas.Display(); + +// *********************************************************** D A T A B A S E ******************************************************** + Console.WriteLine("*********** V E R I F Y I N G D A T A B A S E ***********"); + MySqlConnection sqlConnection=null; + try{ sqlConnection=SqlUtils.CreateMySqlConnection(config.Server,config.Port.ToString(),config.Database,config.User,config.Password);} + catch(Exception exception) + { + Console.WriteLine(String.Format("Encountered Exception: {0}",exception.ToString())); + return; + } + ConnectionState connectionState=sqlConnection.State; + if(!connectionState.Equals(ConnectionState.Open)) + { + Console.WriteLine(String.Format("Unable to connect to databse {0}",config.Database)); + return; + } + Console.WriteLine("Database connection verified."); +// ***************************************************** T A B L E R O W C O U N T S*********************************************************** + GetTableRowCounts(schemas, config, sqlConnection); + + if(commandArgs.Has("ROWCOUNTSONLY") && commandArgs.Get("ROWCOUNTSONLY").Equals(true)) + { + Console.WriteLine("Exiting because ROWCOUNTSONLY is set to True."); + return; + } + +// ********************************************************************************************************************************************* +// (i.e.) CONVERTCHARSETCOLLATION:utf8mb4@utf8mb4_0900_ai_ci + if(commandArgs.Has("CONVERTCHARSETCOLLATION")) + { + Console.WriteLine("**WARNING** This is a destructive event. This process will convert tables in {0}",config.Database); + Console.WriteLine("Please review settings. Proceed Y/N?"); + strResult=Console.ReadLine(); + if(null==strResult||(!strResult.ToUpper().Equals("Y") && !strResult.ToUpper().Equals("YES"))) + { + Console.WriteLine("Cancelled"); + return; + } + ConvertSchema(schemas ,config, sqlConnection); + GetTableRowCounts(schemas, config, sqlConnection); + Console.WriteLine("Done."); + Console.ReadLine(); + return; + } + + if(!commandArgs.Has("PATHIBD,MODE,DATABASEDIRECTORY")) + { + Console.WriteLine(String.Format("One or more required parameters are missing.")); + return; + } + + Console.WriteLine("*********** V E R I F Y I N G I D B F I L E S ***********"); + if(!VerifyIdbFiles(schemas,config)) + { + Console.WriteLine("Unable to verify IDBFiles"); + return; + } + + if(config.Mode.ToUpper().Equals("TEST")) + { + Console.WriteLine("Mode is TEST."); + sqlConnection.Close(); + sqlConnection.Dispose(); + return; + } + + Console.WriteLine("**WARNING** This is a destructive event. This process will drop tables in {0}",config.Database); + Console.WriteLine("Please review settings. Proceed Y/N?"); + strResult=Console.ReadLine(); + if(null==strResult||(!strResult.ToUpper().Equals("Y") && !strResult.ToUpper().Equals("YES"))) + { + Console.WriteLine("Cancelled"); + return; + } + + Console.WriteLine("*********** I M P O R T ***********"); + foreach(Schema schema in schemas) + { + ImportTable(schema ,config, sqlConnection); + } + sqlConnection.Close(); + sqlConnection.Dispose(); + Console.WriteLine("Done."); + return; + } +// ******************************************************************************************************************************************************************************** +// *************************************************************************** C O N V E R T C H A R A C T E R S E T *********************************************************** +// ******************************************************************************************************************************************************************************** + private static void ConvertSchema(Schemas schemas, Config config, MySqlConnection sqlConnection) + { + MySqlCommand sqlCommand=null; + String strSetKeyChecksTrue="SET foreign_key_checks =1;"; + String strSetKeyChecksFalse="SET foreign_key_checks =0;"; + + try + { + Console.WriteLine(String.Format("{0}",strSetKeyChecksFalse)); + sqlCommand = new MySqlCommand(strSetKeyChecksFalse, sqlConnection); + sqlCommand.CommandTimeout=Constants.COMMAND_TIMEOUT; + sqlCommand.ExecuteNonQuery(); + sqlCommand.Dispose(); + + foreach(Schema schema in schemas) + { + StringBuilder sb=new StringBuilder(); + sb.Append("ALTER TABLE ").Append(schema.TableName).Append(" CONVERT TO CHARACTER SET ").Append(config.CharacterSet).Append(" COLLATE ").Append(config.Collation).Append(" ;"); + String strQuery=sb.ToString(); + Console.WriteLine(String.Format(strQuery)); + sqlCommand = new MySqlCommand(strQuery, sqlConnection); + sqlCommand.CommandTimeout=Constants.COMMAND_TIMEOUT; + sqlCommand.ExecuteNonQuery(); + sqlCommand.Dispose(); + if(!VerifyCharSetCollation(schema.TableName, config, sqlConnection)) + { + Console.WriteLine(String.Format("FAILED to change character set / collation on table {0}",schema.TableName)); + } + else Console.WriteLine(String.Format("VERIFIED")); + } + Console.WriteLine(String.Format("{0}",strSetKeyChecksTrue)); + Console.WriteLine(""); + sqlCommand = new MySqlCommand(strSetKeyChecksTrue, sqlConnection); + sqlCommand.CommandTimeout=Constants.COMMAND_TIMEOUT; + sqlCommand.ExecuteNonQuery(); + sqlCommand.Dispose(); + + } + catch(Exception exception) + { + if(null!=sqlCommand) + { + sqlCommand.Dispose(); + sqlCommand=null; + } + Console.WriteLine("Exception converting character set :{0}",exception.ToString()); + } + } +// ******************************************************************************************************************************************************************************** +// *************************************************************************** V E R I F Y C H A R A C T E R S E T *********************************************************** +// ******************************************************************************************************************************************************************************** + private static bool VerifyCharSetCollation(String tableName, Config config, MySqlConnection sqlConnection) + { + MySqlCommand sqlCommand=null; + MySqlDataReader sqlReader=null; + bool verified=true; + + try + { + StringBuilder sb=new StringBuilder(); + sb.Append("SHOW FULL COLUMNS FROM ").Append(tableName).Append(" ;"); + sqlCommand=sqlConnection.CreateCommand(); + sqlCommand.CommandTimeout=Constants.COMMAND_TIMEOUT; + String strQuery=sb.ToString(); + Console.WriteLine(String.Format(strQuery)); + sqlCommand = new MySqlCommand(strQuery, sqlConnection); + sqlReader=sqlCommand.ExecuteReader(); + while(sqlReader.Read()) + { + String field=sqlReader.IsDBNull(0)?null:sqlReader.GetString(0); + String type=sqlReader.IsDBNull(1)?null:sqlReader.GetString(1).ToLower(); + String collation=sqlReader.IsDBNull(2)?null:sqlReader.GetString(2).ToLower(); + if(!type.StartsWith("varchar"))continue; + if(!collation.Equals(config.Collation))verified=false; + } + sqlReader.Close(); + sqlReader.Dispose(); + sqlCommand.Dispose(); + sqlCommand=null; + sqlReader=null; + return verified; + } + catch(Exception exception) + { + Console.WriteLine("Exception converting character set :{0}",exception.ToString()); + if(null!=sqlReader) + { + sqlReader.Close(); + sqlReader.Dispose(); + } + if(null!=sqlCommand) + { + sqlCommand.Dispose(); + sqlCommand=null; + } + return false; + } + } +// ******************************************************************************************************************************************************************************** +// ******************************************************************************** T A B L E R O W C O U N T S *********************************************************************** +// ******************************************************************************************************************************************************************************** + private static void GetTableRowCounts(Schemas schemas, Config config, MySqlConnection sqlConnection) + { + MySqlCommand sqlCommand=null; + MySqlDataReader sqlReader=null; + + try + { + foreach(Schema schema in schemas) + { + StringBuilder sb=new StringBuilder(); + sb.Append("SELECT COUNT(*) FROM ").Append(schema.TableName).Append(" ;"); + sqlCommand=sqlConnection.CreateCommand(); + sqlCommand.CommandTimeout=Constants.COMMAND_TIMEOUT; + String strQuery=sb.ToString(); + sqlCommand = new MySqlCommand(strQuery, sqlConnection); + sqlReader=sqlCommand.ExecuteReader(); + while(sqlReader.Read()) + { + int rows=sqlReader.GetInt32(0); + Console.WriteLine(String.Format("{0},{1}",schema.TableName,Utility.FormatNumber(rows,0,false))); + } + sqlReader.Close(); + sqlReader.Dispose(); + sqlCommand.Dispose(); + sqlCommand=null; + sqlReader=null; + } + } + catch(Exception exception) + { + Console.WriteLine("Exception:{0}",exception.ToString()); + if(null!=sqlReader) + { + sqlReader.Close(); + sqlReader.Dispose(); + } + if(null!=sqlCommand) + { + sqlCommand.Dispose(); + sqlCommand=null; + } + } + } + +// ***************************************************************************************************************************************************** +// *************************************************************** I M P O R T T A B L E ************************************************************** +// ***************************************************************************************************************************************************** + private static void ImportTable(Schema schema, Config config,MySqlConnection sqlConnection) + { + MySqlTransaction sqlTransaction=null; + String pathIdbFile=null; + String pathIdbFileDestination=null; + + try + { + MySqlCommand sqlCommand=null; + String strQuery=null; + StringBuilder sb=null; + pathIdbFile=config.PathIbd+"\\"+schema.TableName+".ibd"; + pathIdbFileDestination=config.DatabaseDirectory+"\\"+schema.TableName+".ibd"; + sqlTransaction=sqlConnection.BeginTransaction(IsolationLevel.RepeatableRead); + + sb=new StringBuilder(); + sb.Append("DROP TABLE IF EXISTS ").Append(schema.TableName).Append(";"); + sqlCommand=sqlConnection.CreateCommand(); + sqlCommand.CommandTimeout=Constants.COMMAND_TIMEOUT; + strQuery=sb.ToString(); + Console.WriteLine(String.Format(strQuery)); + sqlCommand = new MySqlCommand(strQuery, sqlConnection, sqlTransaction); + sqlCommand.ExecuteNonQuery(); + sqlCommand.Dispose(); + + sqlCommand=sqlConnection.CreateCommand(); + sqlCommand.CommandTimeout=Constants.COMMAND_TIMEOUT; + strQuery=Utility.ListToString(schema.SchemaLines,' '); + Console.WriteLine(String.Format(schema.SchemaLines[0])); + sqlCommand = new MySqlCommand(strQuery, sqlConnection, sqlTransaction); + int result=sqlCommand.ExecuteNonQuery(); + sqlCommand.Dispose(); + + sb=new StringBuilder(); + sb.Append("ALTER TABLE ").Append(schema.TableName).Append(" DISCARD TABLESPACE;"); + strQuery=sb.ToString(); + Console.WriteLine(String.Format("{0}",strQuery)); + sqlCommand = new MySqlCommand(strQuery, sqlConnection, sqlTransaction); + sqlCommand.CommandTimeout=Constants.COMMAND_TIMEOUT; + result=sqlCommand.ExecuteNonQuery(); + sqlCommand.Dispose(); + + Console.WriteLine(String.Format("Copy file {0} -> {1}",pathIdbFile,pathIdbFileDestination)); + File.Copy(pathIdbFile,pathIdbFileDestination,true); + + sb=new StringBuilder(); + sb.Append("ALTER TABLE ").Append(schema.TableName).Append(" IMPORT TABLESPACE;"); + strQuery=sb.ToString(); + Console.WriteLine(String.Format("{0}",strQuery)); + sqlCommand = new MySqlCommand(strQuery, sqlConnection, sqlTransaction); + sqlCommand.CommandTimeout=Constants.COMMAND_TIMEOUT; + sqlCommand.ExecuteNonQuery(); + sqlCommand.Dispose(); + + try + { + sb=new StringBuilder(); + sb.Append("ALTER TABLE ").Append(schema.TableName).Append(" CONVERT TO CHARACTER SET ").Append(Constants.CHARACTER_SET).Append(" COLLATE ").Append(Constants.COLLATION).Append(";"); + strQuery=sb.ToString(); + Console.WriteLine(String.Format("{0}",strQuery)); + sqlCommand = new MySqlCommand(strQuery, sqlConnection, sqlTransaction); + sqlCommand.CommandTimeout=Constants.COMMAND_TIMEOUT; + sqlCommand.ExecuteNonQuery(); + sqlCommand.Dispose(); + } + catch(Exception exception) + { + Console.WriteLine("Exception converting character set :{0}",exception.ToString()); + } + + if(schema.HasForeignKey) + { + sb=new StringBuilder(); + sb.Append("ALTER TABLE ").Append(schema.TableName).Append(" ADD ").Append(schema.ForeignKeyConstraint).Append(";"); + strQuery=sb.ToString(); + Console.WriteLine(String.Format("{0}",strQuery)); + sqlCommand = new MySqlCommand(strQuery, sqlConnection, sqlTransaction); + sqlCommand.CommandTimeout=Constants.COMMAND_TIMEOUT; + sqlCommand.ExecuteNonQuery(); + sqlCommand.Dispose(); + } + sqlTransaction.Commit(); + Console.WriteLine(""); + } + catch(Exception exception) + { + Console.WriteLine(String.Format("Exception:{0}",exception.ToString())); + try{sqlTransaction.Rollback();} + catch(Exception rollbackException) + { + Console.WriteLine(String.Format("Rollback exception:{0}",rollbackException.ToString())); + } + } + } + private static bool VerifyIdbFiles(Schemas schemas,Config config) + { + bool success=true; + foreach(Schema schema in schemas) + { + String pathIdbFile=config.PathIbd+"\\"+schema.TableName+Constants.IBD_EXTENSION;; + Console.Write(String.Format("{0}",pathIdbFile)); + if(!File.Exists(pathIdbFile)) + { + Console.WriteLine("...Not found."); + success=false; + } + Console.WriteLine("...Verified"); + } + return success; + } + private static Schemas GetSchemas(Config config) + { + Schemas schemas=new Schemas(); + + try + { + FileStream inStream = new FileStream(config.PathSchemaFileName,FileMode.Open); + StreamReader streamReader=new StreamReader(inStream); + String strLine=null; + + bool inCreate=false; + Schema schema=null; + while(null!=(strLine=streamReader.ReadLine())) + { + if(strLine.StartsWith("CREATE TABLE") && !inCreate) + { + schema=new Schema(); + schema.TableName=Utility.BetweenString(strLine,"`","`"); + schema.SchemaLines.Add(strLine); + inCreate=true; + } + else if(inCreate) + { +// schema.SchemaLines.Add(strLine); + if(strLine.Contains("FOREIGN KEY")) + { +// schema.SchemaLines.Add(strLine); + schema.ForeignKeyConstraint=strLine; + + schema.HasForeignKey=true; + String[] elements=strLine.Split(' '); + schema.ForeignKeyTable=GetForeignKeyTable(elements); + } + else if(strLine.Trim().EndsWith(";")) + { +// schema.SchemaLines.Add(") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;"); + if(schema.SchemaLines[schema.SchemaLines.Count-1].EndsWith(",")) + { + String line=schema.SchemaLines[schema.SchemaLines.Count-1]; + line=line.Substring(0,line.Length-1); // FUNNY + schema.SchemaLines[schema.SchemaLines.Count-1]=line; + } + schema.SchemaLines.Add(strLine); + inCreate=false; + schemas.Add(schema); + schema=null; + } + else + { + schema.SchemaLines.Add(strLine); + } + } + } + streamReader.Close(); + streamReader.Dispose(); + inStream.Close(); + inStream.Dispose(); + OrderSchemas(schemas); + return schemas; + } + catch(Exception exception) + { + Console.WriteLine(String.Format("Exception:{0}",exception.ToString())); + return null; + } + } + private static Schemas OrderSchemas(Schemas schemas) + { + for(int index=0;indexforeignKeyIndex)continue; + SwapSchemaPositions(schemas,index,foreignKeyIndex); + index=-1; + continue; + } + } + return schemas; + } + private static void SwapSchemaPositions(Schemas schemas,int schemaIndex,int foreignKeySchemaIndex) + { + Schema tempSchema=schemas[schemaIndex]; + schemas[schemaIndex]=schemas[foreignKeySchemaIndex]; + schemas[foreignKeySchemaIndex]=tempSchema; + } + private static int FindSchemaLocation(Schemas schemas,String tableName) + { + for(int index=0;index("SERVER"); + config.Port=commandArgs.Get("PORT"); + config.Database=commandArgs.Get("DATABASE"); + config.User=commandArgs.Get("USER"); + config.Password=commandArgs.Get("PASSWORD"); + config.PathSchemaFileName=commandArgs.Get("PATHSCHEMAFILE"); + config.PathIbd=commandArgs.Get("PATHIBD"); + config.Mode=commandArgs.Get("MODE"); + config.DatabaseDirectory=commandArgs.Get("DATABASEDIRECTORY"); + if(commandArgs.Has("CONVERTCHARSETCOLLATION")) + { + String[] charsetcollation=commandArgs.Get("CONVERTCHARSETCOLLATION").Split('@'); + config.CharacterSet=charsetcollation[0]; + config.Collation=charsetcollation[1]; + } + return config; + } + } +} + diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ceb17e1 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TestHarness")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TestHarness")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("54484c44-f1be-4113-95d7-eabd8d7c2f50")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SQLUtils.cs b/SQLUtils.cs new file mode 100644 index 0000000..dc37e09 --- /dev/null +++ b/SQLUtils.cs @@ -0,0 +1,236 @@ +using System; +using System.Data.SqlClient; +using System.Collections; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.Text; +using MySql.Data.MySqlClient; +//using MarketData.DataAccess; + +namespace CopyDb +{ +/// SQlUtils - SQL utility class + public class SqlUtils + { + public static int COMMAND_TIMEOUT=300; + public static int MIN_POOL_SIZE=10; + public static int MAX_POOL_SIZE=100; + +/// CreateMySqlConnection - Creates an SQL connection. +/// datasource. +/// database. +/// username. +/// users password. +/// SqlConnection or null on error. + public static MySqlConnection CreateMySqlConnection(string datasource,string port,string database,string username,string password) + { + try + { + String connectionString=null; + StringBuilder sb=new StringBuilder(); + sb.Append("server=").Append(datasource).Append("; "); + sb.Append("user id=").Append(username).Append("; "); + sb.Append("password=").Append(password).Append("; "); + sb.Append("database=").Append(database).Append("; "); + sb.Append("SslMode=").Append("None").Append("; "); + sb.Append("pooling=").Append("true").Append(";"); + sb.Append("allow user variables=").Append("true").Append("; "); + sb.Append("default command timeout=").Append("300").Append("; "); + sb.Append("connect timeout=").Append("300").Append(" "); + connectionString=sb.ToString(); + MySqlConnection connection=new MySqlConnection(connectionString); + connection.Open(); + return connection; + } + catch(SqlException exception) + { + throw exception; + //MDTrace.WriteLine(LogLevel.DEBUG,exception.ToString()); + //return null; + } + } +/// CreateSqlConnection - Creates an SQL connection. +/// the datasource. +/// SqlConnection or null on error. + //public static MySqlConnection CreateMySqlConnection(DataSourceEx datasource) + //{ + // try + // { + // String connectionString=null; + // StringBuilder sb=new StringBuilder(); + // sb.Append("server=").Append(datasource.Datasource).Append("; "); + // sb.Append("user id=").Append(datasource.Username).Append("; "); + // sb.Append("password=").Append(datasource.Password).Append("; "); + // sb.Append("database=").Append(datasource.Database).Append("; "); + // sb.Append("SslMode=").Append("None").Append("; "); + // sb.Append("pooling=").Append("true").Append(";"); + // sb.Append("allow user variables=").Append("true").Append("; "); + // sb.Append("default command timeout=").Append("300").Append("; "); + // sb.Append("connect timeout=").Append("300").Append(" "); + // connectionString=sb.ToString(); + // MySqlConnection connection=new MySqlConnection(connectionString); + // connection.Open(); + // return connection; + // } + // catch(SqlException exception) + // { + // MDTrace.WriteLine(LogLevel.DEBUG,exception.ToString()); + // return null; + // } + //} + //public static String FormatDate(DateTime dateTime) + //{ + // return Utility.DateTimeToStringYYYYHMMHDD(dateTime); + //} +/// CreateInClause - Creates an In Clause. +/// ArrayList of items. +/// String. + public static String CreateInClause(ArrayList list) + { + StringBuilder sb=new StringBuilder(); + Hashtable hashtable=new Hashtable(); + foreach(string item in list)if(!hashtable.ContainsKey(item))hashtable.Add(item,item); + list=new ArrayList(hashtable.Keys); + sb.Append("("); + for(int index=0;indexCreateInClause - Creates an In Clause. +/// List of items. +/// String. + public static String CreateInClause(List list) + { + StringBuilder sb = new StringBuilder(); + Hashtable hashtable = new Hashtable(); + foreach (string item in list) if (!hashtable.ContainsKey(item)) hashtable.Add(item, item); + ArrayList uniqueKeys = new ArrayList(hashtable.Keys); + sb.Append("("); + for (int index = 0; index < uniqueKeys.Count; index++) + { + sb.Append("'").Append((string)uniqueKeys[index]).Append("'"); + if (index < uniqueKeys.Count - 1) sb.Append(","); + } + sb.Append(")"); + return sb.ToString(); + } +/// CreateInClause - Creates an In Clause. +/// ArrayList of items. +/// String. + public static String CreateInClauseInt(List list) + { + ArrayList uniqueList=new ArrayList(); + StringBuilder sb=new StringBuilder(); + Hashtable hashtable=new Hashtable(); + foreach(string item in list)if(!hashtable.ContainsKey(item))hashtable.Add(item,item); + uniqueList=new ArrayList(hashtable.Keys); + sb.Append("("); + for(int index=0;indexCreateInClause - Creates an In Clause. +/// ArrayList of items. +/// String. + public static String CreateInClauseInt(List list) + { + ArrayList uniqueList=new ArrayList(); + StringBuilder sb=new StringBuilder(); + Hashtable hashtable=new Hashtable(); + foreach(int item in list)if(!hashtable.ContainsKey(item))hashtable.Add(item,item); + uniqueList=new ArrayList(hashtable.Keys); + sb.Append("("); + for(int index=0;indexCreateInClause - Creates an In Clause. + /// ArrayList of items. + /// String. + //public static String CreateInClauseYear(List list) + //{ + // ArrayList uniqueList = new ArrayList(); + // StringBuilder sb = new StringBuilder(); + // Hashtable hashtable = new Hashtable(); + // foreach (DateTime item in list) + // { + // String strRep = Utility.DateTimeToStringYYYYHMMHDD(item); + // if (!hashtable.ContainsKey(strRep)) hashtable.Add(strRep, strRep); + // } + // uniqueList = new ArrayList(hashtable.Keys); + // sb.Append("("); + // for (int index = 0; index < uniqueList.Count; index++) + // { + // sb.Append(Utility.AddQuotes((string)uniqueList[index])); + // if (index < uniqueList.Count - 1) sb.Append(","); + // } + // sb.Append(")"); + // return sb.ToString(); + //} +// + public static String CreateInClause(List list) + { + StringBuilder sb = new StringBuilder(); + sb.Append("("); + for (int index = 0; index < list.Count; index++) + { + sb.Append(list[index].ToString()); + if (index < list.Count - 1) sb.Append(","); + } + sb.Append(")"); + return sb.ToString(); + } +/// MinDate - Return minimum sql date. +/// DateTime + //public static DateTime MinSqlDate() + //{ + // return SqlDateTime.MinValue.Value; + //} + //public static String AddQuotes(String item) + //{ + // return "'" + item + "'"; + //} + //public static String SqlDate(DateTime dateTime) + //{ + // if (Utility.IsEpoch(dateTime)) return null; + // return Utility.DateTimeToStringYYYYHMMHDD(dateTime); + //} + //public static String ToSqlDateTime(DateTime dateTime) + //{ + // return Utility.DateTimeToStringYYYYHMMHDDHHMMSS(dateTime); + //} + //public static String ToSqlDateTimeTT(DateTime dateTime) + //{ + // return Utility.DateTimeToStringYYYYHMMHDDHHMMSSTT(dateTime); + //} +/// SqlString - Return minimum sql date. +/// DateTime + public static String SqlString(String value) + { + StringBuilder sb=new StringBuilder(); + foreach(char ch in value) + { + sb.Append(ch); + if(ch=='\'')sb.Append("'"); + } + return sb.ToString(); + } + public static String ToSqlString(String value) + { + StringBuilder sb=new StringBuilder(); + return sb.Append("'").Append(SqlString(value)).Append("'").ToString(); + } + } +} diff --git a/Utility.cs b/Utility.cs new file mode 100644 index 0000000..e9b1dc6 --- /dev/null +++ b/Utility.cs @@ -0,0 +1,625 @@ +using System; +using System.Text; +using System.IO.Compression; +using System.IO; +using System.Globalization; +using System.Linq; +using System.Collections.Generic; +using Microsoft.Win32; +using System.Diagnostics; +using System.Security.Principal; +using System.Threading; +using ThreadState=System.Threading.ThreadState; + +namespace CopyDb +{ + public class Utility + { + private static DateTime epoch = DateTime.Parse("01-01-0001"); + private static TimeSpan oneDay=new TimeSpan(1,0,0,0); + + + public static String ThreadStateToString(Thread thread) + { + switch(thread.ThreadState) + { + case ThreadState.Running : + return "Running"; + case ThreadState.StopRequested : + return "StopRequested"; + case ThreadState.SuspendRequested : + return "SuspendRequested"; + case ThreadState.Background : + return "Background"; + case ThreadState.Unstarted : + return "Unstarted"; + case ThreadState.Stopped : + return "Stopped"; + case ThreadState.WaitSleepJoin : + return "WaitSleepJoin"; + case ThreadState.Suspended : + return "Suspended"; + case ThreadState.AbortRequested : + return "AbortRequested"; + case ThreadState.Aborted : + return "Aborted"; + default : + return "Unknown"; + } + } + public static long DateToUnixDate(DateTime dateTime) + { + DateTime javascriptEpoch=DateTime.Parse("01-01-1970 00:00:00"); + DateTime eod=new DateTime(dateTime.Year,dateTime.Month,dateTime.Day,23,0,0); // request end of day + TimeSpan ts=eod-javascriptEpoch; + long longDate=(long)ts.TotalSeconds; + return longDate; + } + public static DateTime UnixDateToDate(long yahooDate) + { + DateTime javascriptEpoch=DateTime.Parse("01-01-1970 00:00:00"); + TimeSpan timespan=TimeSpan.FromSeconds((double)yahooDate); + DateTime date=javascriptEpoch+timespan; + return date; + } + public static void RemoveLogFiles(String strFolder=null) + { + if(null==strFolder)strFolder=Directory.GetCurrentDirectory(); + String[] logFiles=Directory.GetFiles(strFolder); + if(null==logFiles || 0==logFiles.Length)return; + logFiles=logFiles.Where(x => x.EndsWith(".log",StringComparison.InvariantCultureIgnoreCase)).ToArray(); + if(null==logFiles || 0==logFiles.Length)return; + foreach(String logFile in logFiles) + { + try + { + File.Delete(logFile); + } + catch(Exception){;} + } + } + public static String Pad(string str, char filler, int length) + { + int stringLength = str.Length; + if (stringLength >= length) return str; + StringBuilder sb = new StringBuilder(); + + while (stringLength < length) + { + sb.Append(filler); + stringLength++; + } + return sb.ToString() + str; + } + public static bool Is64Bit() + { + if(IntPtr.Size.Equals(8))return true; + return false; + } + public static bool IsAdministrator() + { + return (new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole(WindowsBuiltInRole.Administrator); + } + public static String RemoveHtml(String strItem) + { + if(null==strItem)return null; + String[] codes = { "'","»" }; + if(null==strItem)return strItem; + foreach (String code in codes) + { + strItem = strItem.Replace(code,"'"); + } + strItem=strItem.Replace("&","&"); + strItem=strItem.Replace("‘","'"); + strItem=strItem.Replace("’","'"); + strItem=strItem.Replace("—","-"); + return strItem; + } + public static String RemoveDivs(String strItem) + { + StringBuilder sb=new StringBuilder(); + bool inDiv=false; + if(null==strItem)return strItem; + for(int index=0;index'))inDiv=false; + else if(!inDiv)sb.Append(ch); + } + return sb.ToString(); + } + public static int CharToNum(char ch) + { + return (int)ch-48; + } + public static String RemoveCC(String item) + { + StringBuilder sb=new StringBuilder(); + foreach(char ch in item) + { + if(!Char.IsControl(ch)) sb.Append(ch); + } + return sb.ToString(); + } + public static Stream StreamFromString(string s) + { + var stream=new MemoryStream(); + var writer=new StreamWriter(stream); + writer.Write(s); + writer.Flush(); + stream.Position=0; + return stream; + } + public static String RemoveQuotes(String strItem) + { + if (String.IsNullOrEmpty(strItem)) return null; + if(strItem.StartsWith("\""))strItem=strItem.Substring(1); + if(strItem.EndsWith("\""))strItem=strItem.Substring(0,strItem.Length-1); + return strItem; + } + public static String BetweenString(String strItem, String strBegin, String strEnd) + { + if (null == strItem) return null; + int index=-1; + if(null==strBegin)index=0; + else index = strItem.IndexOf(strBegin); + if (-1 == index) return null; + String str = null; + if(null!=strBegin)str=strItem.Substring(index + strBegin.Length); + else str=strItem; + if(null==strEnd)return str; + index = str.IndexOf(strEnd); + if (-1 == index) return null; + StringBuilder sb = new StringBuilder(); + for (int strIndex = 0; strIndex < str.Length; strIndex++) + { + if (index == strIndex) break; + sb.Append(str[strIndex]); + } + return sb.ToString(); + } + public static String RemoveAfter(String strItem, char charItem) + { + StringBuilder sb = new StringBuilder(); + for (int index = 0; index < strItem.Length; index++) + { + char ch = strItem[index]; + if (ch.Equals(charItem)) break; + sb.Append(ch); + } + return sb.ToString(); + } + public static bool OutOfRange(double value) + { + return value > 100000000000000000000.00 || value< -99999999999999999999.99; + } + public static String RemoveControlChars(String strItem) + { + StringBuilder sb=new StringBuilder(); + for(int index=0;index=1000.00) formatString.Append("{0:0,0."); + else formatString.Append("{0:0."); + for(int index=0;index list,char separator=',') + { + StringBuilder sb=new StringBuilder(); + if (null == list || 0 == list.Count) return null; + for(int index=0;index ToList(String items,char separator=',') + { + List list = items.Split(separator).ToList(); +// list=(from String s in list select s.Trim()).ToList(); + list=(from String str in list where !String.IsNullOrEmpty(str) select str.Trim()).ToList(); + return list; + } + public static String FromList(List items,String postFix=",") + { + StringBuilder sb=new StringBuilder(); + for(int index=0;index 0) outputStream.Write(decompressedBytesBuffer, 0, count); + else break; + } + decompressionStream.Close(); + compressedStream.Close(); + String strDecompressed = System.Text.Encoding.UTF8.GetString(outputStream.ToArray()); + outputStream.Close(); + outputStream = null; + compressedStream = null; + decompressionStream = null; + return strDecompressed; + } + catch (Exception exception) + { + Console.WriteLine(String.Format("Exception:{0}",exception.ToString())); + return null; + } + finally + { + if (null != outputStream) + { + outputStream.Close(); + outputStream = null; + } + if (null != decompressionStream) + { + decompressionStream.Close(); + decompressionStream = null; + } + if (null != compressedStream) + { + compressedStream.Close(); + compressedStream = null; + } + } + } + public static void LaunchBrowserSearch(String searchTerm) + { + Process.Start("https://www.google.com/search?q="+Uri.EscapeDataString(searchTerm)+"/"); + } + public static bool IsZeroOrNaN(double value) + { + return IsNaN(value)||IsZero(value); + } + private static bool IsZero(double value) + { + if(value==0.00)return true; + return false; + } + private static bool IsNaN(double value) + { + return double.IsNaN(value); + } + public static void DeleteFile(String pathFileName) + { + if(!File.Exists(pathFileName))return; + try{File.Delete(pathFileName);}catch(Exception){;} + } + } +} \ No newline at end of file