Rename phone_number to packed_phone_number
This commit is contained in:
parent
62ca2ab7f3
commit
4e04898fc1
10
README.md
10
README.md
|
@ -13,14 +13,10 @@ get it there.
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
CREATE EXTENSION pg_libphonenumber;
|
CREATE EXTENSION pg_libphonenumber;
|
||||||
SELECT parse_phone_number('03 7010 1234', 'AU');
|
SELECT parse_packed_phone_number('03 7010 1234', 'AU');
|
||||||
SELECT parse_phone_number('2819010011', 'US');
|
SELECT parse_packed_phone_number('2819010011', 'US');
|
||||||
|
|
||||||
CREATE TABLE foo ( ph phone_number );
|
CREATE TABLE foo ( ph packed_phone_number );
|
||||||
|
|
||||||
-- DO NOT RELY ON THIS
|
|
||||||
-- may not always this work way with implicit cast.
|
|
||||||
SELECT '2819010011'::phone_number; -- assumes US
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
CREATE EXTENSION IF NOT EXISTS pg_libphonenumber;
|
CREATE EXTENSION IF NOT EXISTS pg_libphonenumber;
|
||||||
--Test phone number parsing
|
--Test phone number parsing
|
||||||
select parse_phone_number('555-555-5555', 'US');
|
select parse_packed_phone_number('555-555-5555', 'US');
|
||||||
parse_phone_number
|
parse_packed_phone_number
|
||||||
--------------------
|
---------------------------
|
||||||
+1 555-555-5555
|
+1 555-555-5555
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
--These two should produce errors because the number is too long.
|
--These two should produce errors because the number is too long.
|
||||||
--Produces an error in pg-libphonenumber's code
|
--Produces an error in pg-libphonenumber's code
|
||||||
select parse_phone_number('555-555-5555555555', 'US');
|
select parse_packed_phone_number('555-555-5555555555', 'US');
|
||||||
ERROR: phone number '+1 5555555555555555' is too long
|
ERROR: phone number '+1 5555555555555555' is too long
|
||||||
DETAIL: National number is too long
|
DETAIL: National number is too long
|
||||||
--Produces an error from libphonenumber
|
--Produces an error from libphonenumber
|
||||||
select parse_phone_number('555-555-55555555555', 'US');
|
select parse_packed_phone_number('555-555-55555555555', 'US');
|
||||||
ERROR: unable to parse '555-555-55555555555' as a phone number
|
ERROR: unable to parse '555-555-55555555555' as a phone number
|
||||||
DETAIL: National number is too long
|
DETAIL: National number is too long
|
||||||
-- Do we get correct country codes?
|
-- Do we get correct country codes?
|
||||||
-- TODO: expand.
|
-- TODO: expand.
|
||||||
select phone_number_country_code(parse_phone_number('+1-555-555-5555', 'USA'));
|
select phone_number_country_code(parse_packed_phone_number('+1-555-555-5555', 'USA'));
|
||||||
phone_number_country_code
|
phone_number_country_code
|
||||||
---------------------------
|
---------------------------
|
||||||
1
|
1
|
||||||
|
|
|
@ -2,56 +2,52 @@
|
||||||
\echo Use "CREATE EXTENSION pg_libphonenumber" to load this file. \quit
|
\echo Use "CREATE EXTENSION pg_libphonenumber" to load this file. \quit
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Phone number type
|
-- Packed number type
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE TYPE phone_number;
|
CREATE TYPE packed_phone_number;
|
||||||
|
|
||||||
CREATE FUNCTION phone_number_in(cstring) RETURNS phone_number
|
CREATE FUNCTION packed_phone_number_in(cstring) RETURNS packed_phone_number
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'phone_number_in';
|
AS 'pg_libphonenumber', 'packed_phone_number_in';
|
||||||
|
|
||||||
CREATE FUNCTION phone_number_out(phone_number) RETURNS cstring
|
CREATE FUNCTION packed_phone_number_out(packed_phone_number) RETURNS cstring
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'phone_number_out';
|
AS 'pg_libphonenumber', 'packed_phone_number_out';
|
||||||
|
|
||||||
CREATE FUNCTION phone_number_recv(internal) RETURNS phone_number
|
CREATE FUNCTION packed_phone_number_recv(internal) RETURNS packed_phone_number
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'phone_number_recv';
|
AS 'pg_libphonenumber', 'packed_phone_number_recv';
|
||||||
|
|
||||||
CREATE FUNCTION phone_number_send(phone_number) RETURNS bytea
|
CREATE FUNCTION packed_phone_number_send(packed_phone_number) RETURNS bytea
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'phone_number_send';
|
AS 'pg_libphonenumber', 'packed_phone_number_send';
|
||||||
|
|
||||||
CREATE TYPE phone_number (
|
CREATE TYPE packed_phone_number (
|
||||||
INTERNALLENGTH = 8,
|
INTERNALLENGTH = 8,
|
||||||
INPUT = phone_number_in,
|
INPUT = packed_phone_number_in,
|
||||||
OUTPUT = phone_number_out,
|
OUTPUT = packed_phone_number_out,
|
||||||
RECEIVE = phone_number_recv,
|
RECEIVE = packed_phone_number_recv,
|
||||||
SEND = phone_number_send,
|
SEND = packed_phone_number_send,
|
||||||
ALIGNMENT = double,
|
ALIGNMENT = double,
|
||||||
STORAGE = plain
|
STORAGE = plain
|
||||||
);
|
);
|
||||||
|
|
||||||
--
|
|
||||||
-- Casts
|
-- Casts
|
||||||
--
|
|
||||||
|
|
||||||
CREATE CAST (phone_number AS text)
|
CREATE CAST (packed_phone_number AS text)
|
||||||
WITH INOUT;
|
WITH INOUT;
|
||||||
|
|
||||||
--
|
|
||||||
-- Operators and indexing
|
-- Operators and indexing
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION phone_number_equal(phone_number, phone_number) RETURNS bool
|
CREATE FUNCTION packed_phone_number_equal(packed_phone_number, packed_phone_number) RETURNS bool
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'phone_number_equal';
|
AS 'pg_libphonenumber', 'packed_phone_number_equal';
|
||||||
|
|
||||||
CREATE OPERATOR = (
|
CREATE OPERATOR = (
|
||||||
leftarg = phone_number,
|
leftarg = packed_phone_number,
|
||||||
rightarg = phone_number,
|
rightarg = packed_phone_number,
|
||||||
procedure = phone_number_equal,
|
procedure = packed_phone_number_equal,
|
||||||
commutator = =,
|
commutator = =,
|
||||||
negator = <>,
|
negator = <>,
|
||||||
restrict = eqsel,
|
restrict = eqsel,
|
||||||
|
@ -60,97 +56,99 @@ CREATE OPERATOR = (
|
||||||
merges = true
|
merges = true
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE FUNCTION phone_number_not_equal(phone_number, phone_number) RETURNS bool
|
CREATE FUNCTION packed_phone_number_not_equal(packed_phone_number, packed_phone_number) RETURNS bool
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'phone_number_not_equal';
|
AS 'pg_libphonenumber', 'packed_phone_number_not_equal';
|
||||||
|
|
||||||
CREATE OPERATOR <> (
|
CREATE OPERATOR <> (
|
||||||
leftarg = phone_number,
|
leftarg = packed_phone_number,
|
||||||
rightarg = phone_number,
|
rightarg = packed_phone_number,
|
||||||
procedure = phone_number_not_equal,
|
procedure = packed_phone_number_not_equal,
|
||||||
commutator = <>,
|
commutator = <>,
|
||||||
negator = =,
|
negator = =,
|
||||||
restrict = neqsel,
|
restrict = neqsel,
|
||||||
join = neqjoinsel
|
join = neqjoinsel
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE FUNCTION phone_number_less(phone_number, phone_number) RETURNS bool
|
CREATE FUNCTION packed_phone_number_less(packed_phone_number, packed_phone_number) RETURNS bool
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'phone_number_less';
|
AS 'pg_libphonenumber', 'packed_phone_number_less';
|
||||||
|
|
||||||
CREATE OPERATOR < (
|
CREATE OPERATOR < (
|
||||||
leftarg = phone_number,
|
leftarg = packed_phone_number,
|
||||||
rightarg = phone_number,
|
rightarg = packed_phone_number,
|
||||||
procedure = phone_number_less,
|
procedure = packed_phone_number_less,
|
||||||
commutator = >,
|
commutator = >,
|
||||||
negator = >=,
|
negator = >=,
|
||||||
restrict = scalarltsel,
|
restrict = scalarltsel,
|
||||||
join = scalarltjoinsel
|
join = scalarltjoinsel
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE FUNCTION phone_number_less_or_equal(phone_number, phone_number) RETURNS bool
|
CREATE FUNCTION packed_phone_number_less_or_equal(packed_phone_number, packed_phone_number) RETURNS bool
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'phone_number_less_or_equal';
|
AS 'pg_libphonenumber', 'packed_phone_number_less_or_equal';
|
||||||
|
|
||||||
CREATE OPERATOR <= (
|
CREATE OPERATOR <= (
|
||||||
leftarg = phone_number,
|
leftarg = packed_phone_number,
|
||||||
rightarg = phone_number,
|
rightarg = packed_phone_number,
|
||||||
procedure = phone_number_less_or_equal,
|
procedure = packed_phone_number_less_or_equal,
|
||||||
commutator = >=,
|
commutator = >=,
|
||||||
negator = >,
|
negator = >,
|
||||||
restrict = scalarltsel,
|
restrict = scalarltsel,
|
||||||
join = scalarltjoinsel
|
join = scalarltjoinsel
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE FUNCTION phone_number_greater(phone_number, phone_number) RETURNS bool
|
CREATE FUNCTION packed_phone_number_greater(packed_phone_number, packed_phone_number) RETURNS bool
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'phone_number_greater';
|
AS 'pg_libphonenumber', 'packed_phone_number_greater';
|
||||||
|
|
||||||
CREATE OPERATOR > (
|
CREATE OPERATOR > (
|
||||||
leftarg = phone_number,
|
leftarg = packed_phone_number,
|
||||||
rightarg = phone_number,
|
rightarg = packed_phone_number,
|
||||||
procedure = phone_number_greater,
|
procedure = packed_phone_number_greater,
|
||||||
commutator = >,
|
commutator = >,
|
||||||
negator = <=,
|
negator = <=,
|
||||||
restrict = scalargtsel,
|
restrict = scalargtsel,
|
||||||
join = scalargtjoinsel
|
join = scalargtjoinsel
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE FUNCTION phone_number_greater_or_equal(phone_number, phone_number) RETURNS bool
|
CREATE FUNCTION packed_phone_number_greater_or_equal(packed_phone_number, packed_phone_number) RETURNS bool
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'phone_number_greater_or_equal';
|
AS 'pg_libphonenumber', 'packed_phone_number_greater_or_equal';
|
||||||
|
|
||||||
CREATE OPERATOR >= (
|
CREATE OPERATOR >= (
|
||||||
leftarg = phone_number,
|
leftarg = packed_phone_number,
|
||||||
rightarg = phone_number,
|
rightarg = packed_phone_number,
|
||||||
procedure = phone_number_greater_or_equal,
|
procedure = packed_phone_number_greater_or_equal,
|
||||||
commutator = >=,
|
commutator = >=,
|
||||||
negator = <,
|
negator = <,
|
||||||
restrict = scalargtsel,
|
restrict = scalargtsel,
|
||||||
join = scalargtjoinsel
|
join = scalargtjoinsel
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE FUNCTION phone_number_cmp(phone_number, phone_number) RETURNS integer
|
CREATE FUNCTION packed_phone_number_cmp(packed_phone_number, packed_phone_number) RETURNS integer
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'phone_number_cmp';
|
AS 'pg_libphonenumber', 'packed_phone_number_cmp';
|
||||||
|
|
||||||
CREATE OPERATOR CLASS phone_number_ops
|
CREATE OPERATOR CLASS packed_phone_number_ops
|
||||||
DEFAULT FOR TYPE phone_number USING btree AS
|
DEFAULT FOR TYPE packed_phone_number USING btree AS
|
||||||
OPERATOR 1 <,
|
OPERATOR 1 <,
|
||||||
OPERATOR 2 <=,
|
OPERATOR 2 <=,
|
||||||
OPERATOR 3 =,
|
OPERATOR 3 =,
|
||||||
OPERATOR 4 >=,
|
OPERATOR 4 >=,
|
||||||
OPERATOR 5 >,
|
OPERATOR 5 >,
|
||||||
FUNCTION 1 phone_number_cmp(phone_number, phone_number);
|
FUNCTION 1 packed_phone_number_cmp(packed_phone_number, packed_phone_number);
|
||||||
|
|
||||||
|
-- Constructors
|
||||||
|
|
||||||
|
CREATE FUNCTION parse_packed_phone_number(text, text) RETURNS packed_phone_number
|
||||||
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
|
AS 'pg_libphonenumber', 'parse_packed_phone_number';
|
||||||
|
|
||||||
--
|
--
|
||||||
-- General functions
|
-- General functions
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE FUNCTION parse_phone_number(text, text) RETURNS phone_number
|
CREATE FUNCTION phone_number_country_code(packed_phone_number) RETURNS integer
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
LANGUAGE c IMMUTABLE STRICT
|
||||||
AS 'pg_libphonenumber', 'parse_phone_number';
|
AS 'pg_libphonenumber', 'packed_phone_number_country_code';
|
||||||
|
|
||||||
CREATE FUNCTION phone_number_country_code(phone_number) RETURNS integer
|
|
||||||
LANGUAGE c IMMUTABLE STRICT
|
|
||||||
AS 'pg_libphonenumber', 'phone_number_country_code';
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
CREATE EXTENSION IF NOT EXISTS pg_libphonenumber;
|
CREATE EXTENSION IF NOT EXISTS pg_libphonenumber;
|
||||||
|
|
||||||
--Test phone number parsing
|
--Test phone number parsing
|
||||||
select parse_phone_number('555-555-5555', 'US');
|
select parse_packed_phone_number('555-555-5555', 'US');
|
||||||
--These two should produce errors because the number is too long.
|
--These two should produce errors because the number is too long.
|
||||||
--Produces an error in pg-libphonenumber's code
|
--Produces an error in pg-libphonenumber's code
|
||||||
select parse_phone_number('555-555-5555555555', 'US');
|
select parse_packed_phone_number('555-555-5555555555', 'US');
|
||||||
--Produces an error from libphonenumber
|
--Produces an error from libphonenumber
|
||||||
select parse_phone_number('555-555-55555555555', 'US');
|
select parse_packed_phone_number('555-555-55555555555', 'US');
|
||||||
|
|
||||||
-- Do we get correct country codes?
|
-- Do we get correct country codes?
|
||||||
-- TODO: expand.
|
-- TODO: expand.
|
||||||
select phone_number_country_code(parse_phone_number('+1-555-555-5555', 'USA'));
|
select phone_number_country_code(parse_packed_phone_number('+1-555-555-5555', 'USA'));
|
||||||
|
|
|
@ -39,15 +39,13 @@ static char* text_to_c_string(const text* text) {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Internal function used by phone_number_in and parse_phone_number
|
//Internal function used by packed_phone_number_in and parse_packed_phone_number
|
||||||
//TODO: take a std::string to minimize copying?
|
//TODO: take a std::string to minimize copying?
|
||||||
//TODO: rename this so we're not relying on overloading to distinguish this from
|
PackedPhoneNumber* do_parse_packed_phone_number(const char* number_str, const char* country) {
|
||||||
// its extern "C" counterpart.
|
|
||||||
ShortPhoneNumber* parse_phone_number(const char* number_str, const char* country) {
|
|
||||||
PhoneNumber number;
|
PhoneNumber number;
|
||||||
ShortPhoneNumber* short_number;
|
PackedPhoneNumber* short_number;
|
||||||
|
|
||||||
short_number = (ShortPhoneNumber*)palloc0(sizeof(ShortPhoneNumber));
|
short_number = (PackedPhoneNumber*)palloc0(sizeof(PackedPhoneNumber));
|
||||||
if(short_number == nullptr) {
|
if(short_number == nullptr) {
|
||||||
throw std::bad_alloc();
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
|
@ -56,7 +54,7 @@ ShortPhoneNumber* parse_phone_number(const char* number_str, const char* country
|
||||||
error = phoneUtil->Parse(number_str, country, &number);
|
error = phoneUtil->Parse(number_str, country, &number);
|
||||||
if(error == PhoneNumberUtil::NO_PARSING_ERROR) {
|
if(error == PhoneNumberUtil::NO_PARSING_ERROR) {
|
||||||
//Initialize short_number using placement new.
|
//Initialize short_number using placement new.
|
||||||
new(short_number) ShortPhoneNumber(number);
|
new(short_number) PackedPhoneNumber(number);
|
||||||
return short_number;
|
return short_number;
|
||||||
} else {
|
} else {
|
||||||
reportParseError(number_str, error);
|
reportParseError(number_str, error);
|
||||||
|
@ -80,15 +78,15 @@ extern "C" {
|
||||||
* I/O functions
|
* I/O functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_in);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(packed_phone_number_in);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
phone_number_in(PG_FUNCTION_ARGS) {
|
packed_phone_number_in(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
const char *number_str = PG_GETARG_CSTRING(0);
|
const char *number_str = PG_GETARG_CSTRING(0);
|
||||||
|
|
||||||
//TODO: use international format instead.
|
//TODO: use international format instead.
|
||||||
ShortPhoneNumber* number = parse_phone_number(number_str, "US");
|
PackedPhoneNumber* number = do_parse_packed_phone_number(number_str, "US");
|
||||||
if(number) {
|
if(number) {
|
||||||
PG_RETURN_POINTER(number);
|
PG_RETURN_POINTER(number);
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,12 +98,12 @@ extern "C" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_out);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(packed_phone_number_out);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
phone_number_out(PG_FUNCTION_ARGS) {
|
packed_phone_number_out(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
const ShortPhoneNumber* short_number = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
const PackedPhoneNumber* short_number = (PackedPhoneNumber*)PG_GETARG_POINTER(0);
|
||||||
PhoneNumber number = *short_number;
|
PhoneNumber number = *short_number;
|
||||||
|
|
||||||
std::string formatted;
|
std::string formatted;
|
||||||
|
@ -129,17 +127,17 @@ extern "C" {
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_recv);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(packed_phone_number_recv);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
phone_number_recv(PG_FUNCTION_ARGS) {
|
packed_phone_number_recv(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
StringInfo buf = (StringInfo)PG_GETARG_POINTER(0);
|
StringInfo buf = (StringInfo)PG_GETARG_POINTER(0);
|
||||||
ShortPhoneNumber* number;
|
PackedPhoneNumber* number;
|
||||||
|
|
||||||
number = (ShortPhoneNumber*)palloc(sizeof(ShortPhoneNumber));
|
number = (PackedPhoneNumber*)palloc(sizeof(PackedPhoneNumber));
|
||||||
//TODO: make portable (fix endianness issues, etc.).
|
//TODO: make portable (fix endianness issues, etc.).
|
||||||
pq_copymsgbytes(buf, (char*)number, sizeof(ShortPhoneNumber));
|
pq_copymsgbytes(buf, (char*)number, sizeof(PackedPhoneNumber));
|
||||||
PG_RETURN_POINTER(number);
|
PG_RETURN_POINTER(number);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
reportException(e);
|
reportException(e);
|
||||||
|
@ -148,16 +146,16 @@ extern "C" {
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_send);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(packed_phone_number_send);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
phone_number_send(PG_FUNCTION_ARGS) {
|
packed_phone_number_send(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
const ShortPhoneNumber *number = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
const PackedPhoneNumber *number = (PackedPhoneNumber*)PG_GETARG_POINTER(0);
|
||||||
StringInfoData buf;
|
StringInfoData buf;
|
||||||
|
|
||||||
pq_begintypsend(&buf);
|
pq_begintypsend(&buf);
|
||||||
pq_sendbytes(&buf, (const char*)number, sizeof(ShortPhoneNumber));
|
pq_sendbytes(&buf, (const char*)number, sizeof(PackedPhoneNumber));
|
||||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
reportException(e);
|
reportException(e);
|
||||||
|
@ -170,13 +168,13 @@ extern "C" {
|
||||||
* Operator functions
|
* Operator functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_equal);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(packed_phone_number_equal);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
phone_number_equal(PG_FUNCTION_ARGS) {
|
packed_phone_number_equal(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
const PackedPhoneNumber* number1 = (PackedPhoneNumber*)PG_GETARG_POINTER(0);
|
||||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
const PackedPhoneNumber* number2 = (PackedPhoneNumber*)PG_GETARG_POINTER(1);
|
||||||
|
|
||||||
PG_RETURN_BOOL(*number1 == *number2);
|
PG_RETURN_BOOL(*number1 == *number2);
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
|
@ -186,13 +184,13 @@ extern "C" {
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_not_equal);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(packed_phone_number_not_equal);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
phone_number_not_equal(PG_FUNCTION_ARGS) {
|
packed_phone_number_not_equal(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
const PackedPhoneNumber* number1 = (PackedPhoneNumber*)PG_GETARG_POINTER(0);
|
||||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
const PackedPhoneNumber* number2 = (PackedPhoneNumber*)PG_GETARG_POINTER(1);
|
||||||
|
|
||||||
PG_RETURN_BOOL(*number1 != *number2);
|
PG_RETURN_BOOL(*number1 != *number2);
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
|
@ -202,13 +200,13 @@ extern "C" {
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_less);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(packed_phone_number_less);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
phone_number_less(PG_FUNCTION_ARGS) {
|
packed_phone_number_less(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
const PackedPhoneNumber* number1 = (PackedPhoneNumber*)PG_GETARG_POINTER(0);
|
||||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
const PackedPhoneNumber* number2 = (PackedPhoneNumber*)PG_GETARG_POINTER(1);
|
||||||
|
|
||||||
PG_RETURN_BOOL(number1->compare_fast(*number2) < 0);
|
PG_RETURN_BOOL(number1->compare_fast(*number2) < 0);
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
|
@ -218,13 +216,13 @@ extern "C" {
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_less_or_equal);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(packed_phone_number_less_or_equal);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
phone_number_less_or_equal(PG_FUNCTION_ARGS) {
|
packed_phone_number_less_or_equal(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
const PackedPhoneNumber* number1 = (PackedPhoneNumber*)PG_GETARG_POINTER(0);
|
||||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
const PackedPhoneNumber* number2 = (PackedPhoneNumber*)PG_GETARG_POINTER(1);
|
||||||
|
|
||||||
PG_RETURN_BOOL(number1->compare_fast(*number2) <= 0);
|
PG_RETURN_BOOL(number1->compare_fast(*number2) <= 0);
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
|
@ -234,13 +232,13 @@ extern "C" {
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_greater);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(packed_phone_number_greater);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
phone_number_greater(PG_FUNCTION_ARGS) {
|
packed_phone_number_greater(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
const PackedPhoneNumber* number1 = (PackedPhoneNumber*)PG_GETARG_POINTER(0);
|
||||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
const PackedPhoneNumber* number2 = (PackedPhoneNumber*)PG_GETARG_POINTER(1);
|
||||||
|
|
||||||
PG_RETURN_BOOL(number1->compare_fast(*number2) > 0);
|
PG_RETURN_BOOL(number1->compare_fast(*number2) > 0);
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
|
@ -250,13 +248,13 @@ extern "C" {
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_greater_or_equal);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(packed_phone_number_greater_or_equal);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
phone_number_greater_or_equal(PG_FUNCTION_ARGS) {
|
packed_phone_number_greater_or_equal(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
const PackedPhoneNumber* number1 = (PackedPhoneNumber*)PG_GETARG_POINTER(0);
|
||||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
const PackedPhoneNumber* number2 = (PackedPhoneNumber*)PG_GETARG_POINTER(1);
|
||||||
|
|
||||||
PG_RETURN_BOOL(number1->compare_fast(*number2) >= 0);
|
PG_RETURN_BOOL(number1->compare_fast(*number2) >= 0);
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
|
@ -266,13 +264,13 @@ extern "C" {
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_cmp);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(packed_phone_number_cmp);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
phone_number_cmp(PG_FUNCTION_ARGS) {
|
packed_phone_number_cmp(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
const ShortPhoneNumber* number1 = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
const PackedPhoneNumber* number1 = (PackedPhoneNumber*)PG_GETARG_POINTER(0);
|
||||||
const ShortPhoneNumber* number2 = (ShortPhoneNumber*)PG_GETARG_POINTER(1);
|
const PackedPhoneNumber* number2 = (PackedPhoneNumber*)PG_GETARG_POINTER(1);
|
||||||
|
|
||||||
int64_t compared = number1->compare_fast(*number2);
|
int64_t compared = number1->compare_fast(*number2);
|
||||||
|
|
||||||
|
@ -288,10 +286,10 @@ extern "C" {
|
||||||
* Other functions
|
* Other functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(parse_phone_number);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(parse_packed_phone_number);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
parse_phone_number(PG_FUNCTION_ARGS) {
|
parse_packed_phone_number(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
const text* number_text = PG_GETARG_TEXT_P(0);
|
const text* number_text = PG_GETARG_TEXT_P(0);
|
||||||
const text* country_text = PG_GETARG_TEXT_P(1);
|
const text* country_text = PG_GETARG_TEXT_P(1);
|
||||||
|
@ -299,7 +297,7 @@ extern "C" {
|
||||||
char* number_str = text_to_c_string(number_text);
|
char* number_str = text_to_c_string(number_text);
|
||||||
char* country = text_to_c_string(country_text);
|
char* country = text_to_c_string(country_text);
|
||||||
|
|
||||||
ShortPhoneNumber* number = parse_phone_number(number_str, country);
|
PackedPhoneNumber* number = do_parse_packed_phone_number(number_str, country);
|
||||||
//TODO: prevent leaks.
|
//TODO: prevent leaks.
|
||||||
pfree(number_str);
|
pfree(number_str);
|
||||||
pfree(country);
|
pfree(country);
|
||||||
|
@ -314,12 +312,12 @@ extern "C" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PGDLLEXPORT PG_FUNCTION_INFO_V1(phone_number_country_code);
|
PGDLLEXPORT PG_FUNCTION_INFO_V1(packed_phone_number_country_code);
|
||||||
|
|
||||||
PGDLLEXPORT Datum
|
PGDLLEXPORT Datum
|
||||||
phone_number_country_code(PG_FUNCTION_ARGS) {
|
packed_phone_number_country_code(PG_FUNCTION_ARGS) {
|
||||||
try {
|
try {
|
||||||
const ShortPhoneNumber* number = (ShortPhoneNumber*)PG_GETARG_POINTER(0);
|
const PackedPhoneNumber* number = (PackedPhoneNumber*)PG_GETARG_POINTER(0);
|
||||||
|
|
||||||
PG_RETURN_INT32(number->country_code());
|
PG_RETURN_INT32(number->country_code());
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
|
|
|
@ -14,7 +14,7 @@ std::string PhoneNumberTooLongException::number_string() const {
|
||||||
return formatted;
|
return formatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShortPhoneNumber::ShortPhoneNumber(i18n::phonenumbers::PhoneNumber number) {
|
PackedPhoneNumber::PackedPhoneNumber(i18n::phonenumbers::PhoneNumber number) {
|
||||||
uint32 country_code = number.country_code();
|
uint32 country_code = number.country_code();
|
||||||
if(country_code > max_country_code) {
|
if(country_code > max_country_code) {
|
||||||
throw PhoneNumberTooLongException(number, "Country code is too long");
|
throw PhoneNumberTooLongException(number, "Country code is too long");
|
||||||
|
@ -38,7 +38,7 @@ ShortPhoneNumber::ShortPhoneNumber(i18n::phonenumbers::PhoneNumber number) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShortPhoneNumber::operator PhoneNumber() const {
|
PackedPhoneNumber::operator PhoneNumber() const {
|
||||||
PhoneNumber number;
|
PhoneNumber number;
|
||||||
number.set_country_code(country_code());
|
number.set_country_code(country_code());
|
||||||
number.set_national_number(national_number());
|
number.set_national_number(national_number());
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
#include "mask.h"
|
#include "mask.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Raised when a phone number is too long to fit in a ShortPhoneNumber
|
* Raised when a phone number is too long to fit in a PackedPhoneNumber
|
||||||
*
|
*
|
||||||
* This shouldn't happen for any valid phone numbers.
|
* This shouldn't happen for any phone numbers that meet ITU specifications.
|
||||||
*/
|
*/
|
||||||
class PhoneNumberTooLongException : public std::runtime_error {
|
class PhoneNumberTooLongException : public std::runtime_error {
|
||||||
public:
|
public:
|
||||||
|
@ -33,7 +33,7 @@ class PhoneNumberTooLongException : public std::runtime_error {
|
||||||
/**
|
/**
|
||||||
* Stores a phone number (packed into a 64-bit integer)
|
* Stores a phone number (packed into a 64-bit integer)
|
||||||
*/
|
*/
|
||||||
class ShortPhoneNumber {
|
class PackedPhoneNumber {
|
||||||
public:
|
public:
|
||||||
/// The largest possible country code
|
/// The largest possible country code
|
||||||
static constexpr size_t max_country_code = 999;
|
static constexpr size_t max_country_code = 999;
|
||||||
|
@ -54,13 +54,13 @@ class ShortPhoneNumber {
|
||||||
static constexpr size_t leading_zeros_offset = country_code_offset + country_code_bits;
|
static constexpr size_t leading_zeros_offset = country_code_offset + country_code_bits;
|
||||||
static constexpr size_t national_number_offset = leading_zeros_offset + leading_zeros_bits;
|
static constexpr size_t national_number_offset = leading_zeros_offset + leading_zeros_bits;
|
||||||
|
|
||||||
ShortPhoneNumber(i18n::phonenumbers::PhoneNumber number);
|
PackedPhoneNumber(i18n::phonenumbers::PhoneNumber number);
|
||||||
|
|
||||||
bool operator==(const ShortPhoneNumber other) const {
|
bool operator==(const PackedPhoneNumber other) const {
|
||||||
return this->_data == other._data;
|
return this->_data == other._data;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator != (const ShortPhoneNumber other) const {
|
bool operator != (const PackedPhoneNumber other) const {
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class ShortPhoneNumber {
|
||||||
operator i18n::phonenumbers::PhoneNumber() const;
|
operator i18n::phonenumbers::PhoneNumber() const;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compares to another ShortPhoneNumber using a fast collation heuristic
|
* Compares to another PackedPhoneNumber using a fast collation heuristic
|
||||||
*
|
*
|
||||||
* May not produce intuitive results for numbers with the same
|
* May not produce intuitive results for numbers with the same
|
||||||
* country code but different lengths
|
* country code but different lengths
|
||||||
|
@ -78,7 +78,7 @@ class ShortPhoneNumber {
|
||||||
* - 0 (if a == b)
|
* - 0 (if a == b)
|
||||||
* - >0 (if a > b)
|
* - >0 (if a > b)
|
||||||
*/
|
*/
|
||||||
int64_t compare_fast(ShortPhoneNumber other) const {
|
int64_t compare_fast(PackedPhoneNumber other) const {
|
||||||
return other._data - this->_data;
|
return other._data - this->_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ class ShortPhoneNumber {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the size of the ShortPhoneNumber class changes for any reason, it will trip this assertion and remind us to
|
* If the size of the PackedPhoneNumber class changes for any reason, it will trip this assertion and remind us to
|
||||||
* update the SQL definition of the short_phone_number type.
|
* update the SQL definition of the short_phone_number type.
|
||||||
*/
|
*/
|
||||||
static_assert(sizeof(ShortPhoneNumber) == 8, "unexpected size for ShortPhoneNumber");
|
static_assert(sizeof(PackedPhoneNumber) == 8, "unexpected size for PackedPhoneNumber");
|
||||||
|
|
Loading…
Reference in New Issue