手机来电通核心模块——归属地数据库设计(Winsym原创)「建议收藏」

手机来电通核心模块——归属地数据库设计(Winsym原创)「建议收藏」说到Symbian,确实让人头痛。不仅开发平台和SDK版本众多,难以选择,而且对程序员确实要求很高,光是SymbianC++的熟悉就要花上很长时间,更麻烦的是测试和调试。模拟器只能提供一部分功能,和电话通信有关的全部要在真机上测试。很多时候,在模拟器上能跑的代码,放到真机上就不行了,这其中的心酸想必开发过得朋友深有体会。小弟我因为工程实践项目的要求,和几位嵌入式的高手一起搞了Symbian来电通项目。其实来电通项目已经有很多人做了,比较有名的是CallMaster和柳丁,但是这方面的关键技术和源码至今没有

大家好,又见面了,我是你们的朋友全栈君。

 

说到Symbian,确实让人头痛。不仅开发平台和SDK版本众多,难以选择,而且对程序员确实要求很高,光是Symbian C++的熟悉就要花上很长时间,更麻烦的是测试和调试。模拟器只能提供一部分功能,和电话通信有关的全部要在真机上测试。很多时候,在模拟器上能跑的代码,放到真机上就不行了,这其中的心酸想必开发过得朋友深有体会。

小弟我因为工程实践项目的要求,和几位嵌入式的高手一起搞了Symbian来电通项目。其实来电通项目已经有很多人做了,比较有名的是CallMaster和柳丁,但是这方面的关键技术和源码至今没有人公开,这在很大程度上增加了这个项目的难度,我们只好白手起家,也算是一次真正的项目历练(因为很多项目的关键技术和源码一般都不会给你,只有自己研究,^_^)。我在项目中负责两个核心模块的实现。一个是监听模块,另一个就是归属地查询模块。我把这一个多月的成果全部总结了一下,写成技术文章,提供给大家参考。希望想从事这方面开发的朋友能有一些借鉴作用,少走一些弯路,我就感到非常欣慰了。

以下是最核心的部分,归属地数据库的设计和实现,文中可能存在不少问题,欢迎高手们指正,向Symbian高手学习。

 

说明,我们的开发环境是Carbide C++

SDK s60 FP2 CW

 

 

归属地查询模块

归属地模块的主要功能可以划分为两个部分:一是当监听模块获取号码后,自动查找归属地数据库;二是由用户在本地自由查找,可自由选择组合(手机,固话等归属地)。但是两个功能的核心和难点都在于归属地数据库的建立,下面结合图例重点阐述。

整个数据库的建立大致分为三个步骤,见图示:

 

 

 数据库建立

 

一、原始数据的采集,整理。这一步骤主要从网上下载我国目前手机号码的归属地数据库原始数据,我们选用的是access格式的原始数据,但其只有一张表且存在大量冗余信息,原始数据截图如下:

 原始数据表

 二、对原始数据进行分析和总结不难看出,citycardtype字段中存在大量冗余信息。例如:北京市和北京联通GSM卡被存取了很多次,造成了大量的重复。所以,我们必须要设计出一种优秀的表结构格式(在满足功能的前提下,最大限度地消除冗余信息,采用数据库设计相关理论,达到3范式设计要求)。共设计四张表:

1 Phone

2 CityName

3 CardName

4 Zone

 

具体字段如下:

  

 

表名

字段名

类型

长度

说明

Phone

number

     int

 

手机号码段,主码唯一标示

 

cityid

  int

 

归属城市编号

 

cardid

  int

 

卡类型编号

CityName

cityid

int

 

归属城市编号,主码

 

cityname

text

50

归属城市名称

CardName

cardid

int

 

卡类型编号,主码

 

cardname

text

50

卡类型名称

Zone

zonecode

text

10

二级城市归属地区号 联合主码

 

zonename

text

50

二级城市归属地名称 联合主码

 

 

在实际应用过程中,查找效率和安全问题是我们必须要考虑的两个主要问题,为此我们采取了以下解决方案:

对于查找效率问题,我们采用了建立索引机制。由于Phone表中的记录的规模(大约有15万条记录),为了提高查找效率,对表Phone中的字段numberCityNamecityid字段,CardNamecardid字段分别建立索引。相应Sql语句可参考以下:

