//-< CLIDB.CPP >-----------------------------------------------------*--------* // GigaBASE Version 1.0 (c) 1999 GARRET * ? * // (Post Relational Database Management System) * /\| * // * / \ * // Created: 7-Nov-99 K.A. Knizhnik * / [] \ * // Last update: 7-Nov-99 K.A. Knizhnik * GARRET * //-------------------------------------------------------------------*--------* // Example of Web database publishing: Clients Database //-------------------------------------------------------------------*--------* #include "clidb.h" dbDatabase db; //- Client ------------------------------------------------ void Client::print(WWWconnection& con) const { con << TAG << ""; } REGISTER(Client); //- Manager ------------------------------------------------ bool Manager::loginFromAnyHost; void Manager::print(WWWconnection& con) const { con << TAG << ""; } REGISTER(Manager); //- Segment ------------------------------------------------ void Segment::print(WWWconnection& con) const { con << TAG << ""; } REGISTER(Segment); //- History ------------------------------------------------ void History::print(WWWconnection& con) const { ThreadContext& the = ThreadContext::of(con); char buf[64]; con << TAG << ""; } REGISTER(History); //---- ClientSequencer ------------------------------------- REGISTER(Sequencer); template void print(WWWconnection& con, dbCursor& cursor) { do { cursor->print(con); } while(cursor.next()); } template void print(WWWconnection& con, dbArray > const& arr) { dbCursor cursor; for (int i = 0, n = (int)arr.length(); i < n; i++) { cursor.at(arr[i])->print(con); } } //---- Thread Context -------------------------------------------------- ThreadContext& ThreadContext::of(WWWconnection& con) { if (con.userData == NULL) { con.userData = new ThreadContext; } return *(ThreadContext*)con.userData; } ThreadContext::ThreadContext() { qClient = "clientId=",clientId; qManager = "name=",&name; qClients = "start from",clientsArray,"order by organization"; qManagers = "start from",managersArray,"order by name"; qSegment = "name=",&name; qMessage = "messageId=",messageId; qMessages = "start from",messagesArray, "order by",dbDateTime::descent("date"); } //--- HTML specific part ------------------------------------------- #define HTML_HEAD "Content-type: text/html\r\n\r\n\ " #define BODY "" #define EMPTY_LIST "
" void mainMenuReference(WWWconnection& con) { char* manager = con.get("manager"); if (manager != NULL) { con << TAG << "


Back to main menu
"; } con << TAG << ""; } bool error(WWWconnection& con, char const* msg) { con << TAG << HTML_HEAD "ClientDB error" "

" << msg << "

"; mainMenuReference(con); return true; } bool addManagerForm(WWWconnection& con) { con << TAG << HTML_HEAD "Add new manager" BODY "

Add manager

" "
" "" "" "" "" "" "" "" "" "" "
Manager name
Host IP address
Administrator rights
" " " "
"; mainMenuReference(con); return true; } bool addClientForm(WWWconnection& con) { con << TAG << HTML_HEAD "Add new client" BODY "

Add client

" "
" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "
Organization
Phone
Phone2
Fax
E-Mail
WWW address
Person
Person2
CEO
Address
Information
Status
 " "
"; mainMenuReference(con); return true; } bool addSegmentForm(WWWconnection& con) { con << TAG << HTML_HEAD "Add new segment" BODY "

Add segment

" "
" "" "" "" "" "
Segment name

" " " "

"; mainMenuReference(con); return true; } bool addHistoryForm(WWWconnection& con) { con << TAG << HTML_HEAD "Add message" BODY "

Add message

" "
" "" "

" " " "

"; mainMenuReference(con); return true; } bool editManagerForm(WWWconnection& con) { if (con.get("new")) { return addManagerForm(con); } ThreadContext& the = ThreadContext::of(con); the.name = con.get("name"); if (the.name == NULL) { return error(con, "No manager was selected"); } if (the.managers.select(the.qManager) == 0) { return error(con, "No such manager"); } con << TAG << HTML_HEAD "Edit manager form" BODY "

Update manager

