15 use PMG
::RuleDB
::Group
;
17 #use Proxmox::Statistic;
18 use PMG
::RuleDB
::Object
;
19 use PMG
::RuleDB
::WhoRegex
;
20 use PMG
::RuleDB
::ReceiverRegex
;
21 use PMG
::RuleDB
::EMail
;
22 use PMG
::RuleDB
::Receiver
;
23 use PMG
::RuleDB
::IPAddress
;
24 use PMG
::RuleDB
::IPNet
;
25 use PMG
::RuleDB
::Domain
;
26 use PMG
::RuleDB
::ReceiverDomain
;
27 use PMG
::RuleDB
::LDAP
;
28 use PMG
::RuleDB
::LDAPUser
;
29 use PMG
::RuleDB
::TimeFrame
;
30 use PMG
::RuleDB
::Spam
;
31 use PMG
::RuleDB
::ReportSpam
;
32 use PMG
::RuleDB
::Virus
;
33 use PMG
::RuleDB
::Accept
;
34 use PMG
::RuleDB
::Remove
;
35 use PMG
::RuleDB
::ModField
;
36 use PMG
::RuleDB
::MatchField
;
37 use PMG
::RuleDB
::MatchFilename
;
38 use PMG
::RuleDB
::MatchArchiveFilename
;
39 use PMG
::RuleDB
::Attach
;
40 use PMG
::RuleDB
::Disclaimer
;
42 use PMG
::RuleDB
::Quarantine
;
43 use PMG
::RuleDB
::Block
;
44 use PMG
::RuleDB
::Counter
;
45 use PMG
::RuleDB
::Notify
;
46 use PMG
::RuleDB
::Rule
;
47 use PMG
::RuleDB
::ContentTypeFilter
;
48 use PMG
::RuleDB
::ArchiveFilter
;
51 my ($type, $dbh) = @_;
53 $dbh = PMG
::DBTools
::open_ruledb
("Proxmox_ruledb") if !defined ($dbh);
55 my $self = bless { dbh
=> $dbh }, $type;
63 $self->{dbh
}->disconnect();
66 sub create_group_with_obj
{
67 my ($self, $obj, $name, $info) = @_;
72 defined($obj) || die "proxmox: undefined object";
74 $name = encode
('UTF-8', $name // '');
75 $info = encode
('UTF-8', $info // '');
79 $self->{dbh
}->begin_work;
81 $self->{dbh
}->do("INSERT INTO Objectgroup (Name, Info, Class) " .
82 "VALUES (?, ?, ?)", undef,
83 $name, $info, $obj->oclass());
85 my $lid = PMG
::Utils
::lastid
($self->{dbh
}, 'objectgroup_id_seq');
87 $og = PMG
::RuleDB
::Group-
>new($name, $info, $obj->oclass());
90 $obj->{ogroup
} = $lid;
91 $id = $obj->save($self, 1);
92 $obj->{id
} = $id; # just to be sure
97 $self->{dbh
}->rollback;
104 my ($self, $rule) = @_;
106 defined($rule->{id
}) || die "undefined rule id: ERROR";
108 my $sth = $self->{dbh
}->prepare(
109 "SELECT RuleGroup.Grouptype, Objectgroup.ID, " .
110 "Objectgroup.Name, Objectgroup.Info " .
111 "FROM Rulegroup, Objectgroup " .
112 "WHERE Rulegroup.Rule_ID = ? and " .
113 "Rulegroup.Objectgroup_ID = Objectgroup.ID " .
114 "ORDER BY RuleGroup.Grouptype");
118 $sth->execute($rule->{id
});
120 my ($from, $to, $when, $what, $action) = ([], [], [], [], []);
122 while (my $ref = $sth->fetchrow_hashref()) {
123 my $og = PMG
::RuleDB
::Group-
>new($ref->{name
}, $ref->{info
});
124 $og->{id
} = $ref->{id
};
126 if ($ref->{'grouptype'} == 0) { #from
128 } elsif ($ref->{'grouptype'} == 1) { # to
130 } elsif ($ref->{'grouptype'} == 2) { # when
132 } elsif ($ref->{'grouptype'} == 3) { # what
134 } elsif ($ref->{'grouptype'} == 4) { # action
135 my $objects = $self->load_group_objects($og->{id
});
136 my $obj = @$objects[0];
137 defined($obj) || die "undefined action object: ERROR";
138 $og->{action
} = $obj;
145 return ($from, $to, $when, $what, $action);
148 sub load_groups_by_name
{
149 my ($self, $rule) = @_;
151 my ($from, $to, $when, $what, $action) =
152 $self->load_groups($rule);
163 sub update_group_attributes
{
164 my ($self, $og) = @_;
166 my $attributes = [qw(and invert)];
168 for my $attribute ($attributes->@*) {
169 # only save the values if they're set to 1
170 if ($og->{$attribute}) {
172 "INSERT INTO Objectgroup_Attributes (Objectgroup_ID, Name, Value) " .
174 "ON CONFLICT (Objectgroup_ID, Name) DO UPDATE SET Value = ?", undef,
175 $og->{id
}, $attribute, $og->{$attribute}, $og->{$attribute},
179 "DELETE FROM Objectgroup_Attributes " .
180 "WHERE Objectgroup_ID = ? AND Name = ?", undef,
181 $og->{id
}, $attribute,
188 my ($self, $og) = @_;
190 defined($og->{name
}) ||
191 die "undefined group attribute - name: ERROR";
192 defined($og->{info
}) ||
193 die "undefined group attribute - info: ERROR";
194 defined($og->{class}) ||
195 die "undefined group attribute - class: ERROR";
197 if (defined($og->{id
})) {
198 $self->{dbh
}->begin_work;
201 $self->{dbh
}->do("UPDATE Objectgroup " .
202 "SET Name = ?, Info = ? " .
203 "WHERE ID = ?", undef,
204 encode
('UTF-8', $og->{name
}),
205 encode
('UTF-8', $og->{info
}),
208 $self->update_group_attributes($og);
210 $self->{dbh
}->commit;
214 $self->{dbh
}->rollback;
219 $self->{dbh
}->begin_work;
222 my $sth = $self->{dbh
}->prepare(
223 "INSERT INTO Objectgroup (Name, Info, Class) " .
224 "VALUES (?, ?, ?);");
226 $sth->execute(encode
('UTF-8', $og->name), encode
('UTF-8', $og->info), $og->class);
228 $og->{id
} = PMG
::Utils
::lastid
($self->{dbh
}, 'objectgroup_id_seq');
230 $self->update_group_attributes($og);
232 $self->{dbh
}->commit;
236 $self->{dbh
}->rollback;
246 my ($self, $groupid) = @_;
248 defined($groupid) || die "undefined group id: ERROR";
252 $self->{dbh
}->begin_work;
254 # test if group is used in rules
255 $self->{dbh
}->do("LOCK TABLE RuleGroup IN EXCLUSIVE MODE");
257 my $sth = $self->{dbh
}->prepare(
258 "SELECT Rule.Name as rulename, ObjectGroup.Name as groupname " .
259 "FROM RuleGroup, Rule, ObjectGroup WHERE " .
260 "ObjectGroup.ID = ? AND Objectgroup_ID = ObjectGroup.ID AND " .
261 "Rule_ID = Rule.ID");
263 $sth->execute($groupid);
265 if (my $ref = $sth->fetchrow_hashref()) {
266 my $groupname = PMG
::Utils
::try_decode_utf8
($ref->{groupname
});
267 my $rulename = PMG
::Utils
::try_decode_utf8
($ref->{rulename
});
268 die "Group '$groupname' is used by rule '$rulename' - unable to delete\n";
273 $self->{dbh
}->do("DELETE FROM ObjectGroup " .
274 "WHERE ID = ?", undef, $groupid);
276 $self->{dbh
}->do("DELETE FROM RuleGroup " .
277 "WHERE Objectgroup_ID = ?", undef, $groupid);
279 $sth = $self->{dbh
}->prepare("SELECT * FROM Object " .
280 "where Objectgroup_ID = ?");
281 $sth->execute($groupid);
283 while (my $ref = $sth->fetchrow_hashref()) {
284 $self->{dbh
}->do("DELETE FROM Attribut " .
285 "WHERE Object_ID = ?", undef, $ref->{id
});
290 $self->{dbh
}->do("DELETE FROM Object " .
291 "WHERE Objectgroup_ID = ?", undef, $groupid);
293 $self->{dbh
}->commit;
296 $self->{dbh
}->rollback;
303 sub load_group_attributes
{
304 my ($self, $og) = @_;
306 my $attribute_sth = $self->{dbh
}->prepare("SELECT * FROM Objectgroup_Attributes WHERE Objectgroup_ID = ?");
307 $attribute_sth->execute($og->{id
});
309 while (my $ref = $attribute_sth->fetchrow_hashref()) {
310 $og->{and} = $ref->{value
} if $ref->{name
} eq 'and';
311 $og->{invert
} = $ref->{value
} if $ref->{name
} eq 'invert';
315 sub load_objectgroups
{
316 my ($self, $class, $id) = @_;
320 defined($class) || die "undefined object class";
322 $self->{dbh
}->begin_work;
327 if (!(defined($id))) {
328 $sth = $self->{dbh
}->prepare(
329 "SELECT * FROM Objectgroup where Class = ? ORDER BY name");
330 $sth->execute($class);
333 $sth = $self->{dbh
}->prepare(
334 "SELECT * FROM Objectgroup where Class like ? and id = ? " .
336 $sth->execute($class,$id);
339 while (my $ref = $sth->fetchrow_hashref()) {
340 my $og = PMG
::RuleDB
::Group-
>new($ref->{name
}, $ref->{info
},
342 $og->{id
} = $ref->{id
};
344 if ($class eq 'action') {
345 my $objects = $self->load_group_objects($og->{id
});
346 my $obj = @$objects[0];
347 defined($obj) || die "undefined action object: ERROR";
348 $og->{action
} = $obj;
350 $self->load_group_attributes($og);
360 $self->{dbh
}->rollback; # finish transaction
368 my ($self, $otype) = @_;
372 # FIXME: remove deprecated types and files with PMG 8.0
373 my $deprecated_types = {
375 4008 => "ReportSpam",
380 if ($otype == PMG
::RuleDB
::Domain
::otype
()) {
381 $obj = PMG
::RuleDB
::Domain-
>new();
383 elsif ($otype == PMG
::RuleDB
::ReceiverDomain
::otype
) {
384 $obj = PMG
::RuleDB
::ReceiverDomain-
>new();
386 elsif ($otype == PMG
::RuleDB
::WhoRegex
::otype
) {
387 $obj = PMG
::RuleDB
::WhoRegex-
>new();
389 elsif ($otype == PMG
::RuleDB
::ReceiverRegex
::otype
) {
390 $obj = PMG
::RuleDB
::ReceiverRegex-
>new();
392 elsif ($otype == PMG
::RuleDB
::EMail
::otype
) {
393 $obj = PMG
::RuleDB
::EMail-
>new();
395 elsif ($otype == PMG
::RuleDB
::Receiver
::otype
) {
396 $obj = PMG
::RuleDB
::Receiver-
>new();
398 elsif ($otype == PMG
::RuleDB
::IPAddress
::otype
) {
399 $obj = PMG
::RuleDB
::IPAddress-
>new();
401 elsif ($otype == PMG
::RuleDB
::IPNet
::otype
) {
402 $obj = PMG
::RuleDB
::IPNet-
>new();
404 elsif ($otype == PMG
::RuleDB
::LDAP
::otype
) {
405 $obj = PMG
::RuleDB
::LDAP-
>new();
407 elsif ($otype == PMG
::RuleDB
::LDAPUser
::otype
) {
408 $obj = PMG
::RuleDB
::LDAPUser-
>new();
411 elsif ($otype == PMG
::RuleDB
::TimeFrame
::otype
) {
412 $obj = PMG
::RuleDB
::TimeFrame-
>new();
415 elsif ($otype == PMG
::RuleDB
::Spam
::otype
) {
416 $obj = PMG
::RuleDB
::Spam-
>new();
418 elsif ($otype == PMG
::RuleDB
::Virus
::otype
) {
419 $obj = PMG
::RuleDB
::Virus-
>new();
421 elsif ($otype == PMG
::RuleDB
::MatchField
::otype
) {
422 $obj = PMG
::RuleDB
::MatchField-
>new();
424 elsif ($otype == PMG
::RuleDB
::MatchFilename
::otype
) {
425 $obj = PMG
::RuleDB
::MatchFilename-
>new();
427 elsif ($otype == PMG
::RuleDB
::MatchArchiveFilename
::otype
) {
428 $obj = PMG
::RuleDB
::MatchArchiveFilename-
>new();
430 elsif ($otype == PMG
::RuleDB
::ContentTypeFilter
::otype
) {
431 $obj = PMG
::RuleDB
::ContentTypeFilter-
>new();
433 elsif ($otype == PMG
::RuleDB
::ArchiveFilter
::otype
) {
434 $obj = PMG
::RuleDB
::ArchiveFilter-
>new();
437 elsif ($otype == PMG
::RuleDB
::ModField
::otype
) {
438 $obj = PMG
::RuleDB
::ModField-
>new();
440 elsif ($otype == PMG
::RuleDB
::Accept
::otype
()) {
441 $obj = PMG
::RuleDB
::Accept-
>new();
443 elsif ($otype == PMG
::RuleDB
::ReportSpam
::otype
()) {
444 $obj = PMG
::RuleDB
::ReportSpam-
>new();
446 elsif ($otype == PMG
::RuleDB
::Attach
::otype
) {
447 $obj = PMG
::RuleDB
::Attach-
>new();
449 elsif ($otype == PMG
::RuleDB
::Disclaimer
::otype
) {
450 $obj = PMG
::RuleDB
::Disclaimer-
>new();
452 elsif ($otype == PMG
::RuleDB
::BCC
::otype
) {
453 $obj = PMG
::RuleDB
::BCC-
>new();
455 elsif ($otype == PMG
::RuleDB
::Quarantine
::otype
) {
456 $obj = PMG
::RuleDB
::Quarantine-
>new();
458 elsif ($otype == PMG
::RuleDB
::Block
::otype
) {
459 $obj = PMG
::RuleDB
::Block-
>new();
461 elsif ($otype == PMG
::RuleDB
::Counter
::otype
) {
462 $obj = PMG
::RuleDB
::Counter-
>new();
464 elsif ($otype == PMG
::RuleDB
::Remove
::otype
) {
465 $obj = PMG
::RuleDB
::Remove-
>new();
467 elsif ($otype == PMG
::RuleDB
::Notify
::otype
) {
468 $obj = PMG
::RuleDB
::Notify-
>new();
471 die "proxmox: unknown object type: ERROR";
474 if ( grep( $_ == $otype, keys %$deprecated_types)) {
475 syslog
('warning', "proxmox: deprecated object of type %s found!",
476 $deprecated_types->{$otype});
481 # FIXME: remove with PMG 8.0
482 sub load_counters_data
{
485 my $sth = $self->{dbh
}->prepare(
486 "SELECT Object.id, Objectgroup.name, Object.Value, Objectgroup.info " .
487 "FROM Object, Objectgroup " .
488 "WHERE objectgroup.id = object.objectgroup_id and ObjectType = ? " .
489 "order by Objectgroup.name, Value");
493 $sth->execute(PMG
::RuleDB
::Counter-
>otype());
495 while (my $ref = $sth->fetchrow_hashref()) {
496 my $tmp = [$ref->{id
},$ref->{name
},$ref->{value
},$ref->{info
}];
506 my ($self, $objid) = @_;
510 defined($objid) || die "undefined object id";
512 my $sth = $self->{dbh
}->prepare("SELECT * FROM Object where ID = ?");
513 $sth->execute($objid);
515 my $ref = $sth->fetchrow_hashref();
519 if (defined($ref->{'value'})) {
520 $value = $ref->{'value'};
523 if (!(defined($ref->{'objecttype'}) &&
524 defined($ref->{'objectgroup_id'}))) {
528 my $ogroup = $ref->{'objectgroup_id'};
530 my $otype = $ref->{'objecttype'};
531 my $obj = $self->get_object($otype);
533 return $obj->load_attr($self, $objid, $ogroup, $value);
536 sub load_object_full
{
537 my ($self, $id, $gid, $exp_otype) = @_;
539 my $obj = $self->load_object($id);
540 die "object '$id' does not exists\n" if !defined($obj);
542 my $otype = $obj->otype();
543 die "wrong object type ($otype != $exp_otype)\n"
544 if defined($exp_otype) && $otype != $exp_otype;
546 die "wrong object group ($obj->{ogroup} != $gid)\n"
547 if $obj->{ogroup
} != $gid;
552 sub load_group_by_name
{
553 my ($self, $name) = @_;
555 $name = encode
('UTF-8', $name);
556 my $sth = $self->{dbh
}->prepare("SELECT * FROM Objectgroup " .
559 $sth->execute($name);
561 while (my $ref = $sth->fetchrow_hashref()) {
562 my $og = PMG
::RuleDB
::Group-
>new($ref->{name
}, $ref->{info
},
564 $og->{id
} = $ref->{id
};
568 if ($ref->{'class'} eq 'action') {
569 my $objects = $self->load_group_objects($og->{id
});
570 my $obj = @$objects[0];
571 defined($obj) || die "undefined action object: ERROR";
572 $og->{action
} = $obj;
583 sub greylistexclusion_groupid
{
586 my $sth = $self->{dbh
}->prepare(
587 "select id from objectgroup where class='greylist' limit 1;");
591 my $ref = $sth->fetchrow_hashref();
596 sub load_group_objects
{
597 my ($self, $ogid) = @_;
599 defined($ogid) || die "undefined group id: ERROR";
601 my $sth = $self->{dbh
}->prepare(
602 "SELECT * FROM Object " .
603 "WHERE Objectgroup_ID = ? order by ObjectType,Value");
607 $sth->execute($ogid);
609 while (my $ref = $sth->fetchrow_hashref()) {
610 my $obj = $self->load_object($ref->{id
});
611 push @$objects, $obj;
621 my ($self, $obj) = @_;
628 sub group_add_object
{
629 my ($self, $group, $obj) = @_;
631 ($obj->oclass() eq $group->{class}) ||
632 die "wrong object class: ERROR";
634 $obj->{ogroup
} = $group->{id
};
636 $self->save_object($obj);
640 my ($self, $obj) = @_;
642 defined($obj->{id
}) || die "undefined object id";
646 $self->{dbh
}->begin_work;
648 $self->{dbh
}->do("DELETE FROM Attribut " .
649 "WHERE Object_ID = ?", undef, $obj->{id
});
651 $self->{dbh
}->do("DELETE FROM Object " .
655 $self->{dbh
}->commit;
658 $self->{dbh
}->rollback;
668 sub update_rule_attributes
{
669 my ($self, $rule) = @_;
671 my $types = [qw(what when from to)];
672 my $attributes = [qw(and invert)];
674 for my $type ($types->@*) {
675 for my $attribute ($attributes->@*) {
676 my $prop = "$type-$attribute";
678 # only save the values if they're set to 1
679 if ($rule->{$prop}) {
681 "INSERT INTO Rule_Attributes (Rule_ID, Name, Value) " .
683 "ON CONFLICT (Rule_ID, Name) DO UPDATE SET Value = ?", undef,
684 $rule->{id
}, $prop, $rule->{$prop}, $rule->{$prop},
688 "DELETE FROM Rule_Attributes " .
689 "WHERE Rule_ID = ? AND Name = ?", undef,
698 my ($self, $rule) = @_;
700 defined($rule->{name
}) ||
701 die "undefined rule attribute - name: ERROR";
702 defined($rule->{priority
}) ||
703 die "undefined rule attribute - priority: ERROR";
704 defined($rule->{active
}) ||
705 die "undefined rule attribute - active: ERROR";
706 defined($rule->{direction
}) ||
707 die "undefined rule attribute - direction: ERROR";
709 my $rulename = encode
('UTF-8', $rule->{name
});
710 if (defined($rule->{id
})) {
711 $self->{dbh
}->begin_work;
716 "SET Name = ?, Priority = ?, Active = ?, Direction = ? " .
717 "WHERE ID = ?", undef,
718 $rulename, $rule->{priority
}, $rule->{active
},
719 $rule->{direction
}, $rule->{id
});
721 $self->update_rule_attributes($rule);
723 $self->{dbh
}->commit;
727 $self->{dbh
}->rollback;
732 $self->{dbh
}->begin_work;
735 my $sth = $self->{dbh
}->prepare(
736 "INSERT INTO Rule (Name, Priority, Active, Direction) " .
737 "VALUES (?, ?, ?, ?);");
739 $sth->execute($rulename, $rule->priority, $rule->active,
743 $rule->{id
} = PMG
::Utils
::lastid
($self->{dbh
}, 'rule_id_seq');
745 $self->update_rule_attributes($rule);
747 $self->{dbh
}->commit;
751 $self->{dbh
}->rollback;
761 my ($self, $ruleid) = @_;
763 defined($ruleid) || die "undefined rule id: ERROR";
766 $self->{dbh
}->begin_work;
768 $self->{dbh
}->do("DELETE FROM Rule " .
769 "WHERE ID = ?", undef, $ruleid);
770 $self->{dbh
}->do("DELETE FROM RuleGroup " .
771 "WHERE Rule_ID = ?", undef, $ruleid);
772 $self->{dbh
}->commit;
775 $self->{dbh
}->rollback;
783 sub delete_testrules
{
787 $self->{dbh
}->begin_work;
789 my $sth = $self->{dbh
}->prepare("Select id FROM Rule " .
790 "WHERE name = 'testrule'");
793 while(my $ref = $sth->fetchrow_hashref()) {
794 $self->{dbh
}->do("DELETE FROM Rule " .
795 "WHERE ID = ?", undef, $ref->{id
});
796 $self->{dbh
}->do("DELETE FROM RuleGroup " .
797 "WHERE Rule_ID = ?", undef, $ref->{id
});
801 $self->{dbh
}->commit;
804 $self->{dbh
}->rollback;
811 my $grouptype_hash = {
820 my ($self, $ruleid, $groupid, $gtype_str) = @_;
822 my $gtype = $grouptype_hash->{$gtype_str} //
823 die "unknown group type '$gtype_str'\n";
825 defined($ruleid) || die "undefined rule id: ERROR";
826 defined($groupid) || die "undefined group id: ERROR";
827 defined($gtype) || die "undefined group type: ERROR";
829 $self->{dbh
}->do("INSERT INTO RuleGroup " .
830 "(Objectgroup_ID, Rule_ID, Grouptype) " .
831 "VALUES (?, ?, ?)", undef,
832 $groupid, $ruleid, $gtype);
836 sub rule_add_from_group
{
837 my ($self, $rule, $group) = @_;
839 $self->rule_add_group($rule->{id
}, $group->{id
}, 'from');
842 sub rule_add_to_group
{
843 my ($self, $rule, $group) = @_;
845 $self->rule_add_group($rule->{id
}, $group->{id
}, 'to');
848 sub rule_add_when_group
{
849 my ($self, $rule, $group) = @_;
851 $self->rule_add_group($rule->{id
}, $group->{id
}, 'when');
854 sub rule_add_what_group
{
855 my ($self, $rule, $group) = @_;
857 $self->rule_add_group($rule->{id
}, $group->{id
}, 'what');
860 sub rule_add_action
{
861 my ($self, $rule, $group) = @_;
863 $self->rule_add_group($rule->{id
}, $group->{id
}, 'action');
866 sub rule_remove_group
{
867 my ($self, $ruleid, $groupid, $gtype_str) = @_;
869 my $gtype = $grouptype_hash->{$gtype_str} //
870 die "unknown group type '$gtype_str'\n";
872 defined($ruleid) || die "undefined rule id: ERROR";
873 defined($groupid) || die "undefined group id: ERROR";
874 defined($gtype) || die "undefined group type: ERROR";
876 $self->{dbh
}->do("DELETE FROM RuleGroup WHERE " .
877 "Objectgroup_ID = ? and Rule_ID = ? and Grouptype = ?",
878 undef, $groupid, $ruleid, $gtype);
882 sub load_rule_attributes
{
883 my ($self, $rule) = @_;
885 my $types = [qw(what when from to)];
886 my $attributes = [qw(and invert)];
888 my $attribute_sth = $self->{dbh
}->prepare("SELECT * FROM Rule_Attributes WHERE Rule_ID = ?");
889 $attribute_sth->execute($rule->{id
});
891 while (my $ref = $attribute_sth->fetchrow_hashref()) {
892 if ($ref->{name
} =~ m/^((?:what|when|from|to)-(?:and|invert))$/) {
894 $rule->{$prop} = $ref->{value
};
900 my ($self, $id) = @_;
902 defined($id) || die "undefined id: ERROR";
904 $self->{dbh
}->begin_work;
909 my $sth = $self->{dbh
}->prepare(
910 "SELECT * FROM Rule where id = ? ORDER BY Priority DESC");
914 my $ref = $sth->fetchrow_hashref();
915 die "rule '$id' does not exist\n" if !defined($ref);
917 $rule = PMG
::RuleDB
::Rule-
>new($ref->{name
}, $ref->{priority
},
918 $ref->{active
}, $ref->{direction
});
919 $rule->{id
} = $ref->{id
};
921 $self->load_rule_attributes($rule);
925 $self->{dbh
}->rollback; # finish transaction
935 my $sth = $self->{dbh
}->prepare(
936 "SELECT * FROM Rule ORDER BY Priority DESC");
942 while (my $ref = $sth->fetchrow_hashref()) {
943 my $rulename = PMG
::Utils
::try_decode_utf8
($ref->{name
});
944 my $rule = PMG
::RuleDB
::Rule-
>new($rulename, $ref->{priority
},
945 $ref->{active
}, $ref->{direction
});
946 $rule->{id
} = $ref->{id
};
963 The RuleDB Object manages the database connection and provides an interface to manipulate the database without SQL. A typical application first create a RuleDB object:
967 $ruledb = PMG::RuleDB->new();
969 =head2 Database Overview
973 Rules contains sets of Groups, grouped by classes (FROM, TO, WHEN, WHAT and ACTION). Each rule has an associated priority and and active/inactive marker.
977 A Group is a set of Objects.
981 Objects contains the filter data.
983 =head3 Rule Semantics
985 The classes have 'and' semantics. A rule matches if the checks in FROM, TO, WHEN and WHAT classes returns TRUE.
987 Within a class the objects are or'ed together.
989 =head2 Managing Rules
991 =head3 $ruledb->load_rules()
993 Returns an array of Rules containing all rules in the database.
995 =head3 $ruledb->save_rule ($rule)
997 One can use the following code to add a new rule to the database:
999 my $rule = PMG::RuleDB::Rule->new ($name, $priority, $active);
1000 $ruledb->save_rule ($rule);
1002 You can also use save_rule() to commit changes back to the database.
1004 =head3 $ruledb->delete_rule ($ruleid)
1006 Removes the rule from the database.
1008 =head3 $ruledb->rule_add_group ($rule, $og, $gtype)
1010 Add an object group to the rule.
1012 Possible values for $gtype are:
1014 'from' 'to', 'when', 'what', 'action'
1016 =head3 $ruledb->rule_remove_group ($rule, $og, $gtype)
1018 Removes an object group from the rule.
1020 =head2 Managing Objects and Groups
1022 =head3 $ruledb->load_groups ($rule)
1024 Return all object groups belonging to a rule. Data is divided into separate arrays:
1026 my ($from, $to, $when, $what, $action) =
1027 $ruledb->load_groups($rule);
1029 =head3 $ruledb->save_group ($og)
1031 This can be used to add or modify an Group. This code segemnt creates
1034 $og = PMG::RuleDB::Group->new ($name, $desc);
1035 $ruledb->save_group ($og);
1038 =head3 $ruledb->delete_group ($groupid)
1040 Deletes the object group, all reference to the group and all objects
1041 belonging to this group from the Database.
1043 =head3 $ruledb->group_add_object ($og, $obj)
1045 Attach an object to an object group.
1047 =head3 $ruledb->save_object ($obj)
1049 Save or update an object. This can be used to add new objects
1050 to the database (although group_add_object() is the preferred way):
1052 $obj = PMG::RuleDB::EMail->new ('.*@mydomain.com');
1053 # we need to set the object group manually
1054 $obj->ogroup ($group->id);
1055 $ruledb->save_object ($obj);
1058 =head3 $ruledb->delete_object ($obj)
1060 Deletes the object, all references to the object and all object
1061 attributes from the database.