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

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

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

 

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

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

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

 

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

SDK 是s60 FP2 CW版

 

 

归属地查询模块

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

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

 

 

 数据库建立

 

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

 原始数据表

 二、对原始数据进行分析和总结不难看出,city和cardtype字段中存在大量冗余信息。例如:北京市和北京联通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中的字段number,CityName的cityid字段,CardName的cardid字段分别建立索引。相应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 Server 2016 检查更新时,错误代码8024401C 的解决方案「建议收藏」

    Windows Server 2016 检查更新时,错误代码8024401C 的解决方案「建议收藏」这个问题的核心是连接不到更新服务器,有多种解决方案(如给SoftwareDistribution改名、疑难解答等),还有一部分情况是因为IPV6导致,关闭IPV6即可解决。如果其他办法都不好用可以试试这个~WindowsServer关闭ipv6的办法:开始->运行->输入Regedit进入注册表编辑器定位到:[HKEY_…

    2022年6月11日
  • ubuntu安装搜狗输入法后黑屏_乌班图如何安装搜狗输入法

    ubuntu安装搜狗输入法后黑屏_乌班图如何安装搜狗输入法1、ubuntu系统配置systemsettings->languagesupport->install/removelanguages,在弹出的菜单中选择Chinese(simplified),点击apply2、配置输入法框架搜狗输入法是建立在fcitx框架之上的,所以要将输入法框架选择为fictx,注意:如果没有fcitx选项,那么你就需…

    2022年9月26日
  • Linux网络抓包工具tcpdump[通俗易懂]

    Linux网络抓包工具tcpdump[通俗易懂]一、tcpdump介绍tcpdump是一个运行在命令行下的抓包工具。它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包。tcpdump适用于大多数的类Unix系统操作系统(如linux,BSD等)。二、安装&用法说明2.1、安装$yum-yinstalltcpdump2.2、用法说明tcpdump采用命令行方式,它的命令格式为tcpdump[-DenNqvX][-ccount][-Ffile][-iinterfac

    2022年8月22日
  • HDMI 2.0高速电平转换芯片——LK361S20「建议收藏」

    HDMI 2.0高速电平转换芯片——LK361S20「建议收藏」LK361S20是一款DP++到HDMI2.0的高速电平转换芯片.输入支持AC或DC耦合的TMDS信号,最该速率可达6Gbps。支持引脚配置和I2C主从配置方式,外围器件精简。

    2022年8月10日
  • Nginx入门(二):常用功能配置[通俗易懂]

    Nginx入门(二):常用功能配置[通俗易懂]1.开始进入nginx的安装目录,我的是在/etc/nginx,会有一个默认的nginx.config配置文件,里面已经包含基本配置,并且设置了默认扫描/etc/nginx/conf.d/目录下所有

    2022年8月16日
  • goland 2021 激活码-激活码分享

    (goland 2021 激活码)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~4…

    2022年3月29日

发表回复

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

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