" "
" "" "" "" "" "" "" "" "
Manager namename << "\">
Host IP addressIPaddr << "\"
Administrator rightsflags & Manager::isMinAdmin) ? "CHECKED" : "") << ">
" " " "

" "

" "" "
"; } else { con << TAG << EMPTY_LIST ""; } mainMenuReference(con); return true; } bool editClientForm(WWWconnection& con) { if (con.get("new")) { return addClientForm(con); } ThreadContext& the = ThreadContext::of(con); char* client = con.get("client"); if (client == NULL) { return error(con, "No client was selected"); } the.clientId = atoi(client); if (the.clients.select(the.qClient) == 0) { return error(con, "No such client"); } the.name = con.get("manager"); if (the.managers.select(the.qManager) == 0) { return error(con, "No such manager"); } con << TAG << HTML_HEAD "Edit client form" BODY "

Update client

" "
" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "
Organizationorganization << "\">
Phonephone << "\">
Phone2phone2 << "\">
Faxfax << "\">
E-Mailemail << "\">
WWW addresswww << "\">
Personperson << "\">
Person2person2 << "\">
CEOlpr << "\">
Addressaddr << "\">
Informationinfo << "\">
Statusstatus << "\">

"; if (the.managers->flags & (Manager::isAdministrator|Manager::isMinAdmin)) { con << TAG << " "; } if (the.managers->flags & Manager::isAdministrator) { con << TAG << ""; } con << TAG << "

" "

" "" "" "" "
 "; } else { con << TAG << EMPTY_LIST; } con << TAG << "
"; mainMenuReference(con); return true; } bool editSegmentForm(WWWconnection& con) { if (con.get("new")) { return addSegmentForm(con); } ThreadContext& the = ThreadContext::of(con); the.name = con.get("name"); if (the.name == NULL) { return error(con, "No segment was selected"); } if (the.segments.select(the.qSegment) == 0) { return error(con, "No such segment"); } char* manager = con.get("manager"); con << TAG << HTML_HEAD "Edit segment" BODY "

Update segment

" "
" "" "" "" "" "" "
Segment name name << "\">

" " " "

" "

Select manager

" "
" "" "" "" "
 "; } else { con << TAG << EMPTY_LIST; } con << TAG << "

" "

Select client

" "
" "" "" "" "
 "; } else { con << TAG << EMPTY_LIST; } con << TAG << "
"; mainMenuReference(con); return true; } bool editHistoryForm(WWWconnection& con) { if (con.get("new")) { return addHistoryForm(con); } ThreadContext& the = ThreadContext::of(con); char buf[64]; char* messageId = con.get("messageId"); if (messageId == NULL) { return error(con, "No message was selected"); } the.messageId = atoi(messageId); if (the.messages.select(the.qMessage) == 0) { return error(con, "No such message"); } the.name = con.get("manager"); the.clients.at(the.messages->client); if (the.messages->manager != null) { the.managers.at(the.messages->manager); } con << TAG << HTML_HEAD "Edit message" BODY "

Edit message

" "
" "" "" "" "" ""; if (the.messages->manager != null) { con << TAG << ""; } con << TAG << "" "" "
Client" << the.clients->organization << "
Manager" << the.managers->name << "
Datedate.asString(buf, sizeof buf) << "\">

" "

"; if (the.managers.select(the.qManager) == 0) { return error(con, "No such manager"); } if ((the.managers->flags & (Manager::isAdministrator|Manager::isMinAdmin)) || the.managers.currentId() == the.messages->manager) { con << TAG << " " ""; } con << TAG << "

"; mainMenuReference(con); return true; } bool managerForm(WWWconnection& con) { ThreadContext& the = ThreadContext::of(con); the.name = con.get("manager"); if (the.managers.select(the.qManager) == 0) { return error(con, "No such manager"); } if (the.managers->flags & Manager::isAdministrator) { con << TAG << HTML_HEAD "Administrator menu" BODY "

Administrator menu

" "
" "" "" "" "" "" "" "
Manager namename << "\">
Manager host IP addressIPaddr << "\"
" "

" "

Select segment

" "
" "" "" "
 "; } else { con << TAG << EMPTY_LIST; } con << TAG << "
" "


