11using System ;
22using System . Collections . Generic ;
3- using System . Data ;
43using System . IO ;
5- using System . Linq ;
6- using System . Linq . Expressions ;
74using System . Text ;
8- using System . Threading . Tasks ;
95using Fclp ;
106using MySql . Data . MySqlClient ;
117
128namespace MySQL_To_CSharp
139{
14-
15- public class ApplicationArguments
10+ class Program
1611 {
17- public string IP { get ; set ; }
18- public int Port { get ; set ; }
19- public string User { get ; set ; }
20- public string Password { get ; set ; }
21- public string Database { get ; set ; }
22- public string Table { get ; set ; }
23- public bool GenerateConstructorAndOutput { get ; set ; }
24- public bool GenerateMarkupPages { get ; set ; }
25- public string MarkupDatabaseNameReplacement { get ; set ; }
26- }
12+ static void Main ( string [ ] args )
13+ {
14+ var parser = new FluentCommandLineParser < ApplicationArguments > ( ) ;
15+ parser . Setup ( arg => arg . IP ) . As ( 'i' , "ip" ) . SetDefault ( "127.0.0.1" ) . WithDescription ( "(optional) IP address of the MySQL server, will use 127.0.0.1 if not specified" ) ;
16+ parser . Setup ( arg => arg . Port ) . As ( 'n' , "port" ) . SetDefault ( 3306 ) . WithDescription ( "(optional) Port number of the MySQL server, will use 3306 if not specified" ) ;
17+ parser . Setup ( arg => arg . User ) . As ( 'u' , "user" ) . SetDefault ( "root" ) . WithDescription ( "(optional) Username, will use root if not specified" ) ;
18+ parser . Setup ( arg => arg . Password ) . As ( 'p' , "password" ) . SetDefault ( String . Empty ) . WithDescription ( "(optional) Password, will use empty password if not specified" ) ;
19+ parser . Setup ( arg => arg . Database ) . As ( 'd' , "database" ) . Required ( ) . WithDescription ( "Database name" ) ;
20+ parser . Setup ( arg => arg . Table ) . As ( 't' , "table" ) . SetDefault ( String . Empty ) . WithDescription ( "(optional) Table name, will generate entire database if not specified" ) ;
21+ parser . Setup ( arg => arg . GenerateConstructorAndOutput ) . As ( 'g' , "generateconstructorandoutput" )
22+ . SetDefault ( false ) . WithDescription ( "(optional) Generate a reading constructor and SQL statement output - Activate with -g true" ) ;
23+ parser . Setup ( arg => arg . GenerateMarkupPages ) . As ( 'm' , "generatemarkuppages" )
24+ . SetDefault ( false )
25+ . WithDescription ( "(optional) Generate markup pages for database and tables which can be used in wikis - Activate with -m true" ) ;
26+ parser . Setup ( arg => arg . MarkupDatabaseNameReplacement ) . As ( 'r' , "markupdatabasenamereplacement" )
27+ . SetDefault ( "" ) . WithDescription ( "(optional) Will use this instead of database name for wiki breadcrump generation" ) ;
28+ parser . SetupHelp ( "?" , "help" ) . Callback ( text => Console . WriteLine ( text ) ) ;
2729
28- public class Column
29- {
30- public string Name { get ; set ; }
31- public Type Type { get ; set ; }
32- public string ColumnType { get ; set ; }
30+ var result = parser . Parse ( args ) ;
31+ if ( ! result . HasErrors )
32+ {
33+ var conf = parser . Object as ApplicationArguments ;
34+ if ( conf . Database is null )
35+ {
36+ Console . WriteLine ( "You didn't specify a database" ) ;
37+ return ;
38+ }
3339
34- public Column ( MySqlDataReader reader )
35- {
36- this . Name = reader . GetString ( 1 ) ;
37- this . ColumnType = reader . GetString ( 2 ) ;
38- }
40+ var confString =
41+ $ "Server={ conf . IP } ;Port={ conf . Port } ;Uid={ conf . User } ;Pwd={ conf . Password } ;Database={ conf . Database } ";
42+ Console . WriteLine ( confString ) ;
3943
40- public override string ToString ( )
41- {
42- return $ "public { this . Type . Name } { this . Name . FirstCharUpper ( ) } {{ get; set; }}";
43- }
44- }
44+ var database = new Dictionary < string , List < Column > > ( ) ;
4545
46- public static class StringExtension
47- {
48- public static string FirstCharUpper ( this string str )
49- {
50- return str . First ( ) . ToString ( ) . ToUpper ( ) + str . Substring ( 1 ) ;
46+ using ( var con = new MySqlConnection ( confString ) )
47+ {
48+ con . Open ( ) ;
49+
50+ using ( var cmd = con . CreateCommand ( ) )
51+ {
52+ cmd . CommandText =
53+ $ "SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '{ conf . Database } '";
54+ if ( ! conf . Table . Equals ( string . Empty ) )
55+ cmd . CommandText += $ " AND TABLE_NAME = '{ conf . Table } '";
56+
57+ var reader = cmd . ExecuteReader ( ) ;
58+ if ( ! reader . HasRows )
59+ return ;
60+
61+ while ( reader . Read ( ) )
62+ if ( database . ContainsKey ( reader . GetString ( 0 ) ) )
63+ database [ reader . GetString ( 0 ) ] . Add ( new Column ( reader ) ) ;
64+ else
65+ database . Add ( reader . GetString ( 0 ) , new List < Column > ( ) { new Column ( reader ) } ) ;
66+ }
67+
68+ foreach ( var table in database )
69+ {
70+ using ( var cmd = con . CreateCommand ( ) )
71+ {
72+ // TODO: Is there a way to do this without this senseless statement?
73+ cmd . CommandText = $ "SELECT * FROM `{ table . Key } ` LIMIT 0";
74+ var reader = cmd . ExecuteReader ( ) ;
75+ var schema = reader . GetSchemaTable ( ) ;
76+ foreach ( var column in table . Value )
77+ column . Type = schema . Select ( $ "ColumnName = '{ column . Name } '") [ 0 ] [ "DataType" ] as Type ;
78+ }
79+ }
80+
81+ con . Close ( ) ;
82+ }
83+
84+ DbToClasses ( conf . Database , database , conf . GenerateConstructorAndOutput ) ;
85+ if ( conf . GenerateMarkupPages )
86+ DbToMarkupPage ( string . IsNullOrEmpty ( conf . MarkupDatabaseNameReplacement ) ? conf . Database : conf . MarkupDatabaseNameReplacement , database ) ;
87+ Console . WriteLine ( "Successfully generated C# classes!" ) ;
88+ }
89+ Console . ReadLine ( ) ;
5190 }
52- }
5391
54- class Program
55- {
5692 private static void DbToClasses ( string dbName , Dictionary < string , List < Column > > db , bool generateConstructorAndOutput )
5793 {
5894 if ( ! Directory . Exists ( dbName ) )
@@ -84,7 +120,7 @@ private static void DbToClasses(string dbName, Dictionary<string, List<Column>>
84120 sb . AppendLine ( $ "}}{ Environment . NewLine } ") ;
85121
86122 // update query
87- sb . AppendLine ( $ "public string UpdateQuery()") ;
123+ sb . AppendLine ( "public string UpdateQuery()" ) ;
88124 sb . AppendLine ( "{" ) ;
89125 sb . Append ( $ "return $\" UPDATE `{ table . Key } ` SET") ;
90126 foreach ( var column in table . Value )
@@ -94,7 +130,7 @@ private static void DbToClasses(string dbName, Dictionary<string, List<Column>>
94130 sb . AppendLine ( $ "}}{ Environment . NewLine } ") ;
95131
96132 // insert query
97- sb . AppendLine ( $ "public string InsertQuery()") ;
133+ sb . AppendLine ( "public string InsertQuery()" ) ;
98134 sb . AppendLine ( "{" ) ;
99135 sb . Append ( $ "return $\" INSERT INTO `{ table . Key } ` VALUES (") ;
100136 foreach ( var column in table . Value )
@@ -103,7 +139,7 @@ private static void DbToClasses(string dbName, Dictionary<string, List<Column>>
103139 sb . AppendLine ( $ ");\" ;{ Environment . NewLine } }}{ Environment . NewLine } ") ;
104140
105141 // delete query
106- sb . AppendLine ( $ "public string DeleteQuery()") ;
142+ sb . AppendLine ( "public string DeleteQuery()" ) ;
107143 sb . AppendLine ( "{" ) ;
108144 sb . AppendLine ( $ "return $\" DELETE FROM `{ table . Key } ` WHERE { table . Value [ 0 ] . Name } = {{{table.Value[0].Name.FirstCharUpper()}}};\" ;") ;
109145 sb . AppendLine ( "}" ) ;
@@ -164,87 +200,6 @@ private static void DbToMarkupPage(string dbName, Dictionary<string, List<Column
164200 sw . Close ( ) ;
165201 sb . Clear ( ) ;
166202 }
167-
168- }
169-
170- static void Main ( string [ ] args )
171- {
172- var parser = new FluentCommandLineParser < ApplicationArguments > ( ) ;
173- parser . Setup ( arg => arg . IP ) . As ( 'i' , "ip" ) . SetDefault ( "127.0.0.1" ) . WithDescription ( "(optional) IP address of the MySQL server, will use 127.0.0.1 if not specified" ) ;
174- parser . Setup ( arg => arg . Port ) . As ( 'n' , "port" ) . SetDefault ( 3306 ) . WithDescription ( "(optional) Port number of the MySQL server, will use 3306 if not specified" ) ;
175- parser . Setup ( arg => arg . User ) . As ( 'u' , "user" ) . SetDefault ( "root" ) . WithDescription ( "(optional) Username, will use root if not specified" ) ;
176- parser . Setup ( arg => arg . Password ) . As ( 'p' , "password" ) . SetDefault ( String . Empty ) . WithDescription ( "(optional) Password, will use empty password if not specified" ) ;
177- parser . Setup ( arg => arg . Database ) . As ( 'd' , "database" ) . Required ( ) . WithDescription ( "Database name" ) ;
178- parser . Setup ( arg => arg . Table ) . As ( 't' , "table" ) . SetDefault ( String . Empty ) . WithDescription ( "(optional) Table name, will generate entire database if not specified" ) ;
179- parser . Setup ( arg => arg . GenerateConstructorAndOutput ) . As ( 'g' , "generateconstructorandoutput" )
180- . SetDefault ( false ) . WithDescription ( "(optional) Generate a reading constructor and SQL statement output - Activate with -g true" ) ;
181- parser . Setup ( arg => arg . GenerateMarkupPages ) . As ( 'm' , "generatemarkuppages" )
182- . SetDefault ( false )
183- . WithDescription ( "(optional) Generate markup pages for database and tables which can be used in wikis - Activate with -m true" ) ;
184- parser . Setup ( arg => arg . MarkupDatabaseNameReplacement ) . As ( 'r' , "markupdatabasenamereplacement" )
185- . SetDefault ( "" ) . WithDescription ( "(optional) Will use this instead of database name for wiki breadcrump generation" ) ;
186- parser . SetupHelp ( "?" , "help" ) . Callback ( text => Console . WriteLine ( text ) ) ;
187-
188- var result = parser . Parse ( args ) ;
189- if ( ! result . HasErrors )
190- {
191- var conf = parser . Object as ApplicationArguments ;
192- if ( conf . Database is null )
193- {
194- Console . WriteLine ( "You didn't specify a database" ) ;
195- return ;
196- }
197-
198- var confString =
199- $ "Server={ conf . IP } ;Port={ conf . Port } ;Uid={ conf . User } ;Pwd={ conf . Password } ;Database={ conf . Database } ";
200- Console . WriteLine ( confString ) ;
201-
202- var database = new Dictionary < string , List < Column > > ( ) ;
203-
204- using ( var con = new MySqlConnection ( confString ) )
205- {
206- con . Open ( ) ;
207-
208- using ( var cmd = con . CreateCommand ( ) )
209- {
210- cmd . CommandText =
211- $ "SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '{ conf . Database } '";
212- if ( ! conf . Table . Equals ( string . Empty ) )
213- cmd . CommandText += $ " AND TABLE_NAME = '{ conf . Table } '";
214-
215- var reader = cmd . ExecuteReader ( ) ;
216- if ( ! reader . HasRows )
217- return ;
218-
219- while ( reader . Read ( ) )
220- if ( database . ContainsKey ( reader . GetString ( 0 ) ) )
221- database [ reader . GetString ( 0 ) ] . Add ( new Column ( reader ) ) ;
222- else
223- database . Add ( reader . GetString ( 0 ) , new List < Column > ( ) { new Column ( reader ) } ) ;
224- }
225-
226- foreach ( var table in database )
227- {
228- using ( var cmd = con . CreateCommand ( ) )
229- {
230- // lul - is there a way to do this without this senseless statement?
231- cmd . CommandText = $ "SELECT * FROM `{ table . Key } ` LIMIT 0";
232- var reader = cmd . ExecuteReader ( ) ;
233- var schema = reader . GetSchemaTable ( ) ;
234- foreach ( var column in table . Value )
235- column . Type = schema . Select ( $ "ColumnName = '{ column . Name } '") [ 0 ] [ "DataType" ] as Type ;
236- }
237- }
238-
239- con . Close ( ) ;
240- }
241-
242- DbToClasses ( conf . Database , database , conf . GenerateConstructorAndOutput ) ;
243- if ( conf . GenerateMarkupPages )
244- DbToMarkupPage ( String . IsNullOrEmpty ( conf . MarkupDatabaseNameReplacement ) ? conf . Database : conf . MarkupDatabaseNameReplacement , database ) ;
245- Console . WriteLine ( "Successfully generated C# classes!" ) ;
246- }
247- Console . ReadLine ( ) ;
248203 }
249204 }
250205}
0 commit comments