class ref name: business
category-group: people
layer: 10
header file: z_business.h

synopsis.
The business_o class is a large, involved class in the people group. A business object is a child of the orthodox_o class. Thus, a business can be retrieved from and saved to a database.

In order for the Z Directory business object to be able to exist in a database, all of its dependencies must be met. This means that the topology dataset needs to be loaded prior to saving a business object. The Z Directory topology dataset is normally done when the Z Directory is installed. The program using the business object must be able to access this database, which can be on a different computer from the program. Basically the database must be accessible via the Z Directory components. A limitation is that the business table must be in the same database as the other topology dataset. The ability to use tables in a different database from the table in question ("business" table, in this case) is not yet available in the Z Directory.

The class worker_o is closely related to the business_o class. The term "worker" is used instead of "employee", so that it can encompass any person associated with and doing work for a business: employee, contractor, consultant, executive, even a director. Technically a director or a contractor would not be classified as an employee. The relationship between the two classes is associative: a business object does not own a worker object, just as a business does not own a worker. Thus, a worker that works for a business, if not a slave, has [possibly multiple] start and end dates. Also, a worker can work for more than one business, possibly at the same time.

description.
As an orthodox sub-class, this class has a database schema. The 'columns' section of this schema looks like this:

columns
[
  < name type qual nulls_ok is_uniq ref_table ref_column default check >
  <ownedby       int      \"\" YES     NO      \"\"      \"\"     \"\"   \"\" >
  <sic           int      \"\" YES     NO      \"\"      \"\"     \"\"   \"\" >
  <population    int      \"\" YES     NO      \"\"      \"\"     \"\"   \"\" >
  <friendly      int        3  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <potential     int        3  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <full_name     varchar   80  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <short_name    varchar   80  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <cased_name    varchar   80  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <slogan        varchar   60  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <alias         varchar   70  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <abbreviation  varchar   40  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <attention     varchar   80  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <regno         varchar   20  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <ownedby_str   varchar   60  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <category      varchar   80  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <url0          varchar   60  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <url1          varchar   60  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <url2          varchar   60  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <url3          varchar   60  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <env_list      varchar  512  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <fref          varchar   40  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <note          text    \"\"  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <description   text    \"\"  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <directions    varchar  512  YES     NO      \"\"      \"\"     \"\"   \"\" >
  <hours         varchar   60  YES     NO      \"\"      \"\"     \"\"   \"\" >
  ]