CREATE unique INDEX numIndex ON Phone(number)

CREATE unique INDEX cardidIndex ON CardName(cardid)

CREATE unique INDEX cityidIndex ON CityName(cityid)

 

对于安全问题,我们使用了S60 2nd DBMS专有的权限加密机制,相当于SQL Server数据库的登录密码,最大限度的保护数据库访问的安全和数据库设计专利。具体实现可参考以下代码片段:

// Open the contacts database using the Encrypted format

    _LIT(KPassword, “I Fu le you”);

    //useing decrypted database

    CSecurityBase* securityBase = Security::NewL ();

    securityBase->SetL (TPtrC (), KPassword); //Set the password for decryption

    //Get the key

    CSecurityDecryptBase* decryptBase = securityBase->NewDecryptL (TPtrC8 ());

    CleanupStack::PushL (securityBase);

    User::LeaveIfError ( myDatabase.Open (myDbs, KFile, TPtrC (), decryptBase,myDatabase.EReadOnly));

 

为了方便Sql脚本的提取,以上设计均在SqlServer2000数据库中完全实现。四张表之间的关系可参考以下截图:

 

 数据库表关系

 

三、最后一步是将SqlServer2000平台上的归属地数据库顺利地导入到Symbian专用的 DBMS中。这里存在两个难点,一是Symbian数据库的建立,API的使用;二是海量数据的导入。

对于第一个问题,Symbian为我们提供了两组API
1. RDbStoreDatabase 提供了专有的创建和打开数据库的接口,这样的数据库是不能共享的,数据库以文件的形式存在,所以它又称为客户端访问。
2. RDbNamedDatabase 提供了用名字和格式标识的创建和打开数据库的接口,这个类允许客户端(专有)和服务的共享数据库访问。

考虑到程序的兼容和开发的方便,我们使用的是RDbNamedDatabase,他可以轻松地创建我们想要的数据库,并利用Symbian支持的SQL子集,进行相应的建表,建立索引,查询等操作,完成相应功能需求。代码片段如下:

RFs myDbs;

    // handle for our database

    RDbNamedDatabase myDatabase;

    // we have to connect to the DBMS server first

    User::LeaveIfError( myDbs.Connect());

    myDbs.MkDirAll(KDirName);

    //handles use the cleanup stack

    CleanupClosePushL(myDbs);

    _LIT(KPassword, “I Fu le you”);

    //useing encrypted database

    CSecurityBase* securityBase = Security::NewL();

    securityBase->SetL(TPtrC(), KPassword); //Set the password for encryption

 

    // Get the key

    CSecurityEncryptBase* encryptBase = securityBase->NewEncryptL(TPtrC8());

   

    User::LeaveIfError( myDatabase.Create(myDbs,KFile,TPtrC(),encryptBase));

    //handles use the cleanup stack

    CleanupClosePushL(myDatabase);

   

    _LIT(KSQLCreatePhone, “CREATE TABLE Phone(number  integer ,cityid  unsigned smallint,cardid  unsigned smallint)”);

    _LIT(KSQLIndex,”CREATE unique INDEX numIndex ON Phone(number) “);

    _LIT(KSQLIndex1,”CREATE unique INDEX cardidIndex ON CardName(cardid) “);

    _LIT(KSQLIndex2,”CREATE unique INDEX cityidIndex ON CityName(cityid) “);

   

    _LIT(KSQLCreateCardName,”Create Table CardName(cardid unsigned smallint,cardtype varchar)”);

    _LIT(KSQLCreateCityName,”Create Table CityName(cityid unsigned smallint,cityname varchar)”);

    _LIT(KSQLCreateZone,”Create Table Zone(zonecode varchar,zonename varchar)”);

   

    //create Master tables

    User::LeaveIfError(myDatabase.Execute(KSQLCreatePhone));

    User::LeaveIfError(myDatabase.Execute(KSQLCreateCardName));

    User::LeaveIfError(myDatabase.Execute(KSQLCreateCityName));

    User::LeaveIfError(myDatabase.Execute(KSQLCreateZone));

 

    User::LeaveIfError(myDatabase.Execute(KSQLIndex));

    User::LeaveIfError(myDatabase.Execute(KSQLIndex1));

    User::LeaveIfError(myDatabase.Execute(KSQLIndex2));

 

