fastdb 内存数据库使用实例

      最近一个月忙死了,没有时间发表文章.先是出差一个月,做一个电话自动应答系统.忙的焦头烂额.一个月只休息了三天.现在还晕呢.这两天终于完事了,又让我研究fastdb的使用.今天就来灌个fastdb的例子.

     首先下载fastdb的源代码,make源代码里边的makefile.windows运行makefile.mvc.编译生成fastdb.lib.如果是BCB 把所有的源代码,所有的*.cpp包含到一个library工程,然后build.就会生成一个fastdb.lib.这一块差点把我给唬了.我用BCB,先make makefile.mvc生成fastdb.lib,然后编写一个自己的测试.结果链接报错,说我的lib是coff格式,而需要omf格式,网上一查,有人说BCB中就没有办法使用coff格式的lib.我晕!最后同学提醒,直接把所有的cpp包含到一个lib工程,然后build,生成的lib可以使用了.呵呵!别的不说了.下面把例子的源代码贴出来,有兴趣的自己看吧,这几天太累了,不想写,想休息.休息去了!88!有点长,复制的时候才看出来了!等那天休息好了,解释一下里边的东西!

#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 $" 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;
    }
}

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
概述FastDB是一个高效率的内存数据库系统,具有实时性能和方便的C++接口。 FastDB并不支持客户端/服务器结构,所有使用FastDB数据库的应用程序都必须运行在同一台主机上。FastDB为具有主导读取访问模式的应用程序作了优化。通过消除数据传输的开销和使用高性能的锁工具实现了查询执行的高速度。数据库文件和使用数据库的每一个应用程序占用的虚拟内存空间相映射。所以查询在应用程序的任务中执行,不需要进行任务切换和数据传输。在FastDB中,通过原子指令来实现对数据库并发访问的同步,对查询处理几乎不增加任何开销。FastDB假设整个数据库都在当前内存中,并且在这个假设的基础上优化查询算法和结构。另外,数据库缓存管理几乎不会给FastDB增加任何开销,同时FastDB也不需要在数据库文件和缓冲池中进行数据传送。这就是为什么FastDB比将所有数据放在缓冲池中的传统数据库明显速度快的原因。   FastDB支持事务、在线备份和系统崩溃之后的自动恢复。事务提交协议基于一个影子根页算法,对数据库执行原子更新操作。恢复操作执行起来非常快,给关键应用程序提供了高效率。另外,它还取消了事务日志,提高了系统的整体性能,并且能够更加有效地使用系统资源。   FastDB是面向应用程序的数据库使用应用程序的类信息来构建数据库的表。FastDB支持自动系统赋值,只允许你在一个地方——你的应用程序的类中,改变它们的值。FastDB为从数据库中提取数据提供了一个灵活而方便的接口。使用类似于SQL的语言来书写查询语句。这些非原子字段、嵌套数组、用户自定义类型和方法、直接指向对象内部的指针等后关系性能,简化了数据库应用程序的设计,并且使得它们更加高效。   虽然FastDB的优化是基于整个数据库都存放在机器的物理内存的这个假设上的,我们依然可以将FastDB使用在那些大小超过系统物理内存数据库上。最后,标准操作系统的交换机制将会起作用。但是所有的FastDB的算法和结构的优化都是基于数据存放在内存中这个假设上的,所以数据交换的效率不会很高。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值