fixup the next release version (0.20.6 -> 0.21.0)
use nullEmptyStr function

changed funcs:
  commitUpdatePort
  commitUpdatePortLink
new 'stringN' genericAssertion type

stringN returns NULL if argument is empty
speed-up autoports trigger

trigger_autoports: use new getObjectPortCount DB func
DB transactions on WDM PortCompat pack ops

changed funcs:
  addOIFCompatPack
  delOIFCompatPack
getPortInfo, getPortLinkInfo: throw exceptions

these functions used to return empty values if port or link with given
id did not exist. Now they throw the EntityNotFoundException.

updateCableIdAJAX: don't re-check value and throw an exception
EntityNotFoundException::dispatch: don't redirect user to the main page
	if he is not on the entity's page.
make PortCompat symmetric (both RL and LR pairs)

addPortOIFCompat: ophandler
deletePortOIFCompat: ophandler
insert missing reversed-order pairs in install.php, upgrade.php
reordered and removed RL pairs in install.php

Conflicts:
	wwwroot/inc/upgrade.php
new iif=0 (crossed)

genericAssertion: changed iif check (0 is fine)
addIIFOIFCompat: uint -> iif
opspec[portifcompat-edit-del]: uint -> iif
install.php, upgrade.php: new crossed iif row

Conflicts:
	wwwroot/inc/upgrade.php
convert PP ports into 8P8C, new PPs = 24x8P8C

renderAutoPortsForm: used to support only hardwired ports, fixed
patchpanels feature is refactored

The main idea of this change is to separate links between
ports by two classes: L2 (link-layer) and L1 (physical layer).
If a link connects at least one port of an L1 type (iif = 0),
it is considered an L1 link.

There are features dependent of links: LLDP/CDP neighbor discovery,
802.1Q, some user's local plug-ins. They were written in assumption that
there is only one link for every single port, and they treat all links
as L2.

This change keeps the compatibility with the old code: L2 links may
appear only once on each port, and their data is stored in $portinfo
structure ('remote_id', 'remote_name' as other keys) as before.

This model reflects the reality more accurately: one rarely has multiple
link-layer connections via a single port.

changes:
	DEFAULT_PORT_IIF_ID - syntax change, ability to select multiple iifs

	fetchPortList: the structure format changed, it is almost reverted to the previous one.
		SQL queries are optimised to use indices.
	linkPorts: clear port reservation only if an L2 link is established
	commitUnlinkPort: re-use fetchPortList
	getPortListPrefs: new syntax of DEFAULT_PORT_IIF_ID (multiple expanded iifs)
	getNewPortTypeOptions: moved into interface-lib.php, renamed into getPortTypeSelect()
	formatPortIIFOIF: ability to format crossed ports into port type select boxes
	sortLinks: links are not indexed by id, variable rename
	renderPopupTraceRoute: ports are not indexed by id, variable rename
	renderObjectPortRow: use new portinfo structure format
	renderPortsForObject: idem, spaghetti-code refactored
	op object-ports-editLink is now handled by tableHandler
	editPortForObject: new form params set
	findSparePorts: new 'l1_only' filter
	renderPopupPortSelector: idem
	renderPopupHTML: dont concatenate function names, make it possible to grep on them

upgrade procedure (against 0.20.5):
	change the DEFAULT_PORT_IIF_ID config var type and value
	add id, porta_type, portb_type, PortCompat constaint to the Link table, force porta < portb
	create used, but missing PortCompat pairs (to be sure PortCompat constraint will comply to user's links)
	assign insert/update trigger to the Link table to:
		- forbid connecting a port to itself
		- force porta < portb
		- fill not specified default values of porta_type, portb_type
		- if both ports are of L2 type, ensure they have no other L2 links

Conflicts:
	ChangeLog
	README
	wwwroot/inc/database.php
	wwwroot/inc/upgrade.php
repair 'port type can now be changed while linked'

getExistingPortTypeOptions:
	prototype changed, now takes $portinfo as a parameter
	intersection of links' compatibility sets
fetchPortList: new fields in portinfo's link structure: remote_iif_id, remote_oif_id
renderPortsForObject: simply use getExistingPortTypeOptions
handlePopupPortLink: new getExistingPortTypeOptions prototype
bugfix: display links on 802.1Q tab correctly

fetchPortList: keep compatibility with the old version
formatLinkedPort: revert ['links'] stuff
fixup version again
spelling