2025-05-05 13:52:40 +00:00
: : r e q u i r e s 'ooSQLite.cls'
: : r e q u i r e s "rxunixsys" LIBRARY
: : r e q u i r e s 'ncurses.cls'
: : r e q u i r e s 'app/utils.rex'
: : CLASS A d d r e s s B o o k D B PUBLIC
: : method init
e x p o s e d b
/* C r e a t e d a t a b a s e d i r e c t o r y i f i t d o e s n ' t e x i s t */
2025-05-05 16:40:49 +00:00
if S y s F i l e E x i s t s ( . d b F i l e ) = = . false then DO
2025-05-05 13:52:40 +00:00
S A Y "Initializing new address book"
2025-05-05 16:40:49 +00:00
d b = . o o S Q L i t e C o n n e c t i o n ~ new ( . d b F i l e )
2025-05-05 13:52:40 +00:00
self ~ c r e a t e T a b l e s
END
Else Do
S a y "Initializing existing address book"
2025-05-05 16:40:49 +00:00
d b = . o o S Q L i t e C o n n e c t i o n ~ new ( . d b F i l e , . o o S Q L i t e ~ O P E N _ R E A D W R I T E )
2025-05-05 13:52:40 +00:00
End
return
: : METHOD g e t F i l e N a m e
e x p o s e d b
return d b ~ fileName ( )
: : METHOD c l o s e D b
e x p o s e d b
d b ~ Close ( )
RETURN
: : METHOD c r e a t e T a b l e s
e x p o s e d b
/* C o n t a c t s t a b l e */
d b ~ e x e c ( "CREATE TABLE IF NOT EXISTS contacts (" | | ,
"id INTEGER PRIMARY KEY AUTOINCREMENT," | | ,
"first_name TEXT," | | ,
"last_name TEXT," | | ,
"created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP," | | ,
"updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP" | | ,
")" )
/* P h o n e n u m b e r s t a b l e */
d b ~ e x e c ( "CREATE TABLE IF NOT EXISTS phone_numbers (" | | ,
"id INTEGER PRIMARY KEY AUTOINCREMENT," | | ,
"contact_id INTEGER," | | ,
"type TEXT," | | , - - h o m e , w o r k , m o b i l e , e t c .
"number TEXT," | | ,
"FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE CASCADE" | | ,
")" )
/* E m a i l a d d r e s s e s t a b l e */
d b ~ e x e c ( "CREATE TABLE IF NOT EXISTS email_addresses (" | | ,
"id INTEGER PRIMARY KEY AUTOINCREMENT," | | ,
"contact_id INTEGER," | | ,
"type TEXT," | | , - - h o m e , w o r k , e t c .
"email TEXT," | | ,
"FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE CASCADE" | | ,
")" )
/* P h y s i c a l a d d r e s s e s t a b l e */
d b ~ e x e c ( "CREATE TABLE IF NOT EXISTS addresses (" | | ,
"id INTEGER PRIMARY KEY AUTOINCREMENT," | | ,
"contact_id INTEGER," | | ,
"type TEXT," | | , - - h o m e , w o r k , e t c .
"street TEXT," | | ,
"city TEXT," | | ,
"state TEXT," | | ,
"postal_code TEXT," | | ,
"country TEXT," | | ,
"FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE CASCADE" | | ,
")" )
return
/* C o n t a c t C R U D O p e r a t i o n s */
: : METHOD a d d C o n t a c t
e x p o s e d b
use a r g c o n t a c t D i c t /* U s e a R e x x ' d i r e c t o r y ' t o p a s s m u l t i p l e v a l u e s a r o u n d */
2025-05-05 16:09:30 +00:00
sql = "INSERT INTO contacts (first_name, last_name) VALUES ('" c o n t a c t D i c t ~ F i r s t _ N a m e "', '" c o n t a c t D i c t ~ L a s t _ N a m e "')"
2025-05-05 13:52:40 +00:00
r c = d b ~ e x e c ( sql )
if r c \ = 0 then do
s a y "Error adding contact:" d b ~ e r r M s g ( )
return - 1
end
c o n t a c t I d = d b ~ l a s t I n s e r t R o w I d ( ) /* t h e r o w i d o f ' c o n t a c t s ' t a b l e i s t h e m a s t e r i d */
2025-05-07 20:25:20 +00:00
2025-05-05 13:52:40 +00:00
self ~ a d d P h o n e N u m b e r ( c o n t a c t I d , c o n t a c t D i c t [ "PHONE_TYPE" ] , c o n t a c t D i c t [ "PHONE_NUMBER" ] )
self ~ a d d E m a i l A d d r e s s ( c o n t a c t I d , c o n t a c t D i c t [ "EMAIL_TYPE" ] , c o n t a c t D i c t [ "EMAIL_ADDRESS" ] )
2025-05-08 21:12:16 +00:00
/* c o n t a c t I d , a d d r e s s T y p e , s t r e e t , c i t y , s t a t e , p o s t a l C o d e , c o u n t r y */
2025-05-10 12:27:13 +00:00
self ~ a d d R e a l A d d r e s s ( c o n t a c t I d , "NA" , c o n t a c t D i c t ~ s t r e e t , c o n t a c t D i c t ~ c i t y , c o n t a c t D i c t ~ s t a t e , c o n t a c t D i c t ~ p o s t C o d e , c o n t a c t D i c t ~ c o u n t r y )
2025-05-05 13:52:40 +00:00
return c o n t a c t I d
: : METHOD g e t C o n t a c t
e x p o s e d b
use a r g c o n t a c t I d
r e t u r n e d C o n t e n t = . D i r e c t o r y ~ new ( )
s q l 1 = "SELECT * FROM contacts WHERE id = " c o n t a c t I d
c o n t a c t s = d b ~ e x e c ( s q l 1 , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
/* T h e r e s u l t w i l l b e r e n d e r e d a s a n a r r a y o f R e x x ' d i r e c t o r i e s '
* w h i c h a r e b a s i c a l l y a n a l o g o u s to p y t h o n d i c t i o n a r i e s . * /
if c o n t a c t s = . n i l then DO
S a y 'NO CONTACTS FOUND'
return
END
if c o n t a c t s ~ size < 1 then do
S a y 'NO CONTACT FOUND'
return
END
2025-05-09 23:04:03 +00:00
2025-05-05 13:52:40 +00:00
return c o n t a c t s [ 1 ] /* R e x x i s 1 - i n d e x e d */
2025-05-07 20:25:20 +00:00
/* * * * * * * * * * * * * * * * * * * * * * * * * * *
* GET ALL C O N T A C T INFO *
* * * * * * * * * * * * * * * * * * * * * * * * * * * /
2025-05-05 13:52:40 +00:00
: : METHOD g e t A l l C o n t a c t s
e x p o s e d b
sql = "SELECT * FROM contacts ORDER BY last_name, first_name"
c o n t a c t s = d b ~ e x e c ( sql , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
2025-05-07 20:25:20 +00:00
do c o n t a c t o v e r c o n t a c t s
/* G e t P h o n e N u m b e r s */
p s q l = "SELECT * FROM phone_numbers WHERE contact_id = " c o n t a c t [ "ID" ]
p h o n e s = d b ~ e x e c ( p s q l , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
p h o n e = p h o n e s [ 1 ] /* j u s t g r a b t h e f i r s t p h o n e */
c o n t a c t [ "PHONE_NUMBER" ] = p h o n e [ "NUMBER" ]
c o n t a c t [ "PHONE_TYPE" ] = p h o n e [ "TYPE" ]
/* N o w g e t e m a i l a d d r e s s e s */
e s q l = "SELECT * FROM email_addresses WHERE contact_id = " c o n t a c t [ "ID" ]
e m a i l s = d b ~ e x e c ( e s q l , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
e m a i l = e m a i l s [ 1 ]
c o n t a c t [ "EMAIL_ADDRESS" ] = e m a i l [ "EMAIL" ]
c o n t a c t [ "EMAIL_TYPE" ] = e m a i l [ "TYPE" ]
END
2025-05-05 13:52:40 +00:00
return c o n t a c t s
2025-05-09 23:04:03 +00:00
/* * * * * * * * * * * * * * * * * * * * * * *
* Get C o n t a c t D e t a i l s *
* * * * * * * * * * * * * * * * * * * * * * * /
: : METHOD g e t C o n t a c t D e t a i l s
e x p o s e d b
use a r g c o n t a c t I D
c o n t a c t = self ~ g e t C o n t a c t ( c o n t a c t I d )
if c o n t a c t \ = . n i l then do
/* G e t P h o n e N u m b e r s */
p s q l = "SELECT * FROM phone_numbers WHERE contact_id = " c o n t a c t [ "ID" ]
p h o n e s = d b ~ e x e c ( p s q l , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
p h o n e = p h o n e s [ 1 ] /* j u s t g r a b t h e f i r s t p h o n e */
c o n t a c t [ "PHONE_NUMBER" ] = p h o n e [ "NUMBER" ]
c o n t a c t [ "PHONE_TYPE" ] = p h o n e [ "TYPE" ]
/* N o w g e t e m a i l a d d r e s s e s */
e s q l = "SELECT * FROM email_addresses WHERE contact_id = " c o n t a c t [ "ID" ]
e m a i l s = d b ~ e x e c ( e s q l , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
e m a i l = e m a i l s [ 1 ]
c o n t a c t [ "EMAIL_ADDRESS" ] = e m a i l [ "EMAIL" ]
c o n t a c t [ "EMAIL_TYPE" ] = e m a i l [ "TYPE" ]
/* N o w g e t r e a l p h y s i c a l a d d r e s s */
a s q l = "SELECT * FROM addresses WHERE contact_id = " c o n t a c t [ "ID" ]
a d d r e s s e s = d b ~ e x e c ( a s q l , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
a d d r e s s = a d d r e s s e s [ 1 ]
c o n t a c t [ "STREET" ] = a d d r e s s [ "STREET" ]
c o n t a c t [ "CITY" ] = a d d r e s s [ "CITY" ]
c o n t a c t [ "STATE" ] = a d d r e s s [ "STATE" ]
c o n t a c t [ "POSTAL_CODE" ] = a d d r e s s [ "POSTAL_CODE" ]
c o n t a c t [ "COUNTRY" ] = a d d r e s s [ "COUNTRY" ]
e n d /* a d d c o n t a c t d e t a i l s */
RETURN c o n t a c t
/* * * * * * * * * * * * * * * * * * * * * * *
* Search All C o n t a c t s *
* * * * * * * * * * * * * * * * * * * * * * * /
2025-05-05 13:52:40 +00:00
: : METHOD s e a r c h C o n t a c t s
e x p o s e d b
use a r g s e a r c h T e r m
c o n t a c t s L i s t = . A r r a y ~ new ( )
sql = "SELECT id FROM contacts WHERE first_name LIKE '%" s e a r c h T e r m "%' OR last_name LIKE '%" s e a r c h T e r m "%' ORDER BY last_name, first_name"
c o n t a c t I d s = d b ~ e x e c ( sql , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
do c o n t a c t D i r o v e r c o n t a c t I d s
c o n t a c t I d = c o n t a c t D i r [ "ID" ]
c o n t a c t = self ~ g e t C o n t a c t ( c o n t a c t I d )
if c o n t a c t \ = . n i l then do
2025-05-08 21:12:16 +00:00
/* G e t P h o n e N u m b e r s */
p s q l = "SELECT * FROM phone_numbers WHERE contact_id = " c o n t a c t [ "ID" ]
p h o n e s = d b ~ e x e c ( p s q l , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
p h o n e = p h o n e s [ 1 ] /* j u s t g r a b t h e f i r s t p h o n e */
c o n t a c t [ "PHONE_NUMBER" ] = p h o n e [ "NUMBER" ]
c o n t a c t [ "PHONE_TYPE" ] = p h o n e [ "TYPE" ]
/* N o w g e t e m a i l a d d r e s s e s */
e s q l = "SELECT * FROM email_addresses WHERE contact_id = " c o n t a c t [ "ID" ]
e m a i l s = d b ~ e x e c ( e s q l , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
e m a i l = e m a i l s [ 1 ]
c o n t a c t [ "EMAIL_ADDRESS" ] = e m a i l [ "EMAIL" ]
c o n t a c t [ "EMAIL_TYPE" ] = e m a i l [ "TYPE" ]
c o n t a c t s L i s t ~ append ( c o n t a c t )
end /* a d d c o n t a c t d e t a i l s */
2025-05-05 13:52:40 +00:00
end
return c o n t a c t s L i s t
2025-05-08 21:12:16 +00:00
/* * * * * * * * * * * * * * * * * * * * * * *
* UPDATE C O N T A C T *
* * * * * * * * * * * * * * * * * * * * * * * /
2025-05-05 13:52:40 +00:00
: : METHOD u p d a t e C o n t a c t
e x p o s e d b
2025-05-10 12:27:13 +00:00
use a r g c o n t a c t I d , c o n t a c t D i c t
r c = 0
s q l 1 = "UPDATE contacts SET first_name = '" c o n t a c t D i c t ~ f i r s t _ N a m e "', last_name = '" c o n t a c t D i c t ~ l a s t _ N a m e "' WHERE id = " c o n t a c t I d
r c = d b ~ e x e c ( s q l 1 )
s q l 2 = "UPDATE phone_numbers SET number = '" c o n t a c t D i c t ~ p h o n e _ n u m b e r "', type = '" c o n t a c t D i c t ~ p h o n e _ t y p e "' WHERE contact_id = " c o n t a c t I d
r c = d b ~ e x e c ( s q l 2 )
s q l 3 = "UPDATE email_addresses SET email = '" c o n t a c t D i c t ~ e m a i l _ a d d r e s s "', type = '" c o n t a c t D i c t ~ e m a i l _ t y p e "' WHERE contact_id = " c o n t a c t I d
r c = d b ~ e x e c ( s q l 3 )
s q l 4 = "UPDATE addresses SET street = '" c o n t a c t D i c t ~ s t r e e t "', city = '" c o n t a c t D i c t ~ c i t y "', state = '" c o n t a c t D i c t ~ s t a t e "', postal_code = '" c o n t a c t D i c t ~ p o s t c o d e "', country = '" c o n t a c t D i c t ~ c o u n t r y "' WHERE contact_id = " c o n t a c t I d
r c = d b ~ e x e c ( s q l 4 )
2025-05-08 21:12:16 +00:00
return r c
2025-05-05 13:52:40 +00:00
2025-05-07 20:25:20 +00:00
/* * * * * * * * * * * * * * * * * * * * * * * * * *
* DELETE C O N T A C T *
* * * * * * * * * * * * * * * * * * * * * * * * * /
2025-05-05 13:52:40 +00:00
: : METHOD d e l e t e C o n t a c t
e x p o s e d b
use a r g c o n t a c t I d
/* D e l e t e a l l r e l a t e d r e c o r d s f i r s t ( a s s u m i n g f o r e i g n k e y c o n s t r a i n t s ) */
self ~ r e m o v e C o n t a c t P h o n e s ( c o n t a c t I d )
self ~ r e m o v e C o n t a c t E m a i l s ( c o n t a c t I d )
self ~ r e m o v e C o n t a c t A d d r e s s e s ( c o n t a c t I d )
/* D e l e t e t h e c o n t a c t r e c o r d */
sql = "DELETE FROM contacts WHERE id = " c o n t a c t I d
r c = d b ~ e x e c ( sql )
if r c \ = 0 then do
s a y "Error deleting contact:" d b ~ e r r M s g ( )
return - 1
end
return 0
: : METHOD g e t P h o n e N u m b e r s
e x p o s e d b
use a r g c o n t a c t I d
p h o n e s = . A r r a y ~ new
sql = "SELECT id, type, number FROM phone_numbers WHERE contact_id = " c o n t a c t I d
p h o n e s = d b ~ e x e c ( sql , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
return p h o n e s
: : METHOD a d d P h o n e N u m b e r
e x p o s e d b
use a r g c o n t a c t I d , p h o n e T y p e , p h o n e N u m b e r
if p h o n e T y p e = . n i l | p h o n e N u m b e r = . n i l then return 0
sql = "INSERT INTO phone_numbers (contact_id, type, number) VALUES (" c o n t a c t I d ", '" p h o n e T y p e "', '" p h o n e N u m b e r "')"
r c = d b ~ e x e c ( sql )
if r c \ = 0 then DO
S a y "Unable to insert phone number for contact id " c o n t a c t I d
return r c
END
p h o n e _ i d = d b ~ l a s t I n s e r t R o w I d ( )
return p h o n e _ i d
: : METHOD u p d a t e P h o n e N u m b e r
e x p o s e d b
use a r g p h o n e I d , p h o n e T y p e , p h o n e N u m b e r
sql = "UPDATE phone_numbers SET type = '" p h o n e T y p e "', number = '" p h o n e N u m b e r "' WHERE id = " p h o n e I d
r c = d b ~ e x e c ( sql )
if r c \ = 0 then DO
S a y "Unable to update phone number or type for phone id " c o n t a c t I d
return r c
END
return r c
: : METHOD d e l e t e P h o n e N u m b e r
2025-05-05 16:09:30 +00:00
e x p o s e d b
use a r g p h o n e I d
sql = "DELETE FROM phone_numbers WHERE id = " p h o n e I d
r c = d b ~ e x e c ( sql )
if r c \ = 0 then DO
S a y "Unable to delete phone id " p h o n e I d
return r c
END
return r c
2025-05-05 13:52:40 +00:00
/* E m a i l a d d r e s s o p e r a t i o n s */
: : METHOD a d d E m a i l A d d r e s s
e x p o s e d b
use a r g c o n t a c t I d , e m a i l T y p e , e m a i l A d d r e s s
if e m a i l T y p e = . n i l | e m a i l A d d r e s s = . n i l then return 0
sql = "INSERT INTO email_addresses (contact_id, type, email) VALUES (" c o n t a c t I d ", '" e m a i l T y p e "', '" e m a i l A d d r e s s "')"
r c = d b ~ e x e c ( sql )
if r c \ = 0 then do
s a y "Error adding email address:" d b ~ e r r M s g ( )
return - 1
end
e m a i l _ i d = d b ~ l a s t I n s e r t R o w I d ( )
return e m a i l _ i d
: : METHOD g e t E m a i l A d d r e s s e s
e x p o s e d b
use a r g c o n t a c t I d
sql = "SELECT id, type, email FROM email_addresses WHERE contact_id = " c o n t a c t I d
e m a i l s = d b ~ e x e c ( sql , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
return e m a i l s
: : METHOD u p d a t e E m a i l A d d r e s s
e x p o s e d b
use a r g e m a i l I d , e m a i l T y p e , e m a i l A d d r e s s
sql = "UPDATE email_addresses SET type = '" e m a i l T y p e "', email = '" e m a i l a d d r e s s "' WHERE id = " e m a i l I d
r c = d b ~ e x e c ( sql )
if r c \ = 0 then do
s a y "Error adding email address:" d b ~ e r r M s g ( )
return - 1
end
return r c
: : METHOD d e l e t e E m a i l A d d r e s s
2025-05-05 16:09:30 +00:00
e x p o s e d b
use a r g e m a i l I d
2025-05-05 13:52:40 +00:00
2025-05-05 16:09:30 +00:00
sql = "DELETE FROM email_addresses WHERE id = " e m a i l I d
r c = d b ~ e x e c ( sql )
if r c \ = 0 then do
s a y "Error deleting email address:" d b ~ e r r M s g ( )
return - 1
end
return r c
2025-05-05 13:52:40 +00:00
/* P h y s i c a l a d d r e s s o p e r a t i o n s */
: : METHOD a d d R e a l A d d r e s s
e x p o s e d b
use a r g c o n t a c t I d , a d d r e s s T y p e , s t r e e t , c i t y , s t a t e , p o s t a l C o d e , c o u n t r y
if a d d r e s s T y p e = . n i l | s t r e e t = . n i l then return 0
sql = "INSERT INTO addresses (contact_id, type, street, city, state, postal_code, country)" ,
"VALUES (" c o n t a c t I d ", '" a d d r e s s T y p e "', '" s t r e e t "', '" c i t y "', '" s t a t e "', '" p o s t a l C o d e "', '" c o u n t r y "')"
r c = d b ~ e x e c ( sql )
if r c \ = 0 then do
s a y "Error adding address:" d b ~ e r r M s g ( )
return - 1
end
a d d r _ i d = d b ~ l a s t I n s e r t R o w I d ( )
return a d d r _ i d
: : METHOD g e t R e a l A d d r e s s e s
e x p o s e d b
use a r g c o n t a c t I d
sql = "SELECT id, type, street, city, state, postal_code, country" | | ,
" FROM addresses WHERE contact_id = " c o n t a c t I d
a d d r e s s e s = d b ~ e x e c ( sql , . true , . o o S Q L i t e ~ O O _ A R R A Y _ O F _ D I R E C T O R I E S )
return a d d r e s s e s
: : METHOD u p d a t e R e a l A d d r e s s
e x p o s e d b
use a r g a d d r e s s I d , a d d r e s s T y p e , s t r e e t , c i t y , s t a t e , p o s t a l C o d e , c o u n t r y
sql = "UPDATE addresses SET type = '" a d d r e s s T y p e "', street = '" s t r e e t "', city = '" c i t y "'," | | ,
" state = '" s t a t e "', postal_code = '" p o s t a l C o d e "', country = '" c o u n t r y "' WHERE id = " a d d r e s s I d
r c = d b ~ e x e c ( sql )
if r c \ = 0 then do
s a y "Error updating address:" d b ~ e r r M s g ( )
return - 1
end
return r c
: : METHOD d e l e t e A d d r e s s
e x p o s e d b
use a r g a d d r e s s I d
sql = "DELETE FROM addresses WHERE id = " a d d r e s s I d
r c = d b ~ e x e c ( sql )
if r c \ = 0 then do
s a y "Error removing address:" d b ~ e r r M s g ( )
return - 1
end
return 0
: : METHOD r e m o v e C o n t a c t P h o n e s
e x p o s e d b
use a r g c o n t a c t I d
sql = "DELETE FROM phone_numbers WHERE contact_id = " c o n t a c t I d
r c = d b ~ e x e c ( sql )
if r c \ = 0 then do
s a y "Error removing phone numbers:" d b ~ e r r M s g ( )
return - 1
end
return 0
: : METHOD r e m o v e C o n t a c t E m a i l s
e x p o s e d b
use a r g c o n t a c t I d
sql = "DELETE FROM email_addresses WHERE contact_id = " c o n t a c t I d
r c = d b ~ e x e c ( sql )
if r c \ = 0 then do
s a y "Error removing email addresses:" d b ~ e r r M s g ( )
return - 1
end
return 0
: : METHOD r e m o v e C o n t a c t A d d r e s s e s
e x p o s e d b
use a r g c o n t a c t I d
sql = "DELETE FROM addresses WHERE contact_id = " c o n t a c t I d
r c = d b ~ e x e c ( sql )
if r c \ = 0 then do
s a y "Error removing addresses:" d b ~ e r r M s g ( )
return - 1
end
return 0