Rename phone_number to packed_phone_number

This commit is contained in:
Ben Merritt 2019-07-30 23:06:24 -07:00
parent 62ca2ab7f3
commit 4e04898fc1
No known key found for this signature in database
GPG Key ID: F8AD20ED4E6239B7
7 changed files with 138 additions and 146 deletions

View File

@ -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

View File

@ -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

View File

@ -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';

View File

@ -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'));

View File

@ -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) {

View File

@ -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());

View File

@ -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");