r1871 + implement IPv4 VS tag filtering
[racktables] / inc / database.php
index 5937bd12c32cd98d53e646dfcebe61fcad8ab453..aff37045ed37a3812269ae853454c9eceffd5261 100644 (file)
@@ -47,8 +47,22 @@ function getObjectTypeList ()
        return readChapter ('RackObjectType');
 }
 
-function getObjectList ($type_id = 0)
+function getObjectList ($type_id = 0, $tagfilter = array())
 {
+       $whereclause = '';
+       if ($type_id != 0)
+               $whereclause = " and objtype_id = '${type_id}' ";
+       if (count ($tagfilter))
+       {
+               $whereclause .= ' and (';
+               $orclause = '';
+               foreach ($tagfilter as $tag_id)
+               {
+                       $whereclause .= $orclause . 'tag_id = ' . $tag_id;
+                       $orclause = ' or ';
+               }
+               $whereclause .= ') ';
+       }
        $query =
                "select distinct RackObject.id as id , RackObject.name as name, dict_value as objtype_name, " .
                "RackObject.label as label, RackObject.barcode as barcode, " .
@@ -56,8 +70,10 @@ function getObjectList ($type_id = 0)
                "((RackObject inner join Dictionary on objtype_id=dict_key natural join Chapter) " .
                "left join RackSpace on RackObject.id = object_id) " .
                "left join Rack on rack_id = Rack.id " .
-               "where objtype_id = '${type_id}' and RackObject.deleted = 'no' " .
-               "and chapter_name = 'RackObjectType' order by name";
+               "left join TagStorage on RackObject.id = TagStorage.target_id and target_realm = 'object' " .
+               "where RackObject.deleted = 'no' and chapter_name = 'RackObjectType' " .
+               $whereclause .
+               "order by name";
        $result = useSelectBlade ($query);
        $ret = array();
        while ($row = $result->fetch (PDO::FETCH_ASSOC))
@@ -615,25 +631,28 @@ function getResidentRacksData ($object_id = 0, $fetch_rackdata = TRUE)
        return $ret;
 }
 
-function getObjectGroupInfo ($group_id = 0)
+function getObjectGroupInfo ()
 {
        $query =
                'select dict_key as id, dict_value as name, count(id) as count from ' .
                'Dictionary natural join Chapter left join RackObject on dict_key = objtype_id ' .
                'where chapter_name = "RackObjectType" ' .
-               (($group_id > 0) ? "and dict_key = ${group_id} " : '') .
-               'group by dict_key';
+               'group by dict_key order by dict_value';
        $result = useSelectBlade ($query);
        $ret = array();
+       $ret[0] = array ('id' => 0, 'name' => 'ALL types');
        $clist = array ('id', 'name', 'count');
+       $total = 0;
        while ($row = $result->fetch (PDO::FETCH_ASSOC))
-               foreach ($clist as $dummy => $cname)
-                       $ret[$row['id']][$cname] = $row[$cname];
+               if ($row['count'] > 0)
+               {
+                       $total += $row['count'];
+                       foreach ($clist as $dummy => $cname)
+                               $ret[$row['id']][$cname] = $row[$cname];
+               }
        $result->closeCursor();
-       if ($group_id > 0)
-               return current ($ret);
-       else
-               return $ret;
+       $ret[0]['count'] = $total;
+       return $ret;
 }
 
 // This function returns objects, which have no rackspace assigned to them.
@@ -891,16 +910,29 @@ function getObjectAddresses ($object_id = 0)
        return $ret;
 }
 
-function getAddressspaceList ()
+function getAddressspaceList ($tagfilter = array())
 {
+       if (!count ($tagfilter))
+               $whereclause = '';
+       else
+       {
+               $whereclause = 'where ';
+               $orclause = '';
+               foreach ($tagfilter as $tag_id)
+               {
+                       $whereclause .= $orclause . 'tag_id = ' . $tag_id;
+                       $orclause = ' or ';
+               }
+       }
        $query =
-               "select ".
+               "select distinct ".
                "id as IPRanges_id, ".
                "INET_NTOA(ip) as IPRanges_ip, ".
                "mask as IPRanges_mask, ".
                "name as IPRanges_name ".
-               "from IPRanges ".
-               "order by ip";
+               "from IPRanges left join TagStorage on IPRanges.id = TagStorage.target_id and target_realm = 'ipv4net' " .
+               $whereclause .
+               " order by ip";
        $result = useSelectBlade ($query);
        $ret=array();
        $count=0;
@@ -1061,6 +1093,38 @@ function searchByl2address ($l2addr)
        return NULL;
 }
 