Many of these columns can be set via member function put_value() (which see). The column is referenced by a keyword which may be the same as the table column name or different (if different, usually it's similar). The list of keywords, in alphabetical order:

keyword short name table name get()
add()?
type notes
abbreviation abbrev abbreviation   line item  
alias alias alias   line item any other name the business goes by
email-address arpa   A multiword item other keyword aliases: arpa-address; e-mail-address
attention attn attention   line item this is for letter packaging
cased_name spell cased_name   line item  
description what description   text  
directions direc directions   text  
environment-list env env_list   text brief list of blank-separated keywords
event events   A repeatable block  
external_id n.a. external_id G line item  
fax-number fax   A multiword item  
file-reference fref fref   line item specialized use: file name where entry originated
found found found   line item  
full_name n.a. full_name G line item like who:, but synthetically derived
group group category   line item  
hours hours hours   line item this may become type text
income incom n.a.   repeatable block fully dollar-formatted, eg, "$1,500,000"
note note note   text  
owner owner ownedby_str   line item  
phone-number phone   A multiword item fax-number is actually an alias
population popu population   line item number of workers, latest census. Should include commas (eg "3,141" not "3141"
potential potent potential   line item "private" "marketing" number, in [-100..+100] (inclusive)
regno regno regno   line item registration number (more common in UK)
short_name n.a. short_name G line item eg, "Bling & Blang", whereas full name might be "Bling & Blang Associates, LLC"
SIC-code SIC sic   line item  
slogan slogan slogan   line item up to 58 characters
source source source   line item where you first discovered the business (URL, newspaper name, etc)
status status   A repeatable block follows same syntax as event: items - date, followed by "current status" description
t_end end t_end G line item  
t_start start t_start   line item  
web-address www     multiword item alternate keyword: url. Up to 4 URLs can be stored. See the discussion titled "web address anomaly" on this page.
who who     repeatable block the who-block is an important special case.
The keyword is what you use to reference the item in put_value(); the short name is used in the character array to prefix the item's value (string representation); the table name is simply the column name in the database table (as per the previous list).

The type column in the table above describes the format the item can be represented in a string. The parsing is done by the the kw_parser object . You can find more info about the parsing process there. The column labeled "get()/add()?" is used to note items that are treated a little differently. Items denoted 'G' can be accessed from a business_o instance via the get() member function, not the get_value() function (this is an anomality to be fixed in future releases). Items denoted 'A' should be added to a business object via the add_value() function (this makes things work in the same way as the worker object).

A business can and usually does have things such as a postal address, telephones, and e-mail addresses, so the following objects represent sub-tables of the business class:

postal_address_o
phone_number_o
email_address_o
event_o
extended_data_o

There is a long chain of dependencies for the business_o class. For example, the postal_address table is a sub-table of the business table, so it must exist prior to the existance of the business table. The postal_address table has a foreign key to the country and landmark_code tables (a postal address must be within a country).

It would be easier to simply load the full Z Directory topo data into a database rather than trying to chase down the interdependencies and making only the minimal set of tables required for a given orthodox subclass.

The web address anomaly.

Adding a "web address" (ie, a url) to a business is done via put_value(). However, you can call this function repeatedly, up to 4 times. The text given as a URL is stored directly in the entry's row in the business table. This means that although a URL is technically a repeatable item, and would normally be saved to a separate table, a simpler albeit less correct approach has been taken. The limit of 4 URLs is actually arbitrary, and represents a compromise between the two possible approaches: (a) "1 business, 1 URL"; and (b) a business can have theoretically an infinite number of URLs. To fetch a given URL, use get_nth_value() (the mixing of function pairs here further aggravates consistency).

member functions (primary)

business_o()
SIGNATURE: business_o ()
SYNOPSIS: creates a business object, devoid of any data.
 

business_o(business_o)
SIGNATURE: business_o (const business_o &rhs)
SYNOPSIS: makes an exact copy of the "rhs" object.
TRAITS: this function is inline
 

operator = (business_o)
SIGNATURE: business_o &operator = (const business_o &rhs)
SYNOPSIS: copies exactly the RHS object ("rhs"); any previous contents are over-written.
RETURNS: reference [handle] to the current (left-hand side) object
 

destructor
SIGNATURE: ~business_o ()
SYNOPSIS:
'destroys' the object: all data fields are reset (to empty strings). This should be explicitly called only on pointers to computer objects created via "new".
 

name()
SIGNATURE: const string_o &name (int *pi = NULL) const
SYNOPSIS: returns the name of the business. This is equivalent to get("full_name").
 

get_value()
SIGNATURE: const string_o &get_value (const string_o &, int *) const
SYNOPSIS: [WIP]
 

get_nth_value()
SIGNATURE: const string_o &get_nth_value (const string_o &, count_t, int *) const
SYNOPSIS: [WIP]
 

get_nth_event()
SIGNATURE: const event_o &get_nth_event (count_t, int *) const
SYNOPSIS: [WIP]
 

get_nth_xdata()
SIGNATURE: const xdata_o &get_nth_xdata (const string_o &, count_t, int *) const
SYNOPSIS: [not ready]
 

get_nth_income()
SIGNATURE: const xdata_o &get_nth_income (count_t, int *) const
SYNOPSIS: [WIP]
TRAITS: this function is inline
 

get_nth_status()
SIGNATURE: const xdata_o &get_nth_status (count_t, int *) const
SYNOPSIS: [WIP]
TRAITS: this function is inline
 

get_nth_address()
SIGNATURE: const postal_address_o &get_nth_address (count_t, int *) const
SYNOPSIS: [not ready]
 

get_nth_arpa()
SIGNATURE: const email_address_o &get_nth_arpa (count_t, int *) const
SYNOPSIS: [WIP]
 

get_nth_phone()
SIGNATURE: const phone_number_o &get_nth_phone (count_t, int *) const
SYNOPSIS: [WIP]
 

last_error()
SIGNATURE: int last_error () const
SYNOPSIS: [WIP]
TRAITS: this function is inline
 

is_loaded()
SIGNATURE: boolean is_loaded (int * = NULL) const
SYNOPSIS: [COMING SOON..]
 

operator !=()
SIGNATURE: int operator != (const business_o &) const
SYNOPSIS: [WIP]
TRAITS: this function is inline
 

operator ==()
SIGNATURE: int opera=or == (const business_o &) const
SYNOPSIS: [WIP]
 

last_error()
SIGNATURE: int last_error (string_o &, string_o &, count_t &, count_t &, int &) const
SYNOPSIS: [WIP]
 

set_error()
SIGNATURE: int set_error (string_o = "")
SYNOPSIS: [COMING SOON..]
TRAITS: this function is inline
 

operator <<()
SIGNATURE: friend std::ostream &operator << (std::ostream &, const business_o &)
SYNOPSIS: [WIP]
 

default_ccode()
SIGNATURE: const string_o &default_ccode()
SYNOPSIS: [WIP]
TRAITS: this function is inline
 

setmode()
SIGNATURE: int setmode (const paramstring_o &, int * = NULL)
SYNOPSIS: [COMING SOON..]
 

reset()
SIGNATURE: int reset ()
SYNOPSIS: [WIP]
 

soft_reset()
SIGNATURE: int soft_reset ()
SYNOPSIS: [COMING SOON..]
 

print()
SIGNATURE: string_o print (int * = NULL) const
SYNOPSIS: [COMING SOON..]
 

store_add()
SIGNATURE: int store_add (int * = NULL)
SYNOPSIS: [COMING SOON..]
 

store_fetch()
SIGNATURE: int store_fetch (const string_o & = "", int * = NULL)
SYNOPSIS: [COMING SOON..]
 

store_nfetch()
SIGNATURE: int store_nfetch (dbbi_o &dx, count_t &i, const count_t my_max, string_o &where_clause, int *pexi)
SYNOPSIS: [WIP]
 

add_address()
SIGNATURE: int add_address (const postal_address_o &, int *pi = NULL)
SYNOPSIS: [WIP]
 

add_event()
SIGNATURE: int add_event (const event_o &, int *pi = NULL)
SYNOPSIS: [WIP]
 

add_income()
SIGNATURE: int add_income (const xdata_o &, int *pi = NULL)
SYNOPSIS: [WIP]
 

add_status()
SIGNATURE: int add_status (const xdata_o &, int *pi = NULL)
SYNOPSIS: [COMING SOON..]
 

put_value()
SIGNATURE: int put_value (const string_o &nam, const string_o &val, int *pi = NULL)
SYNOPSIS: sets the value specified by 'nam'. The item must be a property of the business, not a repeatable (ie, sub-table) item.
 

add_value()
SIGNATURE: int add_value (const string_o &nam, const string_o &val, int *pi = NULL)
SYNOPSIS:
adds the value specified by 'nam'. The parameter must be a "repeatable type": phone number, e-mail address, or event. The items subject to this function are marked with an "A" in the 4th column of the master list on this page.
 

clone()
SIGNATURE: business_o *clone () const
SYNOPSIS: makes a complete copy of the business object, returning a pointer to it
TRAITS: this function is inline
 

operator =()
SIGNATURE: business_o &operator = (const textstring_o &)
SYNOPSIS: [WIP]
 

operator =()
SIGNATURE: orthodox_o &operator = (const rec_dbag_o &)
SYNOPSIS: [WIP]
 

bad_reference()
SIGNATURE: static const business_o &bad_reference ()
SYNOPSIS: [COMING SOON..]
 

error_info()
SIGNATURE: string_o error_info () const
SYNOPSIS: [WIP]
 

position()
SIGNATURE: int position () const
SYNOPSIS: [WIP]
 

zdb_lookup_existing_biz()
SIGNATURE: int zdb_lookup_existing_biz (business_o &biz, business_o &biz2, string_o &s_name, string_o &s_val, paramstring_o &ps, int *pi)
SYNOPSIS:
This external subroutine tries to find a business in the database with 1) the same name; 2) a matching e-mail address; 3) a matching phone number; 4) a matching postal address.
PARAMETERS

  • s_name: [output] a string that reports how the match was found, e.g., "email_address", "phone_number", etc.
  • s_val: the value of the match, eg, the phone number (put into string format)
  • ps: a list of items to check, as a parameter string. examples: "checkphone=YES checkarpa=NO checkpost=YES".
  • pi: [output] error indicator flag. values: 0: all ok;
    4: error trying to get biz table ID;
    5: error trying to create biz table(s)