对于第二个问题,我们采取的方法是,将所有Sql Server2000数据库各表格的数据,全部转成sql脚本,并利用Symbian提供的文件系统相关的API,读取每一行sql语句并执行,最终在电脑模拟器上生成数据库文件dbms.db。经实际操作,这种方法比在手机上生成可以大大节省数据库生成时间,效果显著。相应的sql脚本截图如下:

 

 数据sql脚本

 

读取的代码片段如下:

RFile myfile;

    //open file with RFile

    User::LeaveIfError(myfile.Open(myDbs,KFileName1,EFileRead));

    CleanupClosePushL(myfile);

   

    //Reads  single lines of text to or from a file

    txt.Set(myfile);

    TBuf16<60> textsql;

    //TDesC16 sqlRow;

    while(txt.Read(textsql) != KErrEof  )

    {

       //console->Printf(textsql);

       User::LeaveIfError(myDatabase.Execute(textsql));

       //console->Printf(_L(“/n”));

       textsql.Delete(0,textsql.Length());

    }

全部完成后,就可以利用SQL语句查询了,哈哈,好爽啊!

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/163156.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Windows 7专业版安装VS2005与WinCE6.0开发环境

    近期更新了自己的小黑从XP更新到WIN7专业版,我花了两天时间验证了下列软件安装在WIN7PRO是完全兼容的。1:2011年最新更新的SourceInsight3.50.0066版本,这个是支持W

    2021年12月26日
    40
  • IT界最伟大的十位人物「建议收藏」

    IT界最伟大的十位人物「建议收藏」美国《电脑周刊》最近评出了“IT界最伟大十位人物”,苹果公司创办人史蒂夫·乔布斯(SteveJobs)凭借着创新精神和在苹果的二次创业排名榜首。    世界首富的微软董事会主席比尔·盖茨仅排名第三位,不敌万维网(Web)发明人蒂姆·伯纳斯·李。巧合的是,三甲排名人物都是在同一年出生。    上榜的十位人物大多世界闻名,而且富可敌国。例如,盖茨已经

    2022年10月9日
    2
  • 损失函数 mse_二分类损失函数

    损失函数 mse_二分类损失函数损失函数文章目录损失函数含义:标准:常用的两种损失函数均方误差损失函数(MSE)【MeanSquareErrorLoss】交叉熵损失函数(CS)【CrossEntropyLoss】均方误差损失函数计算公式含义解释代码实现适用范围交叉熵损失函数计算公式含义解释代码实现适用范围含义:用于衡量在训练集上模型的输出与真实输出的差异标准:损失函数越小,模型输出与真实输出越相似,模型效果越好常用的两种损失函数均方误差损失函数(MSE)【MeanSquareErrorLoss】交叉

    2022年9月16日
    2
  • Tomcat报错—Invalid keystore format ,tomcat启动报错[通俗易懂]

    今天在修改了一些代码,然后重新放到服务器上,启动服务器的时候报这个错误!我就很纳闷,修改的文件里面根本就没有涉及到tomcat配置文件的内容怎么会出现这样子内容呢?想了很久也网上百度了很多,很多博客提供的解答都没有解决我的问题,然后我们主管过来看了一会,给出了指导性的建议,去看tomcat下的conf/server.xml 文件。然后逐步排查。

    2022年2月24日
    81
  • pycharm中python版本_如何在pycharm中切换python版本「建议收藏」

    pycharm中python版本_如何在pycharm中切换python版本「建议收藏」由于历史原因,现在的python主要流行的是2.5左右的版本和3.0之后的版本。在实际中,我们也会选择不同的版本,或者随时切换版本。接下来我会介绍如何再pycharm中切换python版本工具/原料pycharm软件python3.3和python2.7两个版本,并且安装好方法/步骤1打开软件会看到,这里有明显的红色提示错误。原因是当前使用的是python3.3,当执行print的时候,打印的文字…

    2022年8月28日
    0
  • python爬虫的思路总结

    python爬虫的思路总结爬虫是一个比较容易上手的技术,也许花5分钟看一篇文档就能爬取单个网页上的数据。但对于大规模爬虫,完全就是另一回事,并不是1*n这么简单,还会衍生出许多别的问题。系统的大规模爬虫流程如图所示。先检查

    2022年7月3日
    24

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号