Storing IPv4 addresses as integers (rather than strings)
String IP addresses displayed in tables don't sort naturally. e.g., x.x.x.1, x.x.x.10, x.x.x.11, x.x.x.2.
Storing the IP addresses in the database as a 32-bit integer (which is what they are supposed to represent), and returning those to a table column but rendering them with a view to convert to four-decimal octet format solves the sorting problem.
From IP address to integer
With the built-in expression language the job can be done in two stages (to simplify the expression):
Initial expression
split({path.to.IP.as.string}, '\\.')
Expression transform
// Doing this in two steps allows the use of {value} rather than multiple splits.
({value}[0, 0] << 24)
+ ({value}[1, 0] << 16)
+ ({value}[2, 0] << 8)
+ ({value}[3, 0] << 0)
With the Integration Toolkit it can be done in one go.
Integration Toolkit solution
transform(
split({path.to.IP.as.string}, '\\.'),
(value()[0, 0] << 24) +
(value()[1, 0] << 16) +
(value()[2, 0] << 8) +
(value()[3, 0] << 0)
)
These expressions assume that the incoming IP ≥ 1.x.x.x.
From integer to IP address
With the built-in expression language the job can be done in two stages (to simplify the expression):
Initial expression
toInt({../lblIp2IntExpression.props.text})
Expression transform
// Doing this in two steps allows the use of {value} rather than multiple splits.
stringFormat(
"%d.%d.%d.%d",
({value} >> 24) & 0xff,
({value} >> 16) & 0xff,
({value} >> 8) & 0xff,
{value} & 0xff
)
With the Integration Toolkit it can be done in one go.
Integration Toolkit solution
// This was my original attempt.
// See Phil's improved solution below.
transform(
right('0' + toHex({path.to.IP.as.integer}), 8),
fromHex(subString(value(), 0, 2)) + '.' +
fromHex(subString(value(), 2, 4)) + '.' +
fromHex(subString(value(), 4, 6)) + '.' +
fromHex(subString(value(), 6, 8))
)
These expressions assume that the incoming integer represents an IP ≥ 1.x.x.x.
Edit by Phil: I would do the conversion to display without using hex strings.
Better Integration Toolkit Solution
transform(
toInt({path.to.IP.as.integer}),
stringFormat(
"%d.%d.%d.%d",
(value() >> 24) & 0xff,
(value() >> 16) & 0xff,
(value() >> 8) & 0xff,
value() & 0xff
)
)
Does not require the leading octet to be ≥1.
IPv6 is not addressed by these functions.