Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3fa676a

Browse files
committed
From: Garrett Wollman <wollman@khavrinen.lcs.mit.edu> Here is some more contrib-fodder, based on TIH's IP address type, for ISBN and ISSN identifiers (which I just happened to need to keep track of the things in my library).
1 parent efc9a91 commit 3fa676a

File tree

7 files changed

+646
-0
lines changed

7 files changed

+646
-0
lines changed

contrib/README

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ ip_and_mac -
3535
PostgreSQL type extensions for IP and MAC addresses
3636
by Tom Ivar Helbekkmo <tih@Hamartun.Priv.NO>
3737

38+
isbn_issn -
39+
PostgreSQL type extensions for ISBN (books) and ISSN (serials)
40+
by Garrett A. Wollman <wollman@khavrinen.lcs.mit.edu>
41+
3842
linux -
3943
Start postgres back end system
4044
by Thomas Lockhart <lockhart@alumni.caltech.edu>
@@ -80,3 +84,5 @@ userlock -
8084
User locks
8185
by Massimo Dal Zotto <dz@cs.unitn.it>
8286

87+
88+

contrib/isbn_issn/Makefile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#
2+
# PostgreSQL types for ISBN and ISSN identifiers.
3+
#
4+
# $Id: Makefile,v 1.1 1998/08/17 03:35:04 scrappy Exp $
5+
6+
all: isbn.so issn.so
7+
8+
isbn.so: isbn.o
9+
ld -Bshareable -o isbn.so isbn.o
10+
11+
isbn.o: isbn.c
12+
cc -g -O -fPIC -I/usr/local/pgsql/include -c isbn.c
13+
14+
issn.so: issn.o
15+
ld -Bshareable -o issn.so issn.o
16+
17+
issn.o: issn.c
18+
cc -g -O -fPIC -I/usr/local/pgsql/include -c issn.c
19+
20+
install: isbn.so issn.so
21+
install -c isbn.so issn.so /usr/local/pgsql/modules
22+
23+
#
24+
# eof
25+
#

contrib/isbn_issn/README

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
This directory contains definitions for a couple of PostgreSQL
2+
external types, for a couple of international-standard namespaces:
3+
ISBN (books) and ISSN (serials). Rather than just using a char()
4+
member of the appropriate length, I wanted my database to include
5+
the validity-checking that both these numbering systems were designed
6+
to encompass. A little bit of research revealed the formulae
7+
for computing the check digits, and I also included some validity
8+
constraints on the number of hyphens.
9+
10+
The internal representation of these types is intended to be
11+
compatible with `char16', in the (perhaps vain) hope that
12+
this will make it possible to create indices of these types
13+
using char16_ops.
14+
15+
These are based on Tom Ivar Helbekkmo's IP address type definition,
16+
from which I have copied the entire form of the implementation.
17+
18+
Garrett A. Wollman, August 1998

contrib/isbn_issn/isbn.c

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
/*
2+
* PostgreSQL type definitions for ISBNs.
3+
*
4+
* $Id: isbn.c,v 1.1 1998/08/17 03:35:04 scrappy Exp $
5+
*/
6+
7+
#include <stdio.h>
8+
9+
#include <postgres.h>
10+
#include <utils/palloc.h>
11+
12+
/*
13+
* This is the internal storage format for ISBNs.
14+
* NB: This is an intentional type pun with builtin type `char16'.
15+
*/
16+
17+
typedef struct isbn
18+
{
19+
char num[13];
20+
char pad[3];
21+
} isbn;
22+
23+
/*
24+
* Various forward declarations:
25+
*/
26+
27+
isbn *isbn_in(char *str);
28+
char *isbn_out(isbn * addr);
29+
30+
bool isbn_lt(isbn * a1, isbn * a2);
31+
bool isbn_le(isbn * a1, isbn * a2);
32+
bool isbn_eq(isbn * a1, isbn * a2);
33+
bool isbn_ge(isbn * a1, isbn * a2);
34+
bool isbn_gt(isbn * a1, isbn * a2);
35+
36+
bool isbn_ne(isbn * a1, isbn * a2);
37+
38+
int4 isbn_cmp(isbn * a1, isbn * a2);
39+
40+
int4 isbn_sum(char *str);
41+
42+
/*
43+
* ISBN reader.
44+
*/
45+
46+
isbn *
47+
isbn_in(char *str)
48+
{
49+
isbn *result;
50+
char *cp;
51+
int count;
52+
53+
if (strlen(str) != 13) {
54+
elog(ERROR, "isbn_in: invalid ISBN \"%s\"", str);
55+
return (NULL);
56+
}
57+
if (isbn_sum(str) != 0) {
58+
elog(ERROR, "isbn_in: purported ISBN \"%s\" failed checksum",
59+
str);
60+
return (NULL);
61+
}
62+
63+
result = (isbn *) palloc(sizeof(isbn));
64+
65+
strncpy(result->num, str, 13);
66+
memset(result->pad, ' ', 3);
67+
return (result);
68+
}
69+
70+
/*
71+
* The ISBN checksum is defined as follows:
72+
*
73+
* Number the digits from 1 to 9 (call this N).
74+
* Compute the sum, S, of N * D_N.
75+
* The check digit, C, is the value which satisfies the equation
76+
* S + 10*C === 0 (mod 11)
77+
* The value 10 for C is written as `X'.
78+
*
79+
* For our purposes, we want the complete sum including the check
80+
* digit; if this is zero, then the checksum passed. We also check
81+
* the syntactic validity if the provided string, and return 12
82+
* if any errors are found.
83+
*/
84+
int4
85+
isbn_sum(char *str)
86+
{
87+
int4 sum = 0, dashes = 0, val;
88+
int i;
89+
90+
for (i = 0; str[i] && i < 13; i++) {
91+
switch(str[i]) {
92+
case '-':
93+
if (++dashes > 3)
94+
return 12;
95+
continue;
96+
97+
case '0': case '1': case '2': case '3':
98+
case '4': case '5': case '6': case '7':
99+
case '8': case '9':
100+
val = str[i] - '0';
101+
break;
102+
103+
case 'X': case 'x':
104+
val = 10;
105+
break;
106+
107+
default:
108+
return 12;
109+
}
110+
111+
sum += val * (i + 1 - dashes);
112+
}
113+
return (sum % 11);
114+
}
115+
116+
/*
117+
* ISBN output function.
118+
*/
119+
120+
char *
121+
isbn_out(isbn * num)
122+
{
123+
char *result;
124+
125+
if (num == NULL)
126+
return (NULL);
127+
128+
result = (char *) palloc(14);
129+
130+
result[0] = '\0';
131+
strncat(result, num->num, 13);
132+
return (result);
133+
}
134+
135+
/*
136+
* Boolean tests for magnitude.
137+
*/
138+
139+
bool
140+
isbn_lt(isbn * a1, isbn * a2)
141+
{
142+
return (strncmp(a1->num, a2->num, 13) < 0);
143+
};
144+
145+
bool
146+
isbn_le(isbn * a1, isbn * a2)
147+
{
148+
return (strncmp(a1->num, a2->num, 13) <= 0);
149+
};
150+
151+
bool
152+
isbn_eq(isbn * a1, isbn * a2)
153+
{
154+
return (strncmp(a1->num, a2->num, 13) == 0);
155+
};
156+
157+
bool
158+
isbn_ge(isbn * a1, isbn * a2)
159+
{
160+
return (strncmp(a1->num, a2->num, 13) >= 0);
161+
};
162+
163+
bool
164+
isbn_gt(isbn * a1, isbn * a2)
165+
{
166+
return (strncmp(a1->num, a2->num, 13) > 0);
167+
};
168+
169+
bool
170+
isbn_ne(isbn * a1, isbn * a2)
171+
{
172+
return (strncmp(a1->num, a2->num, 13) != 0);
173+
};
174+
175+
/*
176+
* Comparison function for sorting:
177+
*/
178+
179+
int4
180+
isbn_cmp(isbn * a1, isbn * a2)
181+
{
182+
return (strncmp(a1->num, a2->num, 13));
183+
}
184+
185+
/*
186+
* eof
187+
*/

