UserDB

The name "UserDB" stands for a set of built-in Interchange features related to the user database. That includes the database table that will hold your visitors data, and the set of functions operating either on that database or on people's session information.

Interchange's set of user database functions is elaborate, but it still manages not to place application-specific requirements on your practical database. While it is possible to use Interchange's UserDB functions with your custom type of database, it is strongly recommended to follow simple UserDB naming and usage standards. That alone will instantly give you a huge amount of built-in userdb functionality with no overhead programming.

The whole UserDB set consists of:

Creating the user database

To create the database, you could follow a very simple structure. The only two required fields are username and password. Your sample test database could look like this:

code	password

(Note that the name of the first column — the primary key — is arbitrary because Interchange's default functions are not accessing it by name. But it is a good standard to name the first field code in all your database tables).

It is, however, recommended to use an SQL database for any more complex functions. Let's take a look at a more elaborate user database that, among other things, has support for visitors' first and last name, inactivity flag and billing and shipping addresses:

Database  userdb  LENGTH_EXCEPTION_DEFAULT  truncate_log
Database  userdb  DEFAULT_TYPE  varchar(255)

Database  userdb  COLUMN_DEF   "username=varchar(64) NOT NULL PRIMARY KEY"
Database  userdb  COLUMN_DEF   "password=varchar(64) NOT NULL"
Database  userdb  COLUMN_DEF   "accounts=text"
Database  userdb  COLUMN_DEF   "acl=text"
Database  userdb  COLUMN_DEF   "address1=varchar(64)"
Database  userdb  COLUMN_DEF   "address2=varchar(64)"
Database  userdb  COLUMN_DEF   "address3=varchar(64)"
Database  userdb  COLUMN_DEF   "address_book=text"
Database  userdb  COLUMN_DEF   "b_address1=varchar(64)"
Database  userdb  COLUMN_DEF   "b_address2=varchar(64)"
Database  userdb  COLUMN_DEF   "b_address3=varchar(64)"
Database  userdb  COLUMN_DEF   "b_city=varchar(30)"
Database  userdb  COLUMN_DEF   "b_company=varchar(64)"
Database  userdb  COLUMN_DEF   "b_country=varchar(10)"
Database  userdb  COLUMN_DEF   "b_fname=varchar(30)"
Database  userdb  COLUMN_DEF   "b_lname=varchar(30)"
Database  userdb  COLUMN_DEF   "b_nickname=text"
Database  userdb  COLUMN_DEF   "b_phone=varchar(30)"
Database  userdb  COLUMN_DEF   "b_state=varchar(10)"
Database  userdb  COLUMN_DEF   "b_zip=varchar(10)"
Database  userdb  COLUMN_DEF   "carts=text"
Database  userdb  COLUMN_DEF   "city=varchar(30)"
Database  userdb  COLUMN_DEF   "company=varchar(64)"
Database  userdb  COLUMN_DEF   "country=varchar(10)"
Database  userdb  COLUMN_DEF   "credit_limit=varchar(16)"
Database  userdb  COLUMN_DEF   "db_acl=text"
Database  userdb  COLUMN_DEF   "dealer=varchar(32)"
Database  userdb  COLUMN_DEF   "email=varchar(42)"
Database  userdb  COLUMN_DEF   "fax=varchar(30)"
Database  userdb  COLUMN_DEF   "file_acl=text"
Database  userdb  COLUMN_DEF   "fname=varchar(30)"
Database  userdb  COLUMN_DEF   "inactive=varchar(8)"
Database  userdb  COLUMN_DEF   "lname=varchar(30)"
Database  userdb  COLUMN_DEF   "mail_list=text"
Database  userdb  COLUMN_DEF   "mod_time=varchar(20)"
Database  userdb  COLUMN_DEF   "mv_shipmode=varchar(255)"
Database  userdb  COLUMN_DEF   "owner=varchar(20)"
Database  userdb  COLUMN_DEF   "p_nickname=text"
Database  userdb  COLUMN_DEF   "phone_day=varchar(30)"
Database  userdb  COLUMN_DEF   "phone_night=varchar(30)"
Database  userdb  COLUMN_DEF   "price_level=varchar(30)"
Database  userdb  COLUMN_DEF   "preferences=text"
Database  userdb  COLUMN_DEF   "s_nickname=text"
Database  userdb  COLUMN_DEF   "state=varchar(20)"
Database  userdb  COLUMN_DEF   "zip=varchar(10)"
Database  userdb  DEFAULT      "inactive=''"

The above is Interchange's database representation format that allows Interchange to be aware of the database structure and automagically create it if it's missing. See database glossary entry for complete information.

The above is PostgreSQL-compatible definition. We have the equivalent MySQL version available (in short, you only need to replace type =text with MySQL's =BLOB).

Registering the database

To make the new database table accessible to Interchange, and to define a couple more UserDB-specific options, you could add the following to your catalog.cfg:

# For SQL databases:
Database  userdb  userdb.txt   __SQLDSN__

# Or for file-based database (DBM):
Database  userdb  userdb.txt   TAB

# Encrypt passwords?
UserDB    default    crypt         0

# Ignore uppercase/lowercase in usernames?
UserDB    default    ignore_case   1

# Enable this in combination with the above, so that
# username is always 'normalized':
Filter    mv_username lc

# To disable field containing date of last change:
UserDB    default    time_field    none

# To enable field containing date of last change
#UserDB    default    time_field    mod_time

UserDB    default    logfile       var/log/userdb.log

# To allow people login using their email, and not their username
# (in that case, username does not have to be meaningful and
# can be automatically assigned, like "U00001"):
#UserDB    default    indirect_login  email

Creating the login page

The login page could again be very simple, like this:

[set Login]
[userdb login]
[/set]

<form action="[process secure=1]" method="POST">
  <input type="hidden" name="mv_todo"  value="return">
  <input type="hidden" name="mv_nextpage" value="index">
  <input type="hidden" name="mv_click" value="Login">
  [form-session-id]

  <input name="mv_username" type="text">
  <input name="mv_password" type="password">
  <input value="Submit"   type="submit">
</form>

More complex login page with support for cookies and "remembering" users, and that displays a logout option if the user is already logged in could look like this:

[set Login]
  [userdb login]
[/set]

[set Logout_choice]
  [if type=explicit compare="[userdb function=logout clear='[cgi clear_values]']"]
    [set mv_no_count]1[/set]
    [set mv_no_session_id]1[/set]
    [if cgi clear_cart]
      [calc] @$Items = (); return; [/calc]
    [/if]
  [/if]
[/set]

[tmp cookie_username][read-cookie MV_USERNAME][/tmp]

<form action="[process secure=1]" method="POST">
  <input type="hidden" name="mv_todo"  value="return">
  <input type="hidden" name="mv_nextpage" value="index">
  [form-session-id]

  [if !session logged_in]
    <input type="hidden" name="mv_click" value="Login">

    <input name="mv_username" type="text">
    <input name="mv_password" type="password">

    [if config CookieLogin]
    <input type="hidden" name="mv_cookie_password" value="0">
    <input type="checkbox" name="mv_cookie_password" value="1" [if scratch cookie_username]CHECKED[/if]>
    [/if]

  [else]
    <input type="hidden" name="mv_click" value="Logout_choice">

    Logged in as [data session username].

    <input class="input" type="hidden" name="clear_values" value="1">
    <input class="input" type="checkbox" name="clear_values" checked value="1"> Erase values.

  [/else]
  [/if]

  <input type="submit" value="Submit">
</form>


Conclusion

When the user logs in, user database values are automatically copied to their values space and can be retrieved at any time using the [value] tag. (Values which are not present in the database might take on a default value defined with ValuesDefault).

Often times, you would like to save users' data back to the user database, be it during or at the end of user session. You can automatically do this with a combination of form processing directives, but if you want to do it manually, use the following simple yet powerful code:

[update values]
[userdb save]

The above code saves all users' values back to the database. Values which do not have a corresponding database field are ignored (as there's no place to save them). This is a fault-tolerant behavior and something you almost always want to happen anyway.

For all advanced examples and more technical discussion, see [userdb] tag documentation.

DocBook! Interchange!