Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bde01dc

Browse files
authored
Add files via upload
1 parent 5196ffb commit bde01dc

File tree

2 files changed

+232
-0
lines changed

2 files changed

+232
-0
lines changed

‎functions/phone_serialize.sql‎

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
create or replace function phone_serialize(
2+
country_code text, --код страны в любом формате или NULL
3+
area_code text, --код зоны в любом формате или NULL
4+
local_number text, --локальный номер телефона в любом формате или NULL
5+
separator text default '(-.-)' -- набор символов в разделителе должен быть таким,
6+
-- чтобы корректно работали функции phone_normalize() и phone_parse()
7+
)
8+
returns text --not null
9+
stable
10+
--returns null on null input
11+
parallel safe
12+
language plpgsql
13+
cost 2
14+
as
15+
$$
16+
begin
17+
return concat_ws('', country_code, separator, area_code, separator, local_number);
18+
end
19+
$$;
20+
21+
comment on function phone_serialize(
22+
country_code text,
23+
area_code text,
24+
local_number text,
25+
separator text
26+
) is 'Сериализует номер телефона из трёх полей в одно по специальному разделителю';
27+
28+
------------------------------------------------------------------------------------------------------------------------
29+
30+
create or replace function phone_serialize(
31+
country_code int, --код страны в любом формате или NULL
32+
area_code text, --код зоны в любом формате или NULL
33+
local_number text, --локальный номер телефона в любом формате или NULL
34+
separator text default '(-.-)' -- набор символов в разделителе должен быть таким,
35+
-- чтобы корректно работали функции phone_normalize() и phone_parse()
36+
)
37+
returns text
38+
stable
39+
--returns null on null input
40+
parallel safe
41+
language sql
42+
as
43+
$$
44+
select phone_serialize(country_code::text, area_code, local_number);
45+
$$;
46+
47+
comment on function phone_serialize(
48+
country_code int,
49+
area_code text,
50+
local_number text,
51+
separator text
52+
) is 'Сериализует номер телефона из трёх полей в одно по специальному разделителю';
53+
54+
55+
------------------------------------------------------------------------------------------------------------------------
56+
--TEST
57+
do $$
58+
begin
59+
assert phone_serialize(7, '965', '1234567') = '7(-.-)965(-.-)1234567';
60+
assert phone_serialize('+7', '965', '1234567') = '+7(-.-)965(-.-)1234567';
61+
assert phone_serialize('', '', '') = '(-.-)(-.-)';
62+
assert phone_serialize(null::text, null, null) = '(-.-)(-.-)';
63+
assert phone_serialize(null::int, null, null) = '(-.-)(-.-)';
64+
65+
assert phone_serialize('7', '965', '1234567', '') = '79651234567';
66+
assert phone_serialize('7', '965', '1234567', null) = '79651234567';
67+
end;
68+
$$;
69+