" "
" "" "
" "
"; } else { con << TAG << HTML_HEAD "Manager menu" BODY "

Manager menu

" "
" "" "" ""; if (the.managers->flags & Manager::isMinAdmin) { con << TAG <<""; } the.segments.at(the.managers->segment); con << TAG << "" "" "" "
Manager namename << "\">
Manager host IP addressIPaddr << "\"
" "

" "

Select client

" "
" "" "" "name << "\">" "
 "; } else { con << TAG << EMPTY_LIST; } con << TAG << "
"; } con << TAG << ""; return true; } bool login(WWWconnection& con) { ThreadContext& the = ThreadContext::of(con); the.name = con.get("name"); if (the.managers.select(the.qManager) == 0) { return error(con, "No such manager"); } if (!Manager::loginFromAnyHost && strcmp(the.managers->IPaddr, "*") != 0 && strcmp(the.managers->IPaddr, con.getPeer()) != 0) { return error(con, "You can not login from this host"); } con.addPair("manager", the.name); return managerForm(con); } bool shutdown(WWWconnection& con) { con << TAG << HTML_HEAD "ClientDB message" "

ClientDB server is terminated

"; return false; } bool addManager(WWWconnection& con) { ThreadContext& the = ThreadContext::of(con); Manager manager; the.name = con.get("segment"); if (the.segments.select(the.qSegment, dbCursorForUpdate) == 0) { return error(con, "No such segment"); } the.name = con.get("name"); if (the.managers.select(the.qManager) != 0) { return error(con, "Manager with such name already exists"); } manager.name = con.get("name"); manager.IPaddr = con.get("ipaddr"); manager.flags = con.get("miniadmin") ? Manager::isMinAdmin : 0; manager.segment = the.segments.currentId(); insert(manager); return managerForm(con); } bool addClient(WWWconnection& con) { ThreadContext& the = ThreadContext::of(con); Client client; the.sequencer.select(dbCursorForUpdate); the.name = con.get("segment"); if (the.segments.select(the.qSegment) == 0) { return error(con, "No such segment"); } client.organization = con.get("organization"); client.phone = con.get("phone"); client.phone2 = con.get("phone2"); client.fax = con.get("fax"); client.email = con.get("email"); client.www = con.get("www"); client.person = con.get("person"); client.person2 = con.get("person2"); client.lpr = con.get("lpr"); client.addr = con.get("addr"); client.info = con.get("info"); client.status = con.get("status"); client.clientId = ++the.sequencer->lastClientId; client.segment = the.segments.currentId(); the.sequencer.update(); insert(client); return managerForm(con); } bool addSegment(WWWconnection& con) { ThreadContext& the = ThreadContext::of(con); Segment segment; segment.name = the.name = con.get("name"); if (the.segments.select(the.qSegment, dbCursorForUpdate) != 0) { return error(con, "Segment with such name already exists"); } insert(segment); return managerForm(con); } bool addHistory(WWWconnection& con) { ThreadContext& the = ThreadContext::of(con); the.sequencer.select(dbCursorForUpdate); the.clientId = atoi(con.get("client")); if (the.clients.select(the.qClient) == 0) { error(con, "No such client"); return true; } History his; his.messageId = ++the.sequencer->lastMessageId; his.message = con.get("message"); his.client = the.clients.currentId(); the.name = con.get("manager"); if (the.managers.select(the.qManager) == 0) { error(con, "No such manger"); return true; } his.manager = the.managers.currentId(); his.date = dbDateTime::current(); insert(his); the.sequencer.update(); return managerForm(con); } bool editManager(WWWconnection& con) { ThreadContext& the = ThreadContext::of(con); the.name = con.get("oldName"); if (the.managers.select(the.qManager, dbCursorForUpdate) == 0) { error(con, "No such manager"); return true; } if (strcmp(con.get("action"), "Remove") == 0) { the.managers.remove(); return managerForm(con); } the.managers->name = con.get("name"); the.managers->IPaddr = con.get("ipaddr"); if (con.get("miniadmin")) { the.managers->flags |= Manager::isMinAdmin; } else { the.managers->flags &= ~Manager::isMinAdmin; } the.managers.update(); return managerForm(con); } bool editClient(WWWconnection& con) { ThreadContext& the = ThreadContext::of(con); the.clientId = atoi(con.get("client")); if (the.clients.select(the.qClient, dbCursorForUpdate) == 0) { error(con, "No such client"); return true; } if (strcmp(con.get("action"), "Remove") == 0) { the.clients.remove(); } else { the.clients->organization = con.get("organization"); the.clients->phone = con.get("phone"); the.clients->phone2 = con.get("phone2"); the.clients->fax = con.get("fax"); the.clients->email = con.get("email"); the.clients->www = con.get("www"); the.clients->person = con.get("person"); the.clients->person2 = con.get("person2"); the.clients->lpr = con.get("lpr"); the.clients->addr = con.get("addr"); the.clients->info = con.get("info"); the.clients->status = con.get("status"); the.clients.update(); } return managerForm(con); } bool editSegment(WWWconnection& con) { ThreadContext& the = ThreadContext::of(con); the.name = con.get("oldName"); if (the.segments.select(the.qSegment, dbCursorForUpdate) == 0) { error(con, "No such segment"); return true; } if (strcmp(con.get("action"), "Remove") == 0) { the.segments.remove(); } else { the.segments->name = con.get("name"); the.segments.update(); } return managerForm(con); } bool editHistory(WWWconnection& con) { ThreadContext& the = ThreadContext::of(con); the.messageId = atoi(con.get("messageId")); if (the.messages.select(the.qMessage, dbCursorForUpdate) == 0) { error(con, "No such message"); return true; } if (strcmp(con.get("action"), "Remove") == 0) { the.messages.remove(); } else { the.messages->message = con.get("message"); the.messages.update(); } return managerForm(con); } WWWapi::dispatcher dispatchTable[] = { {"addManagerForm", addManagerForm}, {"addClientForm", addClientForm}, {"addSegmentForm", addSegmentForm}, {"addHistoryForm", addHistoryForm}, {"editManagerForm", editManagerForm}, {"editClientForm", editClientForm}, {"editSegmentForm", editSegmentForm}, {"editHistoryForm", editHistoryForm}, {"managerForm", managerForm}, {"login", login}, {"shutdown", shutdown}, {"addManager", addManager}, {"addClient", addClient}, {"addSegment", addSegment}, {"addHistory", addHistory}, {"editManager", editManager}, {"editClient", editClient}, {"editSegment", editSegment}, {"editHistory", editHistory} }; #ifdef USE_EXTERNAL_HTTP_SERVER CGIapi wwwServer(db, itemsof(dispatchTable), dispatchTable); char* defaultAddress = "localhost:6101"; socket_t::socket_domain domain = socket_t::sock_local_domain; #else #ifdef USE_QUEUE_MANAGER HTTPapi wwwServer(db, itemsof(dispatchTable), dispatchTable, true); #else HTTPapi wwwServer(db, itemsof(dispatchTable), dispatchTable, false); #endif char* defaultAddress = "localhost:80"; socket_t::socket_domain domain = socket_t::sock_global_domain; #endif int __cdecl main(int argc, char* argv[]) { char* address = (argc > 1) ? argv[1] : defaultAddress; if (!wwwServer.open(address, domain)) { fprintf(stderr, "Failed to open WWW session\n"); return EXIT_FAILURE; } if (!db.open("clidb.dbs")) { fprintf(stderr, "Failed to open database\n"); return EXIT_FAILURE; } dbCursor sequencer; if (sequencer.select() == 0) { Sequencer seq; seq.lastClientId = 0; seq.lastMessageId = 0; insert(seq); Manager administrator; administrator.name = "administrator"; administrator.IPaddr = "*"; administrator.flags = Manager::isAdministrator; insert(administrator); } db.commit(); if (argc > 2 && strcmp(argv[2], "login_from_any_host") == 0) { Manager::loginFromAnyHost = true; } #ifdef USE_QUEUE_MANAGER QueueManager qmgr(wwwServer, db); qmgr.start(); #else WWWconnection con; while (wwwServer.connect(con) && wwwServer.serve(con)); #endif db.close(); printf("End of session\n"); return EXIT_SUCCESS; }