summaryrefslogtreecommitdiffstats
path: root/library/Director/Db/MembershipHousekeeping.php
blob: 4d1ae88373f56c25003733fad4e944cc1bcd0f24 (plain)
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<?php

namespace Icinga\Module\Director\Db;

use Icinga\Module\Director\Application\MemoryLimit;
use Icinga\Module\Director\Data\Db\DbConnection;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Db\Cache\PrefetchCache;
use Icinga\Module\Director\Objects\GroupMembershipResolver;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Objects\IcingaObjectGroup;

abstract class MembershipHousekeeping
{
    protected $type;

    protected $groupType;

    protected $connection;

    /** @var GroupMembershipResolver */
    protected $resolver;

    /** @var IcingaObject[] */
    protected $objects;

    /** @var IcingaObjectGroup[] */
    protected $groups;

    protected $prepared = false;

    protected static $instances = [];

    public function __construct(Db $connection)
    {
        $this->connection = $connection;

        if ($this->groupType === null) {
            $this->groupType = $this->type . 'Group';
        }
    }

    /**
     * @param string       $type
     * @param DbConnection $connection
     *
     * @return static
     */
    public static function instance($type, $connection)
    {
        if (! array_key_exists($type, self::$instances)) {
            /** @var MembershipHousekeeping $class */
            $class = 'Icinga\\Module\\Director\\Db\\' . ucfirst($type) . 'MembershipHousekeeping';

            /** @var MembershipHousekeeping $helper */
            self::$instances[$type] = new $class($connection);
        }

        return self::$instances[$type];
    }

    protected function prepare()
    {
        if ($this->prepared) {
            return $this;
        }

        $this->prepareCache();
        $this->resolver()->defer();

        $this->objects = IcingaObject::loadAllByType($this->type, $this->connection);
        $this->resolver()->addObjects($this->objects);

        $this->groups = IcingaObject::loadAllByType($this->groupType, $this->connection);
        $this->resolver()->addGroups($this->groups);

        MemoryLimit::raiseTo('1024M');

        $this->prepared = true;

        return $this;
    }

    public function check()
    {
        $this->prepare();

        $resolver = $this->resolver()->checkDb();

        return array($resolver->getNewMappings(), $resolver->getOutdatedMappings());
    }

    public function update()
    {
        $this->prepare();

        $this->resolver()->refreshDb(true);

        return true;
    }

    protected function prepareCache()
    {
        PrefetchCache::initialize($this->connection);

        IcingaObject::prefetchAllRelationsByType($this->type, $this->connection);
    }

    protected function resolver()
    {
        if ($this->resolver === null) {
            /** @var GroupMembershipResolver $class */
            $class = 'Icinga\\Module\\Director\\Objects\\' . ucfirst($this->type) . 'GroupMembershipResolver';
            $this->resolver = new $class($this->connection);
        }

        return $this->resolver;
    }

    /**
     * @return IcingaObject[]
     */
    public function getObjects()
    {
        return $this->objects;
    }

    /**
     * @return IcingaObjectGroup[]
     */
    public function getGroups()
    {
        return $this->groups;
    }
}