‎functions/phone_unserialize.sql‎

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
create or replace function phone_unserialize(
2+
phone text, --номер телефона, сериализованный функцией phone_serialize()
3+
4+
country_code_example text, --nullable
5+
area_code_example text, --nullable
6+
local_number_example text, --nullable
7+
8+
separator text default '(-.-)', -- набор символов в разделителе должен быть таким же, как при сериализации
9+
10+
country_code out text, --nullable
11+
area_code out text, --nullable
12+
local_number out text --nullable
13+
)
14+
returns record
15+
stable
16+
--returns null on null input
17+
parallel safe
18+
language plpgsql
19+
cost 3
20+
as
21+
$$
22+
declare
23+
parts text[] not null default array[]::text[];
24+
begin
25+
26+
if phone is null then
27+
return;
28+
end if;
29+
30+
parts := string_to_array(phone, separator);
31+
32+
if array_length(parts, 1) != 3 then
33+
raise exception using
34+
message = 'Cannot split phone into 3 parts by separator!',
35+
detail = format('Phone = "%s", separator = "%s"', phone, separator),
36+
hint = 'Serialized phone was broken or another seperator used?';
37+
end if;
38+
39+
country_code := parts[1];
40+
area_code := parts[2];
41+
local_number := parts[3];
42+
43+
if nullif(country_code_example, '') is null then
44+
if country_code != '' then
45+
raise exception using
46+
message = 'Unconsistent unserialized "country_code" value',
47+
detail = format('Emtpy string expected, but "%s" given', country_code);
48+
end if;
49+
country_code = country_code_example;
50+
end if;
51+
52+
if nullif(area_code_example, '') is null then
53+
if area_code != '' then
54+
raise exception using
55+
message = 'Unconsistent unserialized "area_code" value',
56+
detail = format('Emtpy string expected, but "%s" given', area_code);
57+
end if;
58+
area_code = area_code_example;
59+
end if;
60+
61+
if nullif(local_number_example, '') is null then
62+
if local_number != '' then
63+
raise exception using
64+
message = 'Unconsistent unserialized "local_number" value',
65+
detail = format('Emtpy string expected, but "%s" given', local_number);
66+
end if;
67+
local_number = local_number_example;
68+
end if;
69+
70+
end
71+
$$;
72+
73+
comment on function phone_unserialize(
74+
phone text,
75+
76+
country_code_example text,
77+
area_code_example text,
78+
local_number_example text,
79+
80+
separator text,
81+
82+
country_code out text,
83+
area_code out text,
84+
local_number out text
85+
) is 'Десериализует номер телефона из одного поля в три по специальному разделителю';
86+
87+
------------------------------------------------------------------------------------------------------------------------
88+
89+
create or replace function phone_unserialize(
90+
phone text, --номер телефона, сериализованный функцией phone_serialize()
91+
92+
country_code_example int, --nullable
93+
area_code_example text, --nullable
94+
local_number_example text, --nullable
95+
96+
separator text default '(-.-)', -- набор символов в разделителе должен быть таким же, как при сериализации
97+
98+
country_code out int, --nullable
99+
area_code out text, --nullable
100+
local_number out text --nullable
101+
)
102+
returns record
103+
stable
104+
--returns null on null input
105+
parallel safe
106+
language sql
107+
as
108+
$$
109+
select u.country_code::int, u.area_code, u.local_number
110+
from phone_unserialize(phone,
111+
country_code_example::text, area_code_example, local_number_example,
112+
separator) as u;
113+
$$;
114+
115+
comment on function phone_unserialize(
116+
phone text,
117+
118+
country_code_example int,
119+
area_code_example text,
120+
local_number_example text,
121+
122+
separator text,
123+
124+
country_code out int,
125+
area_code out text,
126+
local_number out text
127+
) is 'Десериализует номер телефона из одного поля в три по специальному разделителю';
128+
129+
------------------------------------------------------------------------------------------------------------------------
130+
--TEST
131+
do $$
132+
begin
133+
134+
assert not exists(
135+
with t (country_code, area_code, local_number) as (
136+
values ('+7', '965', '123-45-67'),
137+
('+79651234567', null, null),
138+
(null::text, '+79651234567', null),
139+
(null::text, null, '+79651234567'),
140+
('', '', ''),
141+
(null::text, null, null)
142+
)
143+
select t.*, s.*, u.*
144+
from t
145+
cross join phone_serialize(t.country_code, t.area_code, t.local_number) as s(phone)
146+
cross join phone_unserialize(s.phone, t.country_code, t.area_code, t.local_number) as u
147+
where t is distinct from u
148+
);
149+
150+
assert not exists(
151+
with t (country_code, area_code, local_number) as (
152+
values (7, '965', '123-45-67'),
153+
(null::int, null, null)
154+
)
155+
select t.*, s.*, u.*
156+
from t
157+
cross join phone_serialize(t.country_code, t.area_code, t.local_number) as s(phone)
158+
cross join phone_unserialize(s.phone, t.country_code, t.area_code, t.local_number) as u
159+
where t is distinct from u
160+
);
161+
162+
end;
163+
$$;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /