2010-03-12 Jb Evain <jbevain@novell.com>
[mono.git] / mcs / class / System.Data.Linq / src / DbLinq.Oracle / OracleSchemaLoader.Constraints.cs
1 #region MIT license\r
2 // \r
3 // MIT license\r
4 //\r
5 // Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne\r
6 // \r
7 // Permission is hereby granted, free of charge, to any person obtaining a copy\r
8 // of this software and associated documentation files (the "Software"), to deal\r
9 // in the Software without restriction, including without limitation the rights\r
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
11 // copies of the Software, and to permit persons to whom the Software is\r
12 // furnished to do so, subject to the following conditions:\r
13 // \r
14 // The above copyright notice and this permission notice shall be included in\r
15 // all copies or substantial portions of the Software.\r
16 // \r
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
23 // THE SOFTWARE.\r
24 // \r
25 #endregion\r
26 using System;\r
27 using System.Collections.Generic;\r
28 using System.Data;\r
29 using System.Text;\r
30 using System.Text.RegularExpressions;\r
31 using DbLinq.Util;\r
32 \r
33 namespace DbLinq.Oracle\r
34 {\r
35     partial class OracleSchemaLoader\r
36     {\r
37         protected class DataConstraint\r
38         {\r
39             public string TableSchema;\r
40             public string ConstraintName;\r
41             public string TableName;\r
42             public string ColumnName;\r
43             public string ConstraintType;\r
44             public string ReverseConstraintName;\r
45             public string Expression;\r
46 \r
47             public override string ToString()\r
48             {\r
49                 return "User_Constraint  " + TableName + "." + ColumnName;\r
50             }\r
51         }\r
52 \r
53         protected virtual DataConstraint ReadConstraint(IDataReader rdr)\r
54         {\r
55             var constraint = new DataConstraint();\r
56             int field = 0;\r
57             constraint.TableSchema = rdr.GetAsString(field++);\r
58             constraint.ConstraintName = rdr.GetAsString(field++);\r
59             constraint.TableName = rdr.GetAsString(field++);\r
60             constraint.ColumnName = rdr.GetAsString(field++);\r
61             constraint.ConstraintType = rdr.GetAsString(field++);\r
62             constraint.ReverseConstraintName = rdr.GetAsString(field++);\r
63             return constraint;\r
64         }\r
65 \r
66         private static Regex TriggerMatch1 = new Regex(@".*SELECT\s+(?<exp>\S+.*)\s+INTO\s+\:new.(?<col>\S+)\s+FROM\s+DUAL.*",\r
67             RegexOptions.Compiled | RegexOptions.IgnoreCase);\r
68 \r
69         protected bool MatchTrigger(Regex regex, string fullText, out string expression, out string column)\r
70         {\r
71             var match = regex.Match(fullText);\r
72             if (match.Success)\r
73             {\r
74                 expression = match.Groups["exp"].Value;\r
75                 column = match.Groups["col"].Value;\r
76                 return true;\r
77             }\r
78             expression = null;\r
79             column = null;\r
80             return false;\r
81         }\r
82 \r
83         protected virtual DataConstraint ReadTrigger(IDataReader rdr)\r
84         {\r
85             var constraint = new DataConstraint();\r
86             int field = 0;\r
87             constraint.ConstraintName = rdr.GetAsString(field++);\r
88             constraint.TableSchema = rdr.GetAsString(field++);\r
89             constraint.TableName = rdr.GetAsString(field++);\r
90             constraint.ConstraintType = "T";\r
91             string body = rdr.GetAsString(field++);\r
92             //BEGIN\r
93             //   IF (:new."EmployeeID" IS NULL) THEN\r
94             //        SELECT Employees_seq.NEXTVAL INTO :new."EmployeeID" FROM DUAL;\r
95             //   END IF;\r
96             //END;\r
97             string expression, column;\r
98             if (MatchTrigger(TriggerMatch1, body, out expression, out column))\r
99             {\r
100                 constraint.ColumnName = column.Trim('"');\r
101                 constraint.Expression = expression;\r
102             }\r
103             return constraint;\r
104         }\r
105 \r
106         protected virtual List<DataConstraint> ReadConstraints(IDbConnection conn, string db)\r
107         {\r
108             var constraints = new List<DataConstraint>();\r
109 \r
110             string sql = @"\r
111 SELECT UCC.owner, UCC.constraint_name, UCC.table_name, UCC.column_name, UC.constraint_type, UC.R_constraint_name\r
112 FROM all_cons_columns UCC, all_constraints UC\r
113 WHERE UCC.constraint_name=UC.constraint_name\r
114 AND UCC.table_name=UC.table_name\r
115 AND UCC.TABLE_NAME NOT LIKE '%$%' AND UCC.TABLE_NAME NOT LIKE 'LOGMNR%' AND UCC.TABLE_NAME NOT IN ('HELP','SQLPLUS_PRODUCT_PROFILE')\r
116 AND UC.CONSTRAINT_TYPE!='C'\r
117 and lower(UCC.owner) = :owner";\r
118 \r
119             constraints.AddRange(DataCommand.Find<DataConstraint>(conn, sql, ":owner", db.ToLower(), ReadConstraint));\r
120 \r
121             string sql2 =\r
122                 @"\r
123 select t.TRIGGER_NAME, t.TABLE_OWNER, t.TABLE_NAME, t.TRIGGER_BODY from ALL_TRIGGERS t\r
124 where t.status = 'ENABLED'\r
125  and t.TRIGGERING_EVENT = 'INSERT'\r
126  and t.TRIGGER_TYPE='BEFORE EACH ROW'\r
127  and lower(t.owner) = :owner";\r
128 \r
129             constraints.AddRange(DataCommand.Find<DataConstraint>(conn, sql2, ":owner", db.ToLower(), ReadTrigger));\r
130             return constraints;\r
131         }\r
132     }\r
133 }\r