+function getIPv4PrefixSearchResult ($terms)
+{
+       $query = "select id, inet_ntoa(ip) as ip, mask, name from IPRanges where ";
+       $or = '';
+       foreach (explode (' ', $terms) as $term)
+       {
+               $query .= $or . "name like '%${term}%'";
+               $or = ' or ';
+       }
+       $result = useSelectBlade ($query);
+       $ret = array();
+       while ($row = $result->fetch (PDO::FETCH_ASSOC))
+               $ret[] = $row;
+       return $ret;
+}
+
+function getIPv4AddressSearchResult ($terms)
+{
+       $query = "select inet_ntoa(ip) as ip, name from IPAddress where ";
+       $or = '';
+       foreach (explode (' ', $terms) as $term)
+       {
+               $query .= $or . "name like '%${term}%'";
+               $or = ' or ';
+       }
+       $result = useSelectBlade ($query);
+       $ret = array();
+       while ($row = $result->fetch (PDO::FETCH_ASSOC))
+               $ret[] = $row;
+       return $ret;
+}
+
 // This function returns either port ID or NULL for specified arguments.
 function getPortID ($object_id, $port_name)
 {
@@ -1611,7 +1675,7 @@ function getAttrValues ($object_id, $strip_optgroup = FALSE)
                "left join AttributeValue as AV on AV.attr_id = AM.attr_id and AV.object_id = RO.id " .
                "left join Dictionary as D on D.dict_key = AV.uint_value and AM.chapter_no = D.chapter_no " .
                "left join Chapter as C on AM.chapter_no = C.chapter_no " .
-               "where RO.id = ${object_id} order by A.attr_type";
+               "where RO.id = ${object_id} order by A.attr_type, A.attr_name";
        $result = useSelectBlade ($query);
        while ($row = $result->fetch (PDO::FETCH_ASSOC))
        {
@@ -1765,13 +1829,14 @@ function useInsertBlade ($tablename, $values)
 
 // This swiss-knife blade deletes one record from the specified table
 // using the specified key name and value.
-function useDeleteBlade ($tablename, $keyname, $keyvalue, $quotekey = TRUE)
+function useDeleteBlade ($tablename, $keyname, $keyvalue, $quotekey = TRUE, $deleteall = FALSE)
 {
        global $dbxlink;
        if ($quotekey == TRUE)
-               $query = "delete from ${tablename} where ${keyname}='$keyvalue' limit 1";
-       else
-               $query = "delete from ${tablename} where ${keyname}=$keyvalue limit 1";
+               $keyvalue = "'${keyvalue}'";
+       $query = "delete from ${tablename} where ${keyname}=$keyvalue";
+       if (!$deleteall)
+               $query .= ' limit 1';
        $result = $dbxlink->exec ($query);
        if ($result === NULL)
                return FALSE;
@@ -2138,11 +2203,24 @@ function commitUpdateVS ($vsid = 0, $vip = '', $vport = 0, $proto = '', $name =
 
 // Return the list of virtual services, indexed by vs_id.
 // Each record will be shown with its basic info plus RS pools counter.
-function getVSList ()
+function getVSList ($tagfilter = array())
 {
+       if (!count ($tagfilter))
+               $whereclause = '';
+       else
+       {
+               $whereclause = 'where ';
+               $orclause = '';
+               foreach ($tagfilter as $tag_id)
+               {
+                       $whereclause .= $orclause . 'tag_id = ' . $tag_id;
+                       $orclause = ' or ';
+               }
+       }
        $query = "select vs.id, inet_ntoa(vip) as vip, vport, proto, vs.name, vs.vsconfig, vs.rsconfig, count(rspool_id) as poolcount " .
                "from IPVirtualService as vs left join IPLoadBalancer as lb on vs.id = lb.vs_id " .
-               "group by vs.id order by vs.vip, proto, vport";
+               "left join TagStorage on vs.id = TagStorage.target_id and target_realm = 'ipv4vs' " . 
+               "${whereclause} group by vs.id order by vs.vip, proto, vport";
        $result = useSelectBlade ($query);
        $ret = array ();
        while ($row = $result->fetch (PDO::FETCH_ASSOC))
@@ -2380,29 +2458,107 @@ function executeAutoPorts ($object_id = 0, $type_id = 0)
 
 // Return only implicitly listed tags, the rest of the trail will be
 // generated/deducted later at higher levels.
-function loadRackObjectTags ($object_id = 0)
+function loadEntityTags ($entity_realm = '', $entity_id = 0)
 {
+       if ($entity_realm == '' or $entity_id <= 0)
+       {
+               showError ('Invalid or missing arguments', __FUNCTION__);
+               return NULL;
+       }
        $ret = array();
-       $result = useSelectBlade ("select tt.id, tag from RackObject as ro inner join RackObjectTags as rot on ro.id = rot.object_id inner join TagTree as tt on rot.tag_id = tt.id");
+       $result = useSelectBlade ("select tt.id, tag from TagStorage as ts inner join TagTree as tt on ts.tag_id = tt.id where target_realm = '${entity_realm}' and target_id = ${entity_id}");
        while ($row = $result->fetch (PDO::FETCH_ASSOC))
                $ret[$row['id']] = $row;
        $result->closeCursor();
        return $ret;
 }
 
+function loadRackObjectTags ($id)
+{
+       return loadEntityTags ('object', $id);
+}
+
+function loadIPv4PrefixTags ($id)
+{
+       return loadEntityTags ('ipv4net', $id);
+}
+
+function loadRackTags ($id)
+{
+       return loadEntityTags ('rack', $id);
+}
+
+function loadIPv4VSTags ($id)
+{
+       return loadEntityTags ('ipv4vs', $id);
+}
+
+function loadIPv4RSPoolTags ($id)
+{
+       return loadEntityTags ('ipv4rspool', $id);
+}
+
 function getTagList ()
 {
-       $taglist = array();
-       $result = useSelectBlade ("select id, parent_id, tag from TagTree order by tag");
+       $ret = array();
+       $query = "select id, parent_id, tag, target_realm as realm, count(target_id) as refcnt " .
+               "from TagTree left join TagStorage on id = tag_id " .
+               "group by id, target_realm order by tag";
+       $result = useSelectBlade ($query);
        while ($row = $result->fetch (PDO::FETCH_ASSOC))
-               $taglist[$row['id']] = array
-               (
-                       'id' => $row['id'],
-                       'tag' => $row['tag'],
-                       'parent_id' => $row['parent_id']
-               );
+       {
+               if (!isset ($ret[$row['id']]))
+                       $ret[$row['id']] = array
+                       (
+                               'id' => $row['id'],
+                               'tag' => $row['tag'],
+                               'parent_id' => $row['parent_id'],
+                               'refcnt' => array()
+                       );
+               if ($row['realm'])
+                       $ret[$row['id']]['refcnt'][$row['realm']] = $row['refcnt'];
+       }
        $result->closeCursor();
-       return $taglist;
+       return $ret;
+}
+
+function commitCreateTag ($tagname = '', $parent_id = 0)
+{
+       if ($tagname == '' or $parent_id === 0)
+               return "Invalid args to " . __FUNCTION__;
+       $result = useInsertBlade
+       (
+               'TagTree',
+               array
+               (
+                       'tag' => "'${tagname}'",
+                       'parent_id' => $parent_id
+               )
+       );
+       if ($result)
+               return '';
+       else
+               return "SQL query failed in " . __FUNCTION__;
+}
+
+function commitDestroyTag ($tagid = 0)
+{
+       if ($tagid == 0)
+               return 'Invalid arg to ' . __FUNCTION__;
+       if (useDeleteBlade ('TagTree', 'id', $tagid, FALSE))
+               return '';
+       else
+               return 'useDeleteBlade() failed in ' . __FUNCTION__;
+}
+
+function wipeTags ($realm, $id)
+{
+       global $dbxlink;
+       $query = "delete from TagStorage where target_realm = '${realm}' and target_id = ${id}";
+       $result = $dbxlink->exec ($query);
+       if ($result === NULL)
+               return FALSE;
+       return TRUE;
 }
 
 ?>