DESCRIPTION:
If one (or more) is found, this returns TRUE. Note that this does not mean that the business is already in the database: 2+ businesses can actually share a phone, a postal address, etc (though in practice this is uncommon). And, they can have the same name (this is one of the reasons lawyers exist).
A list of tables to check must be provided in 'ps'; the values can be "YES" or "NO"; the keywords are: checkname, checkarpa, checkpost, checkphone, and checkfax.
RETURNS:
0: found
1: not found
-1: error
 

zdb_fetch_certain_businesses()
SIGNATURE: int zdb_fetch_certain_businesses(vlist_o &x, const string_o &filter, int *pi)
SYNOPSIS:
this uses the string in 'filter' as the "where clause" for a SQL lookup on the business table. All matching businesses are returned in container 'x'.
TRAITS: this subroutine appears to be in a semi-incomplete state. it is not guaranteed.
 

zdb_fetchbiz_by_name()
SIGNATURE: int zdb_fetchbiz_by_name (business_o &b, const string_o &s, flag_o *pflag, int *pi = NULL)
SYNOPSIS:
Retrieves a business object from the database matching the name given in 's'. The spelling must be exact (well almost; there are a couple of wildcard options that can be done via the 'pflag' parameter).
DESCRIPTION:
By default (eg, not supplying a flag variable 'pflag'), this subroutine will search all "name" type fields in the business record:

    full_name
    short_name
    cased_name
    abbreviation
    alias
