subsonic 3.0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. data/lib/LICENSE.txt +41 -0
  2. data/lib/SubSonic.Core.dll +0 -0
  3. data/lib/T4 Templates/ActiveRecord/ActiveRecord.tt +620 -0
  4. data/lib/T4 Templates/ActiveRecord/Context.tt +295 -0
  5. data/lib/T4 Templates/ActiveRecord/SQLServer.ttinclude +347 -0
  6. data/lib/T4 Templates/ActiveRecord/Settings.ttinclude +552 -0
  7. data/lib/T4 Templates/ActiveRecord/StoredProcedures.tt +30 -0
  8. data/lib/T4 Templates/ActiveRecord/Structs.tt +67 -0
  9. data/lib/T4 Templates/LinqTemplates/Classes.tt +117 -0
  10. data/lib/T4 Templates/LinqTemplates/Context.tt +276 -0
  11. data/lib/T4 Templates/LinqTemplates/SQLServer.ttinclude +349 -0
  12. data/lib/T4 Templates/LinqTemplates/Settings.ttinclude +551 -0
  13. data/lib/T4 Templates/LinqTemplates/StoredProcedures.tt +30 -0
  14. data/lib/T4 Templates/LinqTemplates/Structs.tt +67 -0
  15. data/lib/T4 Templates/README.txt +7 -0
  16. data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/ActiveRecord.tt +560 -0
  17. data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/ActiveRecord.vb +6447 -0
  18. data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/Context.tt +258 -0
  19. data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/Context.vb +349 -0
  20. data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/SQLServer.ttinclude +332 -0
  21. data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/Settings.ttinclude +550 -0
  22. data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/StoredProcedures.tt +30 -0
  23. data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/StoredProcedures.vb +55 -0
  24. data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/Structs.tt +57 -0
  25. data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/Structs.vb +1478 -0
  26. data/lib/T4 Templates/SubSonic.TemplatesVB/ActiveRecord/Tests/FetchTests.vb +52 -0
  27. data/lib/T4 Templates/SubSonic.TemplatesVB/App.config +9 -0
  28. data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/Application.Designer.vb +13 -0
  29. data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/Application.myapp +10 -0
  30. data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/AssemblyInfo.vb +35 -0
  31. data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/Resources.Designer.vb +63 -0
  32. data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/Resources.resx +117 -0
  33. data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/Settings.Designer.vb +73 -0
  34. data/lib/T4 Templates/SubSonic.TemplatesVB/My Project/Settings.settings +7 -0
  35. data/lib/T4 Templates/SubSonic.TemplatesVB/SubSonic.TemplatesVB.vbproj +171 -0
  36. data/lib/T4 Templates/SubSonic.TemplatesVB/SubSonic.TemplatesVB.vbproj.user +5 -0
  37. data/lib/T4 Templates/TemplateProviders/MySQL.ttinclude +278 -0
  38. data/lib/T4 Templates/TemplateProviders/MySQL.ttinclude.orig +303 -0
  39. data/lib/T4 Templates/TemplateProviders/MySQLTest.tt +27 -0
  40. data/lib/T4 Templates/TemplateProviders/SQLite.ttinclude +194 -0
  41. data/lib/T4 Templates/TemplateProviders/SQLite.ttinclude.orig +236 -0
  42. data/lib/T4 Templates/TemplateProviders/SQLiteTest.tt +27 -0
  43. data/lib/T4 Templates/TemplateProviders/Settings.ttinclude +551 -0
  44. metadata +112 -0
