-
Notifications
You must be signed in to change notification settings - Fork 0
/
conflictsmeta.pas
120 lines (101 loc) · 3 KB
/
conflictsmeta.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
unit ConflictsMeta;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, sqldb, FileUtil, MetaUnit, Connect;
type
TConflictPairs = array of TPoint;
TConflict = class
FName: String;
FEqual, FUnequal: array of Integer;
constructor Create(AName: String; AEqual, AUnequal: array of Integer);
end;
{ TConflictsModule }
TConflictsModule = class(TDataModule)
ConflictsSQLQuery: TSQLQuery;
public
ScheduleTable: TTableInfo;
ConflictPairs: array of TConflictPairs;
procedure AddConflict(AName: String; AEqual, AUnequal: array of Integer);
function MakeQuery(AID: Integer): String;
function GetConflictPairs(AID: Integer): TConflictPairs;
function IsInConflict(AID: Integer): TPoint;
end;
var
ConflictsModule: TConflictsModule;
Conflicts: array of TConflict;
implementation
constructor TConflict.Create(AName: String; AEqual, AUnequal: array of Integer);
var
i: Integer;
begin
FName := AName;
SetLength(FEqual, Length(AEqual));
SetLength(FUnequal, Length(AUnequal));
for i := 0 to High(AEqual) do
FEqual[i] := AEqual[i];
for i := 0 to High(AUnequal) do
FUnequal[i] := AUnequal[i];
end;
procedure TConflictsModule.AddConflict(AName: String; AEqual, AUnequal: array of Integer);
var
i: Integer;
begin
SetLength(Conflicts, Length(Conflicts) + 1);
Conflicts[High(Conflicts)] := TConflict.Create(AName, AEqual, AUnequal);
SetLength(ConflictPairs, Length(ConflictPairs)+1);
ConflictPairs[High(ConflictPairs)] := GetConflictPairs(High(Conflicts));
end;
function TConflictsModule.MakeQuery(AID: Integer): String;
var
i: Integer;
q, pairs: String;
currConf: TConflict;
begin
ScheduleTable := TMeta.GetTableByName('Schedule_Items');
currConf := Conflicts[AID];
q := 'SELECT A.*, B.* FROM Schedule_Items A INNER JOIN Schedule_Items B ON ';
pairs := '';
for i := 0 to High(currConf.FEqual) do
with ScheduleTable.FFields[currConf.FEqual[i]] do
pairs += Format('AND A.%s = B.%s ', [FName, FName]);
for i := 0 to High(currConf.FUnequal) do
with ScheduleTable.FFields[currConf.FUnequal[i]] do
pairs += Format('AND A.%s <> B.%s ', [FName, FName]);
Delete(pairs, 1, 4);
pairs += 'AND A.ID < B.ID';
q += pairs;
Result := q;
end;
function TConflictsModule.GetConflictPairs(AID: Integer): TConflictPairs;
var
tmpPairs: TConflictPairs;
begin
with ConflictsSQLQuery do begin
Close;
SQL.Clear;
SQL.Text := MakeQuery(AID);
Open;
First;
while not EOF do begin
SetLength(tmpPairs, Length(tmpPairs)+1);
tmpPairs[High(tmpPairs)].x := Fields[0].AsInteger;
tmpPairs[High(tmpPairs)].y := Fields[Length(ScheduleTable.FFields)].AsInteger;
Next;
end;
end;
Result := tmpPairs;
end;
function TConflictsModule.IsInConflict(AID: Integer): TPoint;
var
i, j: Integer;
begin
for i := 0 to High(Conflicts) do
for j := 0 to High(ConflictPairs[i]) do
if (ConflictPairs[i][j].x = AID) or (ConflictPairs[i][j].y = AID) then
Exit(Point(i, j));
Exit(Point(-1, -1));
end;
end.
{$R *.lfm}
end.