Also, by default, only an exact match will be done. enter the 'pflag' (flag) parameter:
    543210
    ^^^^^^
    ||||||......bit 0 (value =  1): do wildcard expansion at end
    |||||.......bit 1 (value =  2): wildcard search before string
    |||.........bit 2 (value =  4): turn off 'abbreviation' column
    ||..........bit 3 (value =  8): turn off 'alias' column
    |...........bit 4 (value = 16): turn off 'short_name' column
Setting bits 0 and 1 is akin to doing a "*[name]*" search. In SQL parlance, it maps onto a "LIKE '%[name]%'" section of the where clause.
Example.
business_o b;
flag_o f;
f.set(0);
string_o name = "ACME INC";
zdb_fetchbiz_by_name(b, name, &f);
If the business table contains these rows:
|---|-----------------------|
| ID| full_name             |
|---|-----------------------|
| 1 | ACME INCORPORATORS    |
| 2 | FACME INCOGNITO       |
| 3 | ACME CASHME           |
| 4 | ACME INC              |
| 5 | ACME INCLUDED         |
| 6 | LITTLE ACME INC       |
|---|-----------------------|
Then row IDs 1, 4, and 5 will match - the first such row encountered (by the underlying SQL database engine) will be returned. If instead of "f.set(0);" the code snippet above would have subsituted "f.set(1);", the search would be [in regex parlance] "*ACME INC", so row IDs 4 and 6 would match. If both flags (0 and 1) are set, all of the rows except row ID 3 would be candidates.
RETURNS:
0: found
1: not found
 