@@ -0,0 +1,332 @@
1
+ <#@ include file="Settings.ttinclude" #>
2
+ <#+
3
+
4
+ IDataReader GetReader(string sql){
5
+ SqlConnection conn=new SqlConnection(ConnectionString);
6
+ SqlCommand cmd=new SqlCommand(sql,conn);
7
+ conn.Open();
8
+ return cmd.ExecuteReader(CommandBehavior.CloseConnection);
9
+ }
10
+ SqlCommand GetCommand(string sql){
11
+ SqlConnection conn=new SqlConnection(ConnectionString);
12
+ SqlCommand cmd=new SqlCommand(sql,conn);
13
+ conn.Open();
14
+ return cmd;
15
+ }
16
+
17
+ const string FKSql=@"SELECT
18
+ ThisTable = FK.TABLE_NAME,
19
+ ThisColumn = CU.COLUMN_NAME,
20
+ OtherTable = PK.TABLE_NAME,
21
+ OtherColumn = PT.COLUMN_NAME,
22
+ Constraint_Name = C.CONSTRAINT_NAME,
23
+ Owner = FK.TABLE_SCHEMA
24
+ FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
25
+ INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
26
+ INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
27
+ INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
28
+ INNER JOIN
29
+ (
30
+ SELECT i1.TABLE_NAME, i2.COLUMN_NAME
31
+ FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
32
+ INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
33
+ WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
34
+ )
35
+ PT ON PT.TABLE_NAME = PK.TABLE_NAME
36
+ WHERE FK.Table_NAME=@tableName OR PK.Table_NAME=@tableName";
37
+
38
+
39
+ const string TABLE_SQL=@"SELECT *
40
+ FROM INFORMATION_SCHEMA.TABLES
41
+ WHERE TABLE_TYPE='BASE TABLE'";
42
+
43
+ const string COLUMN_SQL=@"SELECT
44
+ TABLE_CATALOG AS [Database],
45
+ TABLE_SCHEMA AS Owner,
46
+ TABLE_NAME AS TableName,
47
+ COLUMN_NAME AS ColumnName,
48
+ ORDINAL_POSITION AS OrdinalPosition,
49
+ COLUMN_DEFAULT AS DefaultSetting,
50
+ IS_NULLABLE AS IsNullable, DATA_TYPE AS DataType,
51
+ CHARACTER_MAXIMUM_LENGTH AS MaxLength,
52
+ DATETIME_PRECISION AS DatePrecision,
53
+ COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') AS IsIdentity,
54
+ COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsComputed') as IsComputed
55
+ FROM INFORMATION_SCHEMA.COLUMNS
56
+ WHERE TABLE_NAME=@tableName
57
+ ORDER BY OrdinalPosition ASC";
58
+
59
+
60
+ List<SPParam> GetSPParams(string spName){
61
+ var result=new List<SPParam>();
62
+ string[] restrictions = new string[4] { DatabaseName, null, spName, null };
63
+ using(SqlConnection conn=new SqlConnection(ConnectionString)){
64
+ conn.Open();
65
+ var sprocs=conn.GetSchema("ProcedureParameters", restrictions);
66
+ conn.Close();
67
+ foreach(DataRow row in sprocs.Rows){
68
+ SPParam p=new SPParam();
69
+ p.SysType=GetSysType(row["DATA_TYPE"].ToString());
70
+ p.Name=row["PARAMETER_NAME"].ToString().Replace("@","");
71
+ p.CleanName=CleanUp(p.Name);
72
+ result.Add(p);
73
+ }
74
+
75
+
76
+ }
77
+ return result;
78
+ }
79
+ List<SP> GetSPs(){
80
+ var result=new List<SP>();
81
+ //pull the SPs
82
+
83
+ DataTable sprocs=null;
84
+ //DataTable parameters=null;
85
+
86
+ using(SqlConnection conn=new SqlConnection(ConnectionString)){
87
+ conn.Open();
88
+ sprocs=conn.GetSchema("Procedures");
89
+ conn.Close();
90
+ }
91
+
92
+ foreach(DataRow row in sprocs.Rows){
93
+ string spType=row["ROUTINE_TYPE"].ToString();
94
+ var sp=new SP();
95
+ sp.Name=row["ROUTINE_NAME"].ToString();
96
+
97
+ if(spType=="PROCEDURE" &! sp.Name.StartsWith("sp_")){
98
+
99
+ sp.CleanName=CleanUp(sp.Name);
100
+
101
+ sp.Parameters=GetSPParams(sp.Name);
102
+ result.Add(sp);
103
+ }
104
+ }
105
+ return result;
106
+
107
+ }
108
+
109
+
110
+ List<Table> LoadTables(){
111
+ var result=new List<Table>();
112
+
113
+ //pull the tables in a reader
114
+ using(IDataReader rdr=GetReader(TABLE_SQL)){
115
+ while(rdr.Read()){
116
+ Table tbl=new Table();
117
+ tbl.Name=rdr["TABLE_NAME"].ToString();
118
+ tbl.Schema=rdr["TABLE_SCHEMA"].ToString();
119
+ tbl.Columns=LoadColumns(tbl);
120
+ tbl.PrimaryKey=GetPK(tbl.Name);
121
+ tbl.CleanName=CleanUp(tbl.Name);
122
+ tbl.ClassName=Inflector.MakeSingular(tbl.CleanName);
123
+ tbl.QueryableName=Inflector.MakePlural(tbl.ClassName);
124
+
125
+ //set the PK for the columns
126
+ var pkColumn=tbl.Columns.SingleOrDefault(x=>x.Name.ToLower().Trim()==tbl.PrimaryKey.ToLower().Trim());
127
+ if(pkColumn!=null)
128
+ pkColumn.IsPK=true;
129
+
130
+ tbl.FKTables=LoadFKTables(tbl.Name);
131
+
132
+ result.Add(tbl);
133
+ }
134
+ }
135
+
136
+ foreach(Table tbl in result){
137
+ //loop the FK tables and see if there's a match for our FK columns
138
+ foreach(Column col in tbl.Columns){
139
+ col.IsForeignKey=tbl.FKTables.Any(
140
+ x=>x.ThisColumn.Equals(col.Name,StringComparison.InvariantCultureIgnoreCase)
141
+ );
142
+ }
143
+ }
144
+ return result;
145
+ }
146
+
147
+ List<Column> LoadColumns(Table tbl){
148
+ var result=new List<Column>();
149
+ var cmd=GetCommand(COLUMN_SQL);
150
+ cmd.Parameters.AddWithValue("@tableName",tbl.Name);
151
+
152
+ using(IDataReader rdr=cmd.ExecuteReader(CommandBehavior.CloseConnection)){
153
+ while(rdr.Read()){
154
+ Column col=new Column();
155
+ col.Name=rdr["ColumnName"].ToString();
156
+ col.CleanName=CleanUp(col.Name);
157
+ col.DataType=rdr["DataType"].ToString();
158
+ col.SysType=GetSysType(col.DataType);
159
+ col.DbType=GetDbType(col.DataType);
160
+ col.AutoIncrement=rdr["IsIdentity"].ToString()=="1";
161
+ col.IsNullable=rdr["IsNullable"].ToString()=="YES";
162
+ int.TryParse(rdr["MaxLength"].ToString(),out col.MaxLength);
163
+
164
+ result.Add(col);
165
+ }
166
+
167
+ }
168
+
169
+ return result;
170
+ }
171
+
172
+ List<FKTable> LoadFKTables(string tableName){
173
+
174
+ //this is a "bi-directional" scheme
175
+ //which pulls both 1-many and many-1
176
+
177
+ var result=new List<FKTable>();
178
+ var cmd=GetCommand(FKSql);
179
+ cmd.Parameters.AddWithValue("@tableName",tableName);
180
+ using(IDataReader rdr=cmd.ExecuteReader(CommandBehavior.CloseConnection)){
181
+ while(rdr.Read()){
182
+ FKTable fk=new FKTable();
183
+ string thisTable=rdr["ThisTable"].ToString();
184
+
185
+ if(tableName.ToLower()==thisTable.ToLower()){
186
+ fk.ThisTable=rdr["ThisTable"].ToString();
187
+ fk.ThisColumn=rdr["ThisColumn"].ToString();
188
+ fk.OtherTable=rdr["OtherTable"].ToString();
189
+ fk.OtherColumn=rdr["OtherColumn"].ToString();
190
+
191
+ }else{
192
+ fk.ThisTable=rdr["OtherTable"].ToString();
193
+ fk.ThisColumn=rdr["OtherColumn"].ToString();
194
+ fk.OtherTable=rdr["ThisTable"].ToString();
195
+ fk.OtherColumn=rdr["ThisColumn"].ToString();
196
+
197
+ }
198
+
199
+ fk.OtherClass=Inflector.MakeSingular(CleanUp(fk.OtherTable));
200
+ fk.OtherQueryable=Inflector.MakePlural(fk.OtherClass);
201
+
202
+ result.Add(fk);
203
+ }
204
+ }
205
+ return result;
206
+
207
+ }
208
+
209
+ string GetPK(string table){
210
+
211
+ string pk="";
212
+ DataTable pkTable=new DataTable();
213
+ string sql=@"SELECT KCU.COLUMN_NAME
214
+ FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU
215
+ JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
216
+ ON KCU.CONSTRAINT_NAME=TC.CONSTRAINT_NAME
217
+ WHERE TC.CONSTRAINT_TYPE='PRIMARY KEY'
218
+ AND KCU.TABLE_NAME=@tableName";
219
+
220
+ var cmd=GetCommand(sql);
221
+ cmd.Parameters.AddWithValue("@tableName",table);
222
+ var result=cmd.ExecuteScalar();
223
+ cmd.Dispose();
224
+ if(result!=null)
225
+ pk=result.ToString();
226
+
227
+ return pk;
228
+ }
229
+
230
+ string GetSysType(string sqlType){
231
+ string sysType="String";
232
+ switch (sqlType) {
233
+ case "bigint":
234
+ sysType = "Long";
235
+ break;
236
+ case "smallint":
237
+ sysType= "Short";
238
+ break;
239
+ case "int":
240
+ sysType= "Integer";
241
+ break;
242
+ case "uniqueidentifier":
243
+ sysType= "Guid";
244
+ break;
245
+ case "smalldatetime":
246
+ case "datetime":
247
+ sysType= "Date";
248
+ break;
249
+ case "float":
250
+ sysType="Double";
251
+ break;
252
+ case "real":
253
+ case "numeric":
254
+ case "smallmoney":
255
+ case "decimal":
256
+ case "money":
257
+ sysType= "Decimal";
258
+ break;
259
+ case "bit":
260
+ sysType= "Boolean";
261
+ break;
262
+ case "image":
263
+ case "binary":
264
+ case "tinyint":
265
+ case "varbinary":
266
+ sysType= "Byte()";
267
+ break;
268
+ }
269
+ return sysType;
270
+ }
271
+ DbType GetDbType(string sqlType){
272
+ switch(sqlType)
273
+ {
274
+ case "varchar":
275
+ return DbType.AnsiString;
276
+ case "nvarchar":
277
+ return DbType.String;
278
+ case "int":
279
+ return DbType.Int32;
280
+ case "uniqueidentifier":
281
+ return DbType.Guid;
282
+ case "datetime":
283
+ return DbType.DateTime;
284
+ case "bigint":
285
+ return DbType.Int64;
286
+ case "binary":
287
+ return DbType.Binary;
288
+ case "bit":
289
+ return DbType.Boolean;
290
+ case "char":
291
+ return DbType.AnsiStringFixedLength;
292
+ case "decimal":
293
+ return DbType.Decimal;
294
+ case "float":
295
+ return DbType.Double;
296
+ case "image":
297
+ return DbType.Binary;
298
+ case "money":
299
+ return DbType.Currency;
300
+ case "nchar":
301
+ return DbType.String;
302
+ case "ntext":
303
+ return DbType.String;
304
+ case "numeric":
305
+ return DbType.Decimal;
306
+ case "real":
307
+ return DbType.Single;
308
+ case "smalldatetime":
309
+ return DbType.DateTime;
310
+ case "smallint":
311
+ return DbType.Int16;
312
+ case "smallmoney":
313
+ return DbType.Currency;
314
+ case "sql_variant":
315
+ return DbType.String;
316
+ case "sysname":
317
+ return DbType.String;
318
+ case "text":
319
+ return DbType.AnsiString;
320
+ case "timestamp":
321
+ return DbType.Binary;
322
+ case "tinyint":
323
+ return DbType.Byte;
324
+ case "varbinary":
325
+ return DbType.Binary;
326
+ default:
327
+ return DbType.AnsiString;
328
+ }
329
+
330
+ }
331
+
332
+ #>
@@ -0,0 +1,550 @@
1
+ <#@ template language="C#v3.5" debug="True" hostspecific="True" #>
2
+ <#@ assembly name="EnvDTE" #>
3
+ <#@ assembly name="System.Core.dll" #>
4
+ <#@ assembly name="System.Data" #>
5
+ <#@ assembly name="System.Xml" #>
6
+ <#@ assembly name="System.Configuration" #>
7
+ <#@ import namespace="System.Collections.Generic" #>
8
+ <#@ import namespace="System.Data" #>
9
+ <#@ import namespace="System.Data.SqlClient" #>
10
+ <#@ import namespace="System.Data.Common" #>
11
+ <#@ import namespace="System.Diagnostics" #>
12
+ <#@ import namespace="System.Globalization" #>
13
+ <#@ import namespace="System.IO" #>
14
+ <#@ import namespace="System.Linq" #>
15
+ <#@ import namespace="System.Text" #>
16
+ <#@ import namespace="System.Text.RegularExpressions" #>
17
+ <#@ import namespace="System.Configuration" #>
18
+
19
+ <#+
20
+
21
+ const string Namespace = "Southwind";
22
+ const string ConnectionStringName = "Northwind";
23
+
24
+ //This is the name of your database and is used in naming
25
+ //the repository. By default we set it to the connection string name
26
+ const string DatabaseName = "Northwind";
27
+
28
+ const string ColumnSuffix = "Field";
29
+
30
+ //this is a list of tables you don't want generated
31
+ string[] ExcludeTables = new string[]{
32
+ "sysdiagrams",
33
+ "BuildVersion",
34
+ };
35
+
36
+ string CleanUp(string tableName){
37
+ string result=tableName;
38
+
39
+ //strip blanks
40
+ result=result.Replace(" ","");
41
+
42
+ //put your logic here...
43
+
44
+ return result;
45
+ }
46
+ string CheckNullable(Column col){
47
+ string result="";
48
+ if(col.IsNullable && col.SysType !="Byte()" && col.SysType !="String")
49
+ result="?";
50
+ return result;
51
+ }
52
+ string GetConnectionString(string connectionStringName){
53
+ var _CurrentProject = GetCurrentProject();
54
+
55
+ string result="";
56
+ ExeConfigurationFileMap configFile = new ExeConfigurationFileMap();
57
+ configFile.ExeConfigFilename = GetConfigPath();
58
+
59
+ if (string.IsNullOrEmpty(configFile.ExeConfigFilename))
60
+ throw new ArgumentNullException("The project does not contain App.config or Web.config file.");
61
+
62
+
63
+ var config = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);
64
+ var connSection=config.ConnectionStrings;
65
+
66
+ //if the connectionString is empty - which is the defauls
67
+ //look for count-1 - this is the last connection string
68
+ //and takes into account AppServices and LocalSqlServer
69
+ if(string.IsNullOrEmpty(connectionStringName)){
70
+ if(connSection.ConnectionStrings.Count>1){
71
+ result=connSection.ConnectionStrings[connSection.ConnectionStrings.Count-1].ConnectionString;
72
+ }
73
+ }else{
74
+ try{
75
+ result=connSection.ConnectionStrings[connectionStringName].ConnectionString;
76
+ }catch{
77
+ result="There is no connection string name called '"+connectionStringName+"'";
78
+ }
79
+ }
80
+
81
+ return result;
82
+ }
83
+
84
+ string _connectionString="";
85
+ public string ConnectionString{
86
+ get {
87
+ if(String.IsNullOrEmpty(_connectionString)){
88
+
89
+ _connectionString=GetConnectionString(ConnectionStringName);
90
+
91
+ }
92
+
93
+ if(_connectionString.Contains("|DataDirectory|")){
94
+ //have to replace it
95
+ string dataFilePath=GetDataDirectory();
96
+ _connectionString=_connectionString.Replace("|DataDirectory|",dataFilePath);
97
+ }
98
+
99
+ return _connectionString;
100
+ }
101
+ }
102
+
103
+ public EnvDTE.Project GetCurrentProject() {
104
+
105
+ IServiceProvider _ServiceProvider = (IServiceProvider)Host;
106
+ if (_ServiceProvider == null)
107
+ throw new Exception("Host property returned unexpected value (null)");
108
+
109
+ EnvDTE.DTE dte = (EnvDTE.DTE)_ServiceProvider.GetService(typeof(EnvDTE.DTE));
110
+ if (dte == null)
111
+ throw new Exception("Unable to retrieve EnvDTE.DTE");
112
+
113
+ Array activeSolutionProjects = (Array)dte.ActiveSolutionProjects;
114
+ if (activeSolutionProjects == null)
115
+ throw new Exception("DTE.ActiveSolutionProjects returned null");
116
+
117
+ EnvDTE.Project dteProject = (EnvDTE.Project)activeSolutionProjects.GetValue(0);
118
+ if (dteProject == null)
119
+ throw new Exception("DTE.ActiveSolutionProjects[0] returned null");
120
+
121
+ return dteProject;
122
+
123
+ }
124
+
125
+ private string GetProjectPath()
126
+ {
127
+ EnvDTE.Project project = GetCurrentProject();
128
+ System.IO.FileInfo info = new System.IO.FileInfo(project.FullName);
129
+ return info.Directory.FullName;
130
+ }
131
+
132
+ private string GetConfigPath()
133
+ {
134
+ EnvDTE.Project project = GetCurrentProject();
135
+ foreach (EnvDTE.ProjectItem item in project.ProjectItems)
136
+ {
137
+ // if it is the app.config file, then open it up
138
+ if (item.Name.Equals("App.config",StringComparison.InvariantCultureIgnoreCase) || item.Name.Equals("Web.config",StringComparison.InvariantCultureIgnoreCase))
139
+ return GetProjectPath() + "\\" + item.Name;
140
+ }
141
+ return String.Empty;
142
+ }
143
+
144
+ public string GetDataDirectory(){
145
+ EnvDTE.Project project=GetCurrentProject();
146
+ return System.IO.Path.GetDirectoryName(project.FileName)+"\\App_Data\\";
147
+ }
148
+
149
+ public class Table{
150
+
151
+ public List<Column> Columns;
152
+ public List<FKTable> FKTables;
153
+ public string Name;
154
+ public string CleanName;
155
+ public string ClassName;
156
+ public string PrimaryKey;
157
+ public string Schema;
158
+ public string QueryableName;
159
+
160
+ public bool HasLogicalDelete(){
161
+ return this.Columns.Any(x=>x.Name.ToLower()=="deleted" || x.Name.ToLower()=="isdeleted");
162
+ }
163
+ public Column DeleteColumn{
164
+ get{
165
+ Column result=null;
166
+ if(this.Columns.Any(x=>x.Name.ToLower()=="deleted"))
167
+ result=this.Columns.Single(x=>x.Name.ToLower()=="deleted");
168
+ if(this.Columns.Any(x=>x.Name.ToLower()=="isdeleted"))
169
+ result=this.Columns.Single(x=>x.Name.ToLower()=="isdeleted");
170
+ return result;
171
+ }
172
+ }
173
+ public Column PK{
174
+ get{
175
+ return this.Columns.SingleOrDefault(x=>x.IsPK) ?? this.Columns[0];
176
+ }
177
+ }
178
+ public Column Descriptor{
179
+ get{
180
+ if(this.Columns.Count==1){
181
+ return this.Columns[0];
182
+ }else{
183
+ //get the first string column
184
+ Column result=null;
185
+ result=this.Columns.FirstOrDefault(x=>x.SysType.ToLower().Trim()=="string");
186
+ if(result==null)
187
+ result=this.Columns[1];
188
+ return result;
189
+ }
190
+ }
191
+ }
192
+ }
193
+
194
+ public class Column{
195
+ public string Name;
196
+ public string CleanName;
197
+ public string SysType;
198
+ public string DataType;
199
+ public DbType DbType;
200
+ public bool AutoIncrement;
201
+ public bool IsPK;
202
+ public int MaxLength;
203
+ public bool IsNullable;
204
+ public bool IsForeignKey;
205
+ }
206
+ public class FKTable{
207
+ public string ThisTable;
208
+ public string ThisColumn;
209
+ public string OtherTable;
210
+ public string OtherColumn;
211
+ public string OtherClass;
212
+ public string OtherQueryable;
213
+ }
214
+
215
+ public class SP{
216
+ public string Name;
217
+ public string CleanName;
218
+ public string ClassName;
219
+ public List<SPParam> Parameters;
220
+ public SP(){
221
+ Parameters=new List<SPParam>();
222
+ }
223
+ public string ArgList{
224
+ get{
225
+ StringBuilder sb=new StringBuilder();
226
+ int loopCount=1;
227
+ foreach(var par in Parameters){
228
+ sb.AppendFormat("{1} As {0}", par.SysType,par.CleanName);
229
+ if(loopCount<Parameters.Count)
230
+ sb.Append(",");
231
+ loopCount++;
232
+ }
233
+ return sb.ToString();
234
+ }
235
+ }
236
+ }
237
+ public class SPParam{
238
+ public string Name;
239
+ public string CleanName;
240
+ public string SysType;
241
+
242
+ }
243
+
244
+
245
+ /*
246
+ * SubSonic - http://subsonicproject.com
247
+ *
248
+ * The contents of this file are subject to the New BSD
249
+ * License (the "License"); you may not use this file
250
+ * except in compliance with the License. You may obtain a copy of
251
+ * the License at http://www.opensource.org/licenses/bsd-license.php
252
+ *
253
+ * Software distributed under the License is distributed on an
254
+ * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
255
+ * implied. See the License for the specific language governing
256
+ * rights and limitations under the License.
257
+ */
258
+
259
+ /// <summary>
260
+ /// Summary for the Inflector class
261
+ /// </summary>
262
+ public static class Inflector {
263
+ private static readonly List<InflectorRule> _plurals = new List<InflectorRule>();
264
+ private static readonly List<InflectorRule> _singulars = new List<InflectorRule>();
265
+ private static readonly List<string> _uncountables = new List<string>();
266
+
267
+ /// <summary>
268
+ /// Initializes the <see cref="Inflector"/> class.
269
+ /// </summary>
270
+ static Inflector() {
271
+ AddPluralRule("$", "s");
272
+ AddPluralRule("s$", "s");
273
+ AddPluralRule("(ax|test)is$", "$1es");
274
+ AddPluralRule("(octop|vir)us$", "$1i");
275
+ AddPluralRule("(alias|status)$", "$1es");
276
+ AddPluralRule("(bu)s$", "$1ses");
277
+ AddPluralRule("(buffal|tomat)o$", "$1oes");
278
+ AddPluralRule("([ti])um$", "$1a");
279
+ AddPluralRule("sis$", "ses");
280
+ AddPluralRule("(?:([^f])fe|([lr])f)$", "$1$2ves");
281
+ AddPluralRule("(hive)$", "$1s");
282
+ AddPluralRule("([^aeiouy]|qu)y$", "$1ies");
283
+ AddPluralRule("(x|ch|ss|sh)$", "$1es");
284
+ AddPluralRule("(matr|vert|ind)ix|ex$", "$1ices");
285
+ AddPluralRule("([m|l])ouse$", "$1ice");
286
+ AddPluralRule("^(ox)$", "$1en");
287
+ AddPluralRule("(quiz)$", "$1zes");
288
+
289
+ AddSingularRule("s$", String.Empty);
290
+ AddSingularRule("ss$", "ss");
291
+ AddSingularRule("(n)ews$", "$1ews");
292
+ AddSingularRule("([ti])a$", "$1um");
293
+ AddSingularRule("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", "$1$2sis");
294
+ AddSingularRule("(^analy)ses$", "$1sis");
295
+ AddSingularRule("([^f])ves$", "$1fe");
296
+ AddSingularRule("(hive)s$", "$1");
297
+ AddSingularRule("(tive)s$", "$1");
298
+ AddSingularRule("([lr])ves$", "$1f");
299
+ AddSingularRule("([^aeiouy]|qu)ies$", "$1y");
300
+ AddSingularRule("(s)eries$", "$1eries");
301
+ AddSingularRule("(m)ovies$", "$1ovie");
302
+ AddSingularRule("(x|ch|ss|sh)es$", "$1");
303
+ AddSingularRule("([m|l])ice$", "$1ouse");
304
+ AddSingularRule("(bus)es$", "$1");
305
+ AddSingularRule("(o)es$", "$1");
306
+ AddSingularRule("(shoe)s$", "$1");
307
+ AddSingularRule("(cris|ax|test)es$", "$1is");
308
+ AddSingularRule("(octop|vir)i$", "$1us");
309
+ AddSingularRule("(alias|status)$", "$1");
310
+ AddSingularRule("(alias|status)es$", "$1");
311
+ AddSingularRule("^(ox)en", "$1");
312
+ AddSingularRule("(vert|ind)ices$", "$1ex");
313
+ AddSingularRule("(matr)ices$", "$1ix");
314
+ AddSingularRule("(quiz)zes$", "$1");
315
+
316
+ AddIrregularRule("person", "people");
317
+ AddIrregularRule("man", "men");
318
+ AddIrregularRule("child", "children");
319
+ AddIrregularRule("sex", "sexes");
320
+ AddIrregularRule("tax", "taxes");
321
+ AddIrregularRule("move", "moves");
322
+
323
+ AddUnknownCountRule("equipment");
324
+ AddUnknownCountRule("information");
325
+ AddUnknownCountRule("rice");
326
+ AddUnknownCountRule("money");
327
+ AddUnknownCountRule("species");
328
+ AddUnknownCountRule("series");
329
+ AddUnknownCountRule("fish");
330
+ AddUnknownCountRule("sheep");
331
+ }
332
+
333
+ /// <summary>
334
+ /// Adds the irregular rule.
335
+ /// </summary>
336
+ /// <param name="singular">The singular.</param>
337
+ /// <param name="plural">The plural.</param>
338
+ private static void AddIrregularRule(string singular, string plural) {
339
+ AddPluralRule(String.Concat("(", singular[0], ")", singular.Substring(1), "$"), String.Concat("$1", plural.Substring(1)));
340
+ AddSingularRule(String.Concat("(", plural[0], ")", plural.Substring(1), "$"), String.Concat("$1", singular.Substring(1)));
341
+ }
342
+
343
+ /// <summary>
344
+ /// Adds the unknown count rule.
345
+ /// </summary>
346
+ /// <param name="word">The word.</param>
347
+ private static void AddUnknownCountRule(string word) {
348
+ _uncountables.Add(word.ToLower());
349
+ }
350
+
351
+ /// <summary>
352
+ /// Adds the plural rule.
353
+ /// </summary>
354
+ /// <param name="rule">The rule.</param>
355
+ /// <param name="replacement">The replacement.</param>
356
+ private static void AddPluralRule(string rule, string replacement) {
357
+ _plurals.Add(new InflectorRule(rule, replacement));
358
+ }
359
+
360
+ /// <summary>
361
+ /// Adds the singular rule.
362
+ /// </summary>
363
+ /// <param name="rule">The rule.</param>
364
+ /// <param name="replacement">The replacement.</param>
365
+ private static void AddSingularRule(string rule, string replacement) {
366
+ _singulars.Add(new InflectorRule(rule, replacement));
367
+ }
368
+
369
+ /// <summary>
370
+ /// Makes the plural.
371
+ /// </summary>
372
+ /// <param name="word">The word.</param>
373
+ /// <returns></returns>
374
+ public static string MakePlural(string word) {
375
+ return ApplyRules(_plurals, word);
376
+ }
377
+
378
+ /// <summary>
379
+ /// Makes the singular.
380
+ /// </summary>
381
+ /// <param name="word">The word.</param>
382
+ /// <returns></returns>
383
+ public static string MakeSingular(string word) {
384
+ return ApplyRules(_singulars, word);
385
+ }
386
+
387
+ /// <summary>
388
+ /// Applies the rules.
389
+ /// </summary>
390
+ /// <param name="rules">The rules.</param>
391
+ /// <param name="word">The word.</param>
392
+ /// <returns></returns>
393
+ private static string ApplyRules(IList<InflectorRule> rules, string word) {
394
+ string result = word;
395
+ if (!_uncountables.Contains(word.ToLower())) {
396
+ for (int i = rules.Count - 1; i >= 0; i--) {
397
+ string currentPass = rules[i].Apply(word);
398
+ if (currentPass != null) {
399
+ result = currentPass;
400
+ break;
401
+ }
402
+ }
403
+ }
404
+ return result;
405
+ }
406
+
407
+ /// <summary>
408
+ /// Converts the string to title case.
409
+ /// </summary>
410
+ /// <param name="word">The word.</param>
411
+ /// <returns></returns>
412
+ public static string ToTitleCase(string word) {
413
+ return Regex.Replace(ToHumanCase(AddUnderscores(word)), @"\b([a-z])",
414
+ delegate(Match match) { return match.Captures[0].Value.ToUpper(); });
415
+ }
416
+
417
+ /// <summary>
418
+ /// Converts the string to human case.
419
+ /// </summary>
420
+ /// <param name="lowercaseAndUnderscoredWord">The lowercase and underscored word.</param>
421
+ /// <returns></returns>
422
+ public static string ToHumanCase(string lowercaseAndUnderscoredWord) {
423
+ return MakeInitialCaps(Regex.Replace(lowercaseAndUnderscoredWord, @"_", " "));
424
+ }
425
+
426
+
427
+ /// <summary>
428
+ /// Adds the underscores.
429
+ /// </summary>
430
+ /// <param name="pascalCasedWord">The pascal cased word.</param>
431
+ /// <returns></returns>
432
+ public static string AddUnderscores(string pascalCasedWord) {
433
+ return Regex.Replace(Regex.Replace(Regex.Replace(pascalCasedWord, @"([A-Z]+)([A-Z][a-z])", "$1_$2"), @"([a-z\d])([A-Z])", "$1_$2"), @"[-\s]", "_").ToLower();
434
+ }
435
+
436
+ /// <summary>
437
+ /// Makes the initial caps.
438
+ /// </summary>
439
+ /// <param name="word">The word.</param>
440
+ /// <returns></returns>
441
+ public static string MakeInitialCaps(string word) {
442
+ return String.Concat(word.Substring(0, 1).ToUpper(), word.Substring(1).ToLower());
443
+ }
444
+
445
+ /// <summary>
446
+ /// Makes the initial lower case.
447
+ /// </summary>
448
+ /// <param name="word">The word.</param>
449
+ /// <returns></returns>
450
+ public static string MakeInitialLowerCase(string word) {
451
+ return String.Concat(word.Substring(0, 1).ToLower(), word.Substring(1));
452
+ }
453
+
454
+
455
+ /// <summary>
456
+ /// Determine whether the passed string is numeric, by attempting to parse it to a double
457
+ /// </summary>
458
+ /// <param name="str">The string to evaluated for numeric conversion</param>
459
+ /// <returns>
460
+ /// <c>true</c> if the string can be converted to a number; otherwise, <c>false</c>.
461
+ /// </returns>
462
+ public static bool IsStringNumeric(string str) {
463
+ double result;
464
+ return (double.TryParse(str, NumberStyles.Float, NumberFormatInfo.CurrentInfo, out result));
465
+ }
466
+
467
+ /// <summary>
468
+ /// Adds the ordinal suffix.
469
+ /// </summary>
470
+ /// <param name="number">The number.</param>
471
+ /// <returns></returns>
472
+ public static string AddOrdinalSuffix(string number) {
473
+ if (IsStringNumeric(number)) {
474
+ int n = int.Parse(number);
475
+ int nMod100 = n % 100;
476
+
477
+ if (nMod100 >= 11 && nMod100 <= 13)
478
+ return String.Concat(number, "th");
479
+
480
+ switch (n % 10) {
481
+ case 1:
482
+ return String.Concat(number, "st");
483
+ case 2:
484
+ return String.Concat(number, "nd");
485
+ case 3:
486
+ return String.Concat(number, "rd");
487
+ default:
488
+ return String.Concat(number, "th");
489
+ }
490
+ }
491
+ return number;
492
+ }
493
+
494
+ /// <summary>
495
+ /// Converts the underscores to dashes.
496
+ /// </summary>
497
+ /// <param name="underscoredWord">The underscored word.</param>
498
+ /// <returns></returns>
499
+ public static string ConvertUnderscoresToDashes(string underscoredWord) {
500
+ return underscoredWord.Replace('_', '-');
501
+ }
502
+
503
+
504
+ #region Nested type: InflectorRule
505
+
506
+ /// <summary>
507
+ /// Summary for the InflectorRule class
508
+ /// </summary>
509
+ private class InflectorRule {
510
+ /// <summary>
511
+ ///
512
+ /// </summary>
513
+ public readonly Regex regex;
514
+
515
+ /// <summary>
516
+ ///
517
+ /// </summary>
518
+ public readonly string replacement;
519
+
520
+ /// <summary>
521
+ /// Initializes a new instance of the <see cref="InflectorRule"/> class.
522
+ /// </summary>
523
+ /// <param name="regexPattern">The regex pattern.</param>
524
+ /// <param name="replacementText">The replacement text.</param>
525
+ public InflectorRule(string regexPattern, string replacementText) {
526
+ regex = new Regex(regexPattern, RegexOptions.IgnoreCase);
527
+ replacement = replacementText;
528
+ }
529
+
530
+ /// <summary>
531
+ /// Applies the specified word.
532
+ /// </summary>
533
+ /// <param name="word">The word.</param>
534
+ /// <returns></returns>
535
+ public string Apply(string word) {
536
+ if (!regex.IsMatch(word))
537
+ return null;
538
+
539
+ string replace = regex.Replace(word, replacement);
540
+ if (word == word.ToUpper())
541
+ replace = replace.ToUpper();
542
+
543
+ return replace;
544
+ }
545
+ }
546
+
547
+ #endregion
548
+ }
549
+
550
+ #>