contrib/isbn_issn/isbn.sql

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
--
2+
-- PostgreSQL code for ISBNs.
3+
--
4+
-- $Id: isbn.sql,v 1.1 1998/08/17 03:35:05 scrappy Exp $
5+
--
6+
7+
load '/usr/local/pgsql/modules/isbn.so';
8+
9+
--
10+
-- Input and output functions and the type itself:
11+
--
12+
13+
create function isbn_in(opaque)
14+
returns opaque
15+
as '/usr/local/pgsql/modules/isbn.so'
16+
language 'c';
17+
18+
create function isbn_out(opaque)
19+
returns opaque
20+
as '/usr/local/pgsql/modules/isbn.so'
21+
language 'c';
22+
23+
create type isbn (
24+
internallength = 16,
25+
externallength = 13,
26+
input = isbn_in,
27+
output = isbn_out
28+
);
29+
30+
--
31+
-- The various boolean tests:
32+
--
33+
34+
create function isbn_lt(isbn, isbn)
35+
returns bool
36+
as '/usr/local/pgsql/modules/isbn.so'
37+
language 'c';
38+
39+
create function isbn_le(isbn, isbn)
40+
returns bool
41+
as '/usr/local/pgsql/modules/isbn.so'
42+
language 'c';
43+
44+
create function isbn_eq(isbn, isbn)
45+
returns bool
46+
as '/usr/local/pgsql/modules/isbn.so'
47+
language 'c';
48+
49+
create function isbn_ge(isbn, isbn)
50+
returns bool
51+
as '/usr/local/pgsql/modules/isbn.so'
52+
language 'c';
53+
54+
create function isbn_gt(isbn, isbn)
55+
returns bool
56+
as '/usr/local/pgsql/modules/isbn.so'
57+
language 'c';
58+
59+
create function isbn_ne(isbn, isbn)
60+
returns bool
61+
as '/usr/local/pgsql/modules/isbn.so'
62+
language 'c';
63+
64+
--
65+
-- Now the operators. Note how some of the parameters to some
66+
-- of the 'create operator' commands are commented out. This
67+
-- is because they reference as yet undefined operators, and
68+
-- will be implicitly defined when those are, further down.
69+
--
70+
71+
create operator < (
72+
leftarg = isbn,
73+
rightarg = isbn,
74+
-- negator = >=,
75+
procedure = isbn_lt
76+
);
77+
78+
create operator <= (
79+
leftarg = isbn,
80+
rightarg = isbn,
81+
-- negator = >,
82+
procedure = isbn_le
83+
);
84+
85+
create operator = (
86+
leftarg = isbn,
87+
rightarg = isbn,
88+
commutator = =,
89+
-- negator = <>,
90+
procedure = isbn_eq
91+
);
92+
93+
create operator >= (
94+
leftarg = isbn,
95+
rightarg = isbn,
96+
negator = <,
97+
procedure = isbn_ge
98+
);
99+
100+
create operator > (
101+
leftarg = isbn,
102+
rightarg = isbn,
103+
negator = <=,
104+
procedure = isbn_gt
105+
);
106+
107+
create operator <> (
108+
leftarg = isbn,
109+
rightarg = isbn,
110+
negator = =,
111+
procedure = isbn_ne
112+
);
113+
114+
--
115+
-- eof
116+
--

0 commit comments

Comments
 (0)