zdb_fetchbiz_by_emailaddr()
SIGNATURE: int zdb_fetchbiz_by_emailaddr (business_o &biz, email_address_o &ema, count_t &nw, int *pi = NULL)
SYNOPSIS:
given an e-mail address 'ema', if it belongs to a business, this subroutine will load the business data in the database into the output parameter - object 'biz'.
PARAMETERS

  • biz: [output] the business object that will be set (populated) if one is found
  • ema: [input] the e-mail address to look for
  • pi: [output] error indicator flag. values: 0: all ok,found the biz
    zErr_NoMatch: no such e-mail address
    zErr_DB_Cannot_Fetch: error trying to retrieve biz (should be there)
    zErr_NotOwner: e-mail address found, but doesn't belong to a biz
    zErr_DB_Cannot_Access: database cannot be accessed
    1: [warning only] e-mail address belongs to a worker
RETURNS:
0: found
1: not found
-1: error
 

zdb_fetchbiz_by_postaladdr()
SIGNATURE: int zdb_fetchbiz_by_postaladdr (business_o &biz, postal_address_o &pa, count_t &nw, int *pi = NULL)
SYNOPSIS:
given a postsal address object 'pa', this routine looks for a business record that owns the address. 'paa' must have the database ID and owner values correctly set in order for this call to succeed.
 

zdb_fetchbiz_by_phone()
SIGNATURE: int zdb_fetchbiz_by_phone (business_o &b, phone_number_o &ph, count_t &n, int *pi = NULL)
SYNOPSIS:
given a postsal address object 'pa', this routine looks for a business record that owns the address. 'paa' must have the database ID and owner values correctly set in order for this call to succeed.
 

zdb_fetchbiz_by_event()
SIGNATURE: int zdb_fetchbiz_by_event (business_o &biz, event_o &e, count_t& nw, int *pi = NULL)
SYNOPSIS: This function is a stub. it is currently NOT IMPLEMENTED.
 

zdb_fetchbiz_by_emaildomain()
SIGNATURE: int zdb_fetchbiz_by_emaildomain (business_o &biz, const string_o &dom, int *pi = NULL)
SYNOPSIS:
this subroutine searches for a business that has an e-mail with a matching e-mail domain part [only]. thus, it is a "loose" version of zdb_fetchbiz_by_emailaddr().
DESCRIPTION:
EXAMPLE: if the given domain string is "tekmarkinc.com", this subroutine will search for an e-mail address whose domain matches that. If one is found, and the owner is a business, the business will be loaded into 'biz'. The first matching domain will be used. There is an initial check to see if the domain is an ISP (eg, "gmail.com", hotmail.com", etc) If so, the routine aborts and 1 is returned. This is because some businesses may choose to use an e-mail address belonging to an ISP (these are probably very tiny businesses), so such domains would match a [possibly] large number of businesses.
 

zdb_get_no_owner()
SIGNATURE: int zdb_get_no_owner (orthodox_o &ortho, int type)
SYNOPSIS: the purpose of this strange subroutine has been lost to the ages
DESCRIPTION:
from the internal documentation, "Checks owner ID of the orthodox object. If there is no business (type = 0) or person (type = 1) object with ID = OWNER return 1, else return 0"
TRAITS: this subroutine will no doubt go away unless there is evidence to show that it is needed. DON'T USE or USE AT YOUR OWN RISK.
 

usage.
To set a unary value (an item or property of the business that does not repeat, ie, there is only one of the item), use the member function put_value():

    int ie0, ie1;
    business_o biz;
    ie0 = biz.put_value ("directions", "straight ahead; and to the right", &ie1);
    ie0 = biz.put_value ("population", "15,750",   &ie1);
    ie0 = biz.put_value ("SIC-code",   "7372",     &ie1);
    ie0 = biz.put_value ("status",     "well fed", &ie1);
    ie0 = biz.put_value ("web-address", "www.nobody.org", &ie1);

Note that "web-address" is a special case. This can be called up to 4 times to add 4 different URLs. The URL set is a special case, where the information is stored directly into the business record, defying normalization rules.