Skip to content

Commit 5cec673

Browse files
committed
workingtables
1 parent 43bcced commit 5cec673

29 files changed

+349
-107
lines changed
Lines changed: 140 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,35 @@
1-
using Rdmp.Core.Curation.Data.DataLoad;
1+
using FAnsi.Discovery;
2+
using Rdmp.Core.Curation.Data.DataLoad;
3+
using Rdmp.Core.Databases;
24
using Rdmp.Core.EntityFramework.Helpers;
5+
using Rdmp.Core.MapsDirectlyToDatabaseTable;
36
using Rdmp.Core.ReusableLibraryCode.Checks;
7+
using Rdmp.Core.ReusableLibraryCode.DataAccess;
48
using System;
59
using System.Collections.Generic;
610
using System.ComponentModel.DataAnnotations;
11+
using System.ComponentModel.DataAnnotations.Schema;
12+
using System.Data.Common;
713
using System.Linq;
814
using System.Text;
15+
using System.Text.RegularExpressions;
916
using System.Threading.Tasks;
1017

1118
namespace Rdmp.Core.EntityFramework.Models
1219
{
20+
[Table("ANOTable")]
1321
public class ANOTable: DatabaseObject, ICheckable
1422
{
1523
[Key]
1624
public override int ID { get; set; }
17-
public string Name { get; set; }
25+
public string TableName { get; set; }
1826
public int Server_ID { get; set; }
1927
public int NumberOfIntegersToUseInAnonymousRepresentation { get; set; }
2028
public int NumberOfCharactersToUseInAnonymousRepresentation { get; set; }
2129
public string Suffix { get; set; }
2230

31+
[NoMappingToDatabase]
32+
public ExternalDatabaseServer Server => CatalogueDbContext.GetObjectByID<ExternalDatabaseServer>(Server_ID);
2333
public void Check(ICheckNotifier notifier)
2434
{
2535
throw new NotImplementedException();
@@ -28,5 +38,133 @@ public string GetRuntimeDataType(LoadStage stage)
2838
{
2939
return "TODO";
3040
}
41+
42+
public override string ToString() => TableName;
43+
public DiscoveredTable GetPushedTable()
44+
{
45+
if (!Server.WasCreatedBy(new ANOStorePatcher()))
46+
throw new Exception($"ANOTable's Server '{Server}' is not an ANOStore. ANOTable was '{this}'");
47+
48+
var tables = DataAccessPortal
49+
.ExpectDatabase(Server, DataAccessContext.DataLoad)
50+
.DiscoverTables(false);
51+
52+
return tables.SingleOrDefault(t => t.GetRuntimeName().Equals(TableName));
53+
}
54+
public void PushToANOServerAsNewTable(string identifiableDatatype, ICheckNotifier notifier,
55+
DbConnection forceConnection = null, DbTransaction forceTransaction = null)
56+
{
57+
var server = DataAccessPortal.ExpectServer(Server, DataAccessContext.DataLoad);
58+
59+
//matches varchar(100) and has capture group 100
60+
var regexGetLengthOfCharType = new Regex(@".*char.*\((\d*)\)");
61+
var match = regexGetLengthOfCharType.Match(identifiableDatatype);
62+
63+
//if user supplies varchar(100) and says he wants 3 ints and 3 chars in his anonymous identifiers he will soon run out of combinations
64+
65+
if (match.Success)
66+
{
67+
var length = Convert.ToInt32(match.Groups[1].Value);
68+
69+
if (length >
70+
NumberOfCharactersToUseInAnonymousRepresentation + NumberOfIntegersToUseInAnonymousRepresentation)
71+
notifier.OnCheckPerformed(
72+
new CheckEventArgs(
73+
$"You asked to create a table with a datatype of length {length}({identifiableDatatype}) but you did not allocate an equal or greater number of anonymous identifier types (NumberOfCharactersToUseInAnonymousRepresentation + NumberOfIntegersToUseInAnonymousRepresentation={NumberOfCharactersToUseInAnonymousRepresentation + NumberOfIntegersToUseInAnonymousRepresentation})",
74+
CheckResult.Warning));
75+
}
76+
77+
var con = forceConnection ?? server.GetConnection(); //use the forced connection or open a new one
78+
79+
try
80+
{
81+
if (forceConnection == null)
82+
con.Open();
83+
}
84+
catch (Exception e)
85+
{
86+
notifier.OnCheckPerformed(new CheckEventArgs($"Could not connect to ano server {Server}", CheckResult.Fail,
87+
e));
88+
return;
89+
}
90+
91+
//if table name is ANOChi there are 2 columns Chi and ANOChi in it
92+
var anonymousColumnName = TableName;
93+
var identifiableColumnName = TableName["ANO".Length..];
94+
95+
var anonymousDatatype =
96+
$"varchar({NumberOfCharactersToUseInAnonymousRepresentation + NumberOfIntegersToUseInAnonymousRepresentation + "_".Length + Suffix.Length})";
97+
98+
99+
var sql =
100+
$"CREATE TABLE {TableName}{Environment.NewLine} ({Environment.NewLine}{identifiableColumnName} {identifiableDatatype} NOT NULL,{Environment.NewLine}{anonymousColumnName} {anonymousDatatype}NOT NULL";
101+
102+
sql += $@",
103+
CONSTRAINT PK_{TableName} PRIMARY KEY CLUSTERED
104+
(
105+
{identifiableColumnName} ASC
106+
),
107+
CONSTRAINT AK_{TableName} UNIQUE({anonymousColumnName})
108+
)";
109+
110+
111+
using (var cmd = server.GetCommand(sql, con))
112+
{
113+
cmd.Transaction = forceTransaction;
114+
115+
notifier.OnCheckPerformed(new CheckEventArgs($"Decided appropriate create statement is:{cmd.CommandText}",
116+
CheckResult.Success));
117+
try
118+
{
119+
cmd.ExecuteNonQuery();
120+
121+
if (forceConnection == null) //if we opened this ourselves
122+
con.Close(); //shut it
123+
}
124+
catch (Exception e)
125+
{
126+
notifier.OnCheckPerformed(
127+
new CheckEventArgs(
128+
$"Failed to successfully create the anonymous/identifier mapping Table in the ANO database on server {Server}",
129+
CheckResult.Fail, e));
130+
return;
131+
}
132+
}
133+
134+
try
135+
{
136+
if (forceTransaction ==
137+
null) //if there was no transaction then this has hit the LIVE ANO database and is for real, so save the ANOTable such that it is synchronized with reality
138+
{
139+
notifier.OnCheckPerformed(new CheckEventArgs("Saving state because table has been pushed",
140+
CheckResult.Success));
141+
/*SaveToDatabase*/
142+
}
143+
}
144+
catch (Exception e)
145+
{
146+
notifier.OnCheckPerformed(new CheckEventArgs(
147+
"Failed to save state after table was successfully? pushed to ANO server", CheckResult.Fail, e));
148+
}
149+
}
150+
public void DeleteANOTableInANOStore()
151+
{
152+
//RevertToDatabaseState();
153+
154+
var s = Server;
155+
if (string.IsNullOrWhiteSpace(s.Name) || string.IsNullOrWhiteSpace(s.Database) ||
156+
string.IsNullOrWhiteSpace(TableName))
157+
return;
158+
159+
var tbl = GetPushedTable();
160+
161+
if (tbl?.Exists() == true)
162+
if (!tbl.IsEmpty())
163+
throw new Exception(
164+
$"Cannot delete ANOTable because it references {TableName} which is a table on server {Server} which contains rows, deleting this reference would leave that table as an orphan, we can only delete when there are 0 rows in the table");
165+
else
166+
tbl.Drop();
167+
}
168+
31169
}
32170
}

Rdmp.Core/EntityFramework/Models/ConnectionStringKeyword.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Rdmp.Core.EntityFramework.Helpers;
2+
using Rdmp.Core.ReusableLibraryCode.Checks;
23
using System;
34
using System.Collections.Generic;
45
using System.ComponentModel.DataAnnotations;
@@ -10,14 +11,19 @@
1011
namespace Rdmp.Core.EntityFramework.Models
1112
{
1213
[Table("ConnectionStringKeyword")]
13-
public class ConnectionStringKeyword: DatabaseObject
14+
public class ConnectionStringKeyword: DatabaseObject, ICheckable
1415
{
1516
[Key]
1617
public override int ID { get; set; }
1718
public string DatabaseType { get; set; }
1819
public string Name { get; set; }
1920
public string Value { get; set; }
2021

22+
public void Check(ICheckNotifier notifier)
23+
{
24+
throw new NotImplementedException();
25+
}
26+
2127
public override string ToString() => Name;
2228
}
2329
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using Microsoft.Identity.Client;
2+
using Rdmp.Core.Curation.Data.Dashboarding;
3+
using Rdmp.Core.EntityFramework.Helpers;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.ComponentModel.DataAnnotations;
7+
using System.ComponentModel.DataAnnotations.Schema;
8+
using System.Linq;
9+
using System.Text;
10+
using System.Threading.Tasks;
11+
12+
namespace Rdmp.Core.EntityFramework.Models
13+
{
14+
[Table("DatabaseControl")]
15+
public class DashboardControl: DatabaseObject
16+
{
17+
[Key]
18+
public override int ID { get; set; }
19+
public int DashboardLayout_ID { get; set; }
20+
public int X { get; set; }
21+
public int Y { get; set; }
22+
public int Width { get; set; }
23+
public int Height { get; set; }
24+
public string PersistenceString { get; set; }
25+
public string ControlType { get; set; }
26+
27+
[ForeignKey("DashboardLayout_ID")]
28+
public virtual DashboardLayout ParentLayout { get; set; }
29+
30+
public DashboardObjectUse[] ObjectsUsed => Array.Empty<DashboardObjectUse>();//TODO
31+
}
32+
}

Rdmp.Core/EntityFramework/Models/DashboardLayout.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ public class DashboardLayout: DatabaseObject
2020
public DateTime Created { get; set; }
2121
public override string ToString() => Name;
2222

23+
public virtual List<DashboardControl> Controls { get; set; }
2324
}
2425
}

Rdmp.Core/EntityFramework/Models/ExternalDatabaseServer.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
using FAnsi;
22
using FAnsi.Discovery.QuerySyntax;
33
using Rdmp.Core.EntityFramework.Helpers;
4+
using Rdmp.Core.MapsDirectlyToDatabaseTable.Versioning;
5+
using Rdmp.Core.ReusableLibraryCode.Checks;
46
using Rdmp.Core.ReusableLibraryCode.DataAccess;
57
using System.ComponentModel.DataAnnotations;
68
using System.ComponentModel.DataAnnotations.Schema;
79

810
namespace Rdmp.Core.EntityFramework.Models
911
{
1012
[Table("ExternalDatabaseServer")]
11-
public class ExternalDatabaseServer: DatabaseObject, IDataAccessPoint
13+
public class ExternalDatabaseServer : DatabaseObject, IDataAccessPoint, ICheckable
1214
{
1315
[Key]
1416
public override int ID { get; set; }
@@ -24,9 +26,16 @@ public class ExternalDatabaseServer: DatabaseObject, IDataAccessPoint
2426
public string DatabaseType { get; set; }
2527
public string Username { get; set; }
2628
public string Password { get; set; }
29+
public string CreatedByAssembly { get; set; }
30+
public string MappedDataPath { get; set; }
2731
public override string ToString() => Name;
2832

2933

34+
public string GetDecryptedPassword()
35+
{
36+
return "";//todo
37+
}
38+
3039
[NotMapped]
3140
DatabaseType IDataAccessPoint.DatabaseType { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
3241

@@ -44,6 +53,14 @@ public IQuerySyntaxHelper GetQuerySyntaxHelper()
4453
{
4554
throw new System.NotImplementedException();
4655
}
56+
public bool WasCreatedBy(IPatcher patcher) => !string.IsNullOrWhiteSpace(CreatedByAssembly) &&
57+
(patcher.Name == CreatedByAssembly ||
58+
patcher.LegacyName == CreatedByAssembly);
59+
60+
public void Check(ICheckNotifier notifier)
61+
{
62+
throw new System.NotImplementedException();
63+
}
4764
}
4865

4966
}

Rdmp.Core/EntityFramework/Models/PipelineComponentArgument.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public class PipelineComponentArgument: DatabaseObject, IArgument
1515
{
1616
[Key]
1717
public override int ID { get; set; }
18+
19+
[Column("PipelineComponent_ID")]
1820
public int PipelineComponent_ID { get; set; }
1921
public string Name { get; set; }
2022
public string Value { get; set; }

0 commit comments

Comments
 (0)