- #include <stdio.h>
- #include "fastdb.h"
- USE_FASTDB_NAMESPACE
- class Contract;
- class Detail {
- public:
- char const* name;
- char const* material;
- char const* color;
- real4 weight;
- dbArray< dbReference<Contract> > contracts;
- TYPE_DESCRIPTOR((KEY(name, INDEXED|HASHED),
- KEY(material, HASHED),
- KEY(color, HASHED),
- KEY(weight, INDEXED),
- RELATION(contracts, detail)));
- };
- class Supplier {
- public:
- char const* company;
- char const* location;
- bool foreign;
- dbArray< dbReference<Contract> > contracts;
- TYPE_DESCRIPTOR((KEY(company, INDEXED|HASHED),
- KEY(location, HASHED),
- FIELD(foreign),
- RELATION(contracts, supplier)));
- };
- class Contract {
- public:
- dbDateTime delivery;
- int4 quantity;
- db_int8 price;
- dbReference<Detail> detail;
- dbReference<Supplier> supplier;
- TYPE_DESCRIPTOR((KEY(delivery, HASHED|INDEXED),
- KEY(quantity, INDEXED),
- KEY(price, INDEXED),
- RELATION(detail, contracts),
- RELATION(supplier, contracts)));
- };
- REGISTER(Detail);
- REGISTER(Supplier);
- REGISTER(Contract);
- void input(char const* prompt, char* buf, size_t buf_size)
- {
- char* p;
- do {
- printf(prompt);
- *buf = '\0';
- fgets(buf, buf_size, stdin);
- p = buf + strlen(buf);
- } while (p <= buf+1);
- if (*(p-1) == '\n') {
- *--p = '\0';
- }
- }
- int main()
- {
- const int maxStrLen = 256;
- dbDatabase db;
- char buf[maxStrLen];
- char name[maxStrLen];
- char company[maxStrLen];
- char material[maxStrLen];
- char address[maxStrLen];
- int d, m, y;
- int i, n;
- int choice;
- int quantity;
- db_int8 price;
- dbDateTime from, till;
- Contract contract;
- Supplier supplier;
- Detail detail;
- dbQuery q1, q2, q3, q4, q6, q9, q10;
- q1 = "exists i:(contracts[i].supplier.company=",company,")";
- q2 = "name like",name;
- q3 = "supplier.location =",address;
- q4 = between("delivery", from, till),"and price >",price,
- "order by",dbDateTime::ascent("delivery");
- q6 = "price >=",price,"or quantity >=",quantity;
- q9 = "company =",company;
- q10 = "supplier.company =",company,"and detail.name like",name;
- dbCursor<Detail> details;
- dbCursor<Contract> contracts;
- dbCursor<Supplier> suppliers;
- dbCursor<Contract> updateContracts(dbCursorForUpdate);
- if (db.open("testdb")) {
- while (true) {
- printf(
- "\n\n MENU:\n\
- 1. Details shipped by supplier\n\
- 2. Suppliers of the detail\n\
- 3. Contracts from specified city\n\
- 4. Expensive details to be delivered in specified period\n\
- 5. Foreign suppliers\n\
- 6. Important contracts\n\
- 7. New supplier\n\
- 8. New detail\n\
- 9. New contract\n\
- 10. Cancel contract\n\
- 11. Update contract\n\
- 12. Exit\n\n");
- input(">> ", buf, sizeof buf);
- if (sscanf(buf, "%d", &choice) != 1) {
- continue;
- }
- switch (choice) {
- case 1:
- printf("Details shipped by supplier\n");
- input("Supplier company: ", company, sizeof company);
- if (details.select(q1) > 0) {
- printf("Detail\tMaterial\tColor\tWeight\n");
- do {
- printf("%s\t%s\t%s\t%f\n",
- details->name, details->material,
- details->color, details->weight);
- } while (details.next());
- } else {
- printf("No details shipped by this supplier\n");
- }
- break;
- case 2:
- printf("Suppliers of the detail\n");
- input("Regular expression for detail name: ",name,sizeof name);
- if (details.select(q2) > 0) {
- printf("Detail\tCompany\tLocation\tPrice\n");
- do {
- n = details->contracts.length();
- for (i = 0; i < n; i++) {
- contracts.at(details->contracts[i]);
- suppliers.at(contracts->supplier);
- printf("%s\t%s\t%s\t" INT8_FORMAT "\n",
- details->name,
- suppliers->company, suppliers->location,
- contracts->price);
- }
- } while (details.next());
- } else {
- printf("No such details\n");
- }
- break;
- case 3:
- printf("Contracts from specified city\n");
- input("City: ", address, sizeof address);
- if (contracts.select(q3) > 0) {
- printf("Detail\tCompany\tQuantity\n");
- do {
- printf("%s\t%s\t%d\n",
- details.at(contracts->detail)->name,
- suppliers.at(contracts->supplier)->company,
- contracts->quantity);
- } while (contracts.next());
- } else {
- printf("No contracts with companies in this city");
- }
- break;
- case 4:
- printf("Expensive details to be delivered in specified period\n");
- input("Delivered after (DD-MM-YYYY): ", buf, sizeof buf);
- if (sscanf(buf, "%d-%d-%d\n", &d, &m, &y) != 3) {
- printf("Wrong date\n");
- continue;
- }
- from = dbDateTime(y, m, d);
- input("Delivered before (DD-MM-YYYY): ", buf, sizeof buf);
- if (sscanf(buf, "%d-%d-%d\n", &d, &m, &y) != 3) {
- printf("Wrong date\n");
- continue;
- }
- till = dbDateTime(y, m, d);
- input("Minimal contract price: ", buf, sizeof buf);
- if (sscanf(buf, INT8_FORMAT, &price) != 1) {
- printf("Bad value\n");
- continue;
- }
- if (contracts.select(q4) > 0) {
- printf("Detail\tDate\tPrice\n");
- do {
- printf("%s\t%s\t" INT8_FORMAT "\n",
- details.at(contracts->detail)->name,
- contracts->delivery.asString(buf, sizeof buf),
- contracts->price);
- } while (contracts.next());
- } else {
- printf("No such contracts\n");
- }
- break;
- case 5:
- printf("Foreign suppliers\n");
- if (suppliers.select("foreign and length(contracts) > 0") > 0){
- printf("Company\tLocation\n");
- do {
- printf("%s\t%s\n", suppliers->company,
- suppliers->location);
- } while (suppliers.next());
- } else {
- printf("No such suppliers\n");
- }
- break;
- case 6:
- printf("Important contracts\n");
- input("Minimal contract price: ", buf, sizeof buf);
- if (sscanf(buf, INT8_FORMAT, &price) != 1) {
- printf("Bad value\n");
- continue;
- }
- input("Minimal contract quantity: ", buf, sizeof buf);
- if (sscanf(buf, "%d", &quantity) != 1) {
- printf("Bad value\n");
- continue;
- }
- if (contracts.select(q6) > 0) {
- printf("Company\tPrice\tQuantity\tDelivery\n");
- do {
- printf("%s\t" INT8_FORMAT "\t%d\t%s\n",
- suppliers.at(contracts->supplier)->company,
- contracts->price, contracts->quantity,
- contracts->delivery.asString(buf, sizeof buf,
- "%A %x"));
- } while (contracts.next());
- } else {
- printf("No such contracts\n");
- }
- break;
- case 7:
- printf("New supplier\n");
- input("Company name: ", company, sizeof company);
- input("Company location: ", address, sizeof address);
- input("Foreign company (y/n): ", buf, sizeof buf);
- supplier.company = company;
- supplier.location = address;
- supplier.foreign = (*buf == 'y');
- insert(supplier);
- break;
- case 8:
- printf("New detail\n");
- input("Detail name: ", name, sizeof name);
- input("Detail material: ", material, sizeof material);
- input("Detail weight: ", buf, sizeof buf);
- sscanf(buf, "%f", &detail.weight);
- input("Detail color: ", buf, sizeof buf);
- detail.name = name;
- detail.material = material;
- detail.color = buf;
- insert(detail);
- break;
- case 9:
- printf("New contract\n");
- db.lock(); // prevent deadlock
- input("Supplier company: ", company, sizeof company);
- if (suppliers.select(q9) == 0) {
- printf("No such supplier\n");
- continue;
- }
- input("Detail name: ", name, sizeof name);
- if (details.select(q2) == 0) {
- printf("No such detail\n");
- continue;
- } else if (details.getNumberOfRecords() != 1) {
- printf("More than one record match this pattern");
- continue;
- }
- input("Contract price: ", buf, sizeof buf);
- sscanf(buf, INT8_FORMAT, &contract.price);
- input("Contract quantity: ", buf, sizeof buf);
- sscanf(buf, "%d", &contract.quantity);
- input("Delivered after (days): ", buf, sizeof buf);
- sscanf(buf, "%d", &d);
- contract.delivery =
- dbDateTime::currentDate() + dbDateTime(24*d,0);
- contract.supplier = suppliers.currentId();
- contract.detail = details.currentId();
- insert(contract);
- break;
- case 10:
- printf("Cancel contract\n");
- input("Supplier company: ", company, sizeof company);
- input("Detail name pattern: ", name, sizeof name);
- if (updateContracts.select(q10) == 0) {
- printf("No such contracts\n");
- } else {
- updateContracts.removeAllSelected();
- // Just test rollback
- input("Really cancel contract (y/n) ? ", buf, sizeof buf);
- if (*buf != 'y') {
- printf("Not confirmed\n");
- db.rollback();
- continue;
- }
- }
- break;
- case 11:
- printf("Update contract\n");
- input("Supplier company: ", company, sizeof company);
- input("Detail name pattern: ", name, sizeof name);
- if (updateContracts.select(q10) == 0) {
- printf("No such contracts\n");
- break;
- }
- do {
- printf("Contract with company %s for shipping %d details "
- "%s for {1}quot; INT8_FORMAT " at %s\n",
- suppliers.at(updateContracts->supplier)->company,
- updateContracts->quantity,
- details.at(updateContracts->detail)->name,
- updateContracts->price,
- updateContracts->delivery.asString(buf,sizeof buf));
- input("Change this contract (y/n) ? ", buf, sizeof buf);
- if (*buf == 'y') {
- input("New contract price: ", buf, sizeof buf);
- sscanf(buf, INT8_FORMAT, &updateContracts->price);
- input("New number of details: ", buf, sizeof buf);
- sscanf(buf, "%d", &updateContracts->quantity);
- updateContracts.update();
- }
- } while (updateContracts.next());
- break;
- case 12:
- input("Do you really want to exit (y/n) ? ", buf, sizeof buf);
- if (*buf == 'y') {
- printf("Close database session\n");
- db.close();
- return EXIT_SUCCESS;
- }
- break;
- default:
- printf("Please choose menu items 1..12\n");
- continue;
- }
- printf("Press any key to continue...\n");
- getchar();
- db.commit();
- }
- } else {
- printf("failed to open database\n");
- return EXIT_FAILURE;
- }
- }
FastDB测试
最新推荐文章于 2017-05-26 10:06:39 发布