CLOUD COMPUTING IN NIGERIA - University of Nigeria
Transcript of CLOUD COMPUTING IN NIGERIA - University of Nigeria
i
Digitally Signed by: Content manager’s Name
DN : CN = Webmaster’s name
O = University of Nigeria, Nsukka
OU = Innovation Centre
Ugwoke Oluchi C.
FACULTY OF PHYSICAL SCIENCES
DEPARTMENT OF COMPUTER SCIENCE
CLOUD COMPUTING IN NIGERIA
NNADOZIE, CHAPMAN EZE
PG/MSC/08/49273
ii
TITLE PAGE
CLOUD COMPUTING IN NIGERIA
BY
NNADOZIE, CHAPMAN EZE
PG/MSC/08/49273
BEING A DISSERTATION PRESENTED TO THE DEPARTMENT OF COMPUTER
SCIENCE IN PARTIAL FULFILLMENT OF THE REQUIREMENTS FOR
THE AWARD OF A MASTER OF SCIENCE IN COMPUTER
SCIENCE OF THE UNIVERSITY OF NIGERIA NSUKKA
MAY, 2013
iii
CERTIFICATION PAGE
This is to certify that this dissertation has been read and certified by the undersigned
persons as having met part of the requirements for the award of Master of Science in Computer
Science of the University of Nigeria, Nsukka.
…………………………………………………. ………………………….. ……..………. PROJECT SUPERVISOR SIGNATURE DATE ………………………………………….………. …………………………… …………..… HEAD OF DEPARTMENT SIGNATURE DATE ……………………………………….….………. …………………………… …………..… DEAN OF FACULTY SIGNATURE DATE ……………………………………………...……. …………………………… ……………… EXTERNAL MODERATOR SIGNATURE DATE
iv
DEDICATION
This project work is dedicated to my splendorous wife Mrs Glory Enyidiya C. Nnadozie,
my beloved mother Mrs. Grace Ebere O. Nnadozie, my children – Zaresh and Vida, and in sweet
memory of my late father Late Mazi (Chief) Maurison Ogbonnaya Nnadozie.
v
ACKNOWLEDGEMENT
I wish to acknowledge the Almighty God and his only begotten son Jesus Christ for his
infinite mercy and divine providence.
My profound gratitude goes to my project supervisor Dr. G. A. M. Ikekeonwu whose
intelligible assistance, corrections and constructive suggestions culminated in the successful
completion of this dissertation. May God richly bless him.
My gratitude also goes to my brothers, sisters, mother, my beloved wife, and children for
the necessary moral support they gave me throughout the course of my study.
Finally, I must not forget to appreciate the Head of Department and all the lecturers of the
Department of Computer Science for their encouragements during the course of my study.
vi
LIST OF FIGURES/TABLES
FIGURE 2.1: SIX COMPUTING PARADIGM (VOAS & ZHANG, 2009) 7
FIGURE 2.2: GENERAL CLOUD AND SUBSCRIBER VIEW (BADGER ET AL., 2011) 9
FIGURE 2.3: SERVICE USERS USING DIVERSE TOOLS (SAKR, 2010) 10
FIGURE 2.4: TYPES OF VIRTUALIZATION (PETRI, 2010) 12
FIGURE 2.5: A TYPICAL DATA CENTRE (STRYER, 2010) 13
FIGURE 2.6: CATEGORIES OF CLOUD COMPUTING SERVICES (HOFER &
KARAGIAANNIS, 2011) 15
FIGURE 2.7: PUBLIC CLOUD (DUSTIN ET AL., 2010) 16
FIGURE 2.8: PRIVATE CLOUD (DUSTIN ET AL., 2010) 16
FIGURE 2.9: HYBRID CLOUD (PRASAD ET AL., 2013) 17
FIGURE 2.10: A COMMUNITY CLOUD (PRASAD ET AL., 2013) 17
FIGURE 2.11: START GOOGLE APP ENGINE DIALOG BOX 25
FIGURE 2.12: VERIFY YOUR ACCOUNT BY SMS DIALOB BOX 26
FIGURE 2.13: AUTHENTICATION CODE HAS BEEN SENT DIALOG BOX 26
FIGURE 2.14: CREATE AN APPLICATION WINDOW 27
FIGURE 2.15: SUCCESSFULLY CREATED AN APPLICATION – U ARE WELCOME! 27
FIGURE 4.1: CLOUD SHARE INTERFACE DESIGN 31
FIGURE 4.2: SERVER INTEGRATION FOR THE CLOUD SHARE 32
FIGURE 4.3: CLOUDSHARE SEARCH FLOWCHART (AUTHOR, 2013) 33
TABLE 5.1 COMPUTATION FOR TESTING H0 1 36
TABLE 5.2 COMPUTATION FOR TESTING H0 2 38
FIGURE 6.1A: XAMPP CONTROL PANEL APPLICATION WINDOW 41
vii
FIGURE 6.1B: XAMPP CONTROL PANEL WINDOW WHILE RUNNING 41
FIGURE 6.2: SERVER: LOCALHOST WINDOW 42
FIGURE 6.3A: NEW DATABASE SPHIDER CREATION WINDOW 42
FIGURE 6.3B: NEW DATABASE SPHIDER CREATION WINDOW (2) 43
FIGURE 6.4A: THE COMMAND PROMPT WINDOW 43
FIGURE 6.4B: THE COMMAND PROMPT WINDOW – SEARCHD.EXE RUNNING 44
FIGURE 6.5: CLOUD SHARE SEARCH ENGINE WINDOW 44
FIGURE 6.6A: RESULT FROM A QUERY 45
FIGURE 6.6B: RESULT FROM A QUERY (2) 45
FIGURE 6.6C: RESULT FROM A QUERY (3) 46
FIGURE 6.6D: RESULT FROM A QUERY (4) 46
FIGURE 6.7A: RESULT FROM THE INTERNET DISPLAYING A LINK CLICKED 47
FIGURE 6.7B: RESULT FROM THE INTERNET DISPLAYING A LINK CLICKED 47
FIGURE 6.7C: RESULT FROM THE INTERNET DISPLAYING A LINK CLICKED 48
FIGURE 6.7D: RESULT FROM THE INTERNET DISPLAYING A LINK CLICKED 48
FIGURE 6.7E: RESULT FROM THE INTERNET DISPLAYING A LINK CLICKED 49
FIGURE 6.7F: RESULT FROM THE INTERNET DISPLAYING A LINK CLICKED 49
FIGURE 6.7G: RESULT FROM THE INTERNET DISPLAYING A LINK CLICKED 50
viii
ABSTRACT
Cloud computing, a technology that is made possible through virtualization within
networks, represents a shift from the traditional ownership of infrastructure and other resources
by distinct organization to a more scalable pattern in which computer resources are rented online
to organizations on either as a pay-as-you-use basis or by subscription. The researcher is
motivated to undertake this study due to cloud computing growing awareness which has led to
the increasing adoption of the technology by organizations in Nigeria. This work is carried out to
investigate the impediments to cloud computing deployment in Nigeria while assessing the
enormous benefits that organizations stand to gain by adopting the technology. To ascertain this
objective, the researcher harnessed the use of structured questionnaire which was administered
on some IT staffs of organizations that either offers or uses cloud services, and retrieved same
for analysis and scientific testing in order to validate the veracity or otherwise of the postulated
null hypotheses by subjecting them to t-distribution test (see appendix ‘a’). In the context of a
SaaS, the researcher developed a search engine tagged “Cloud Share”. The design was done
using Adobe Dreamweaver while XAMPP control panel which is a browser based application is
used to process the PHP scripts and display it on the browser utilizing Sphider and Sphinx
software technologies. The application is a prototype search engine that can take a query from
the user and search through the indexed databases to outlay several results upon which the user
can click on any of them to connect to the Internet and retrieve the webpage. The viability of the
application can be enhanced by indexing more websites into its database content.
ix
TABLE OF CONTENTS
TITLE PAGE i
CERTIFICATION PAGE ii
DEDICATION iii
ACKNOWLEDGEMENT iv
ABSTRACT v
LIST OF FIGURES/TABLES vi
TABLE OF CONTENTS viii
CHAPTER 1: INTRODUCTION
1.0 INTRODUCTION 1
1.1 STATEMENT OF PROBLEM 2
1.2 OBJECTIVES OF THE STUDY 3
1.3 SIGNIFICANCE OF THE STUDY 3
1.4 RESEARCH QUESTIONS 3
1.5 RESEARCH HYPOTHESIS 4
1.6 SCOPE OF THE STUDY 4
1.7 LIMITATION OF THE STUDY 5
1.8 DEFINITION OF TECHNICAL TERMS 5
CHAPTER 2: LITERATURE REVIEW
2.0 INTRODUCTION 7
2.1 DEFINITION OF CLOUD COMPUTING 8
2.2 CHARACTERISTICS OF CLOUD COMPUTING 10
2.3 CLOUD COMPUTING TECHNOLOGY 11
2.4 CLOUD COMPUTING SERVICE AND DEPLOYMENT MODELS 14
2.5 IMPEDIMENTS TO CLOUD COMPUTING ADOPTION IN NIGERIA 18
2.6 FEASIBILITIES OF CLOUD COMPUTING IN NIGERIA 21
2.7 GOOGLE APP ENGINE 24
CHAPTER 3: METHODOLOGY AND SYSTEM ANALYSIS
3.0 INTRODUCTION 29
3.1 METHODOLOGY AND SYSTEM ANALYSIS 29
x
CHAPTER 4: SYSTEM DESIGN
4.0 INTRODUCTION 31
4.1 SYSTEM DESIGN 31
CHAPTER 5: HYPOTHESIS TESTING AND EVALUATION
5.0 INTRODUCTION 34
5.1 TESTING OF THE NULL HYPOTHESIS 35
5.1.1 TEST AND EVALUATION OF NULL HYPOTHESIS 1 36
5.1.2 TEST AND EVALUATION OF NULL HYPOTHESIS 2 37
CHAPTER 6: SYSTEM IMPLEMENTATION, SUMMARY, CONCLUSION
AND RECOMMENDATION
6.0 INTRODUCTION 40
6.1 IMPLEMENTATION AND RESULTS 40
6.2 SUMMARY 50
6.3 CONCLUSION 51
6.4 RECOMMENDATIONS 52
REFERENCES 54
APPENDIX ‘A’ 59
APPENDIX ‘B’ 61
APPENDIX ‘C’ 64
1
CHAPTER 1
INTRODUCTION
1.0 INTRODUCTION
Cloud computing, which evolved from the Internet and the web, sets the pace for
a new era of computing globally as it changes the way we work, think, do business, and
communicate. It is a practical innovation that entails the renting of common business
applications or services online by cloud computing service providers to clients on either
as a pay-as-you-go basis or by subscription.
Historically, computing started in the 1960s with mainframe data centre
computing during which IBM attempted utility computing (a pay-as-you-use strategy).
This was shortly followed by personal/minicomputer computing during which computers
became rampant and affordable. Afterwards, we entered into the period of distributed
network computing referred to as Client-Server computing. The steady growth of
computer networking across the globe then gave rise to the Internet and the web in the
1990s. Actually, the term ‘Internet’ was used to describe the growing networks which
were originally restricted to the military and research. In 1995, the Internet was
commercialized following the withdrawal of the US National Science Foundation (NSF)
in the Internet’s sole funding. This action led to the growth of the Internet and the web
globally over the years. Cloud computing birthday could be traced to August 24, 2006
when Amazon publicly test ran its Elastic Computing Cloud (EC2) with the main
intention of offering developers an infrastructure that could be hired to meet their IT
needs (T-Systems, 2011). However, the term cloud computing first became popular in
2007 following its first entry in the English Wikipedia on March 3, 2007. Today,
2
virtualization within networks has given rise to the evolution of cloud computing as it
enables a dynamic data centre to provide a pool of resources that can be exploited as
needed by clients to meet their workloads and varying business demands.
Cloud computing presents a shift of control from the traditional way of companies
owing their respective data centre/infrastructure to a resolve on resource sharing thereby
cutting down the cost of running businesses. The service could be provided using an
enterprise’s data centre, or that of a cloud provider. Major Cloud providers in Nigeria are
Microsoft, Google and International Business Machines (IBM). These companies render
cloud computing services either directly to customers/organizations or in partnership with
other Information Technology (IT) major players like Cisco, NetApp, Sunnet, Descasio,
Wyse technology, Infoware technologies, Accenture, Business Connexion, etc.
1.1 STATEMENT OF PROBLEM
Cloud computing, which is a challenging new technology, is peculiar to the
African continent and Nigeria in particular. This is borne out of the fact that Nigeria falls
short of the basic IT infrastructure requirements (such as steady electricity, and poor
internet connectivity) for the effective adoption of the technology.
Therefore, the following problem statements are intended to be addressed by this
study:-
� What are the feasibilities/constraints of cloud computing deployment by
corporations in Nigeria?
� What are the prospects of cloud computing technology in Nigeria?
� What are the prospects for user access across several classes of users?
3
� How could the providers’ responses to changes in demand be illustrated?
� Are there visible cloud computing platforms in Nigeria?
� How would a usage of a cloud computing platform be demonstrated?
1.2 OBJECTIVES OF THE STUDY
This study intends to:-
� Examine the feasibilities/constraints of cloud computing in Nigeria.
� Examine the prospects of cloud computing technology in Nigeria.
� Show the prospects for user access across several classes of users.
� Demonstrate the providers’ response to changes in demand.
� Show visible cloud computing platforms in Nigeria.
� Demonstrate a usage of a cloud computing platform.
� Develop software that works like a search engine.
1.3 SIGNIFICANCE OF THE STUDY
With the perception that cloud computing technology is still new, this study will
no doubt be useful to students, academia, individuals and organizations. This is because
this study explores the present situation and perception on the adoption of cloud
computing in Nigeria with major emphasis on its challenges and enormous benefits.
1.4 RESEARCH QUESTIONS
The following research questions have been designed for this study:
4
(1) What are the impediments/challenges you envisage that face the adoption of cloud
computing by organizations in Nigeria?
(2) What are the perceived gains, in your view, that organizations in Nigeria stand to
benefit by their adoption of cloud computing technology?
1.5 RESEARCH HYPOTHESIS
For the purpose of this study, the following null hypotheses were formulated to be
later subjected to a scientific test to verify its validity or otherwise.
H0 : There is no enormous challenge to the feasibility of cloud computing adoption by
organizations in Nigeria.
H0 : There is no enormous gain/benefit derivable by the adoption of cloud computing
by organizations in Nigeria.
1.6 SCOPE OF THE STUDY
This study comprises of six chapters. Chapter 1 is the introductory chapter
comprising of eight sections namely – introduction, statement of the problem, objectives
of the study, significance of the study, research questions, research hypothesis, scope of
the study, limitation of the study, and definition of technical terms. Chapter 2 focuses on
the literature review of computing comprising of definition of cloud computing,
characteristics of cloud computing, cloud computing technology, cloud computing
service and deployment models, and many others. Chapter 3 discusses the methodology
and system analysis while chapter 4 discusses the system design. In chapter 5, hypothesis
5
testing and evaluation is discussed using the t-distribution test to test the validity or
otherwise of the above stated null hypotheses. Finally, chapter 6 presents the system
implementation of the application developed, summary of the research findings, drawn
conclusion and the proffering of some recommendations.
1.7 LIMITATION OF THE STUDY
This study is limited to the statistical analysis of the impediments to cloud
computing deployment in Nigeria. The indigenous cloud service providers examined
consist of NetApp Technologies, Wyse Technologies, Descasio, and Infoware
Technologies while the organizations using the services include Nigerian Airspace
Management Agency (NAMA), Coscharis Group, and Electronic Test Company.
1.8 DEFINITION OF TECHNICAL TERMS
All the definitions below are according to Wikipedia encyclopaedia.
• Client:- is a piece of computer hardware or software that accesses a service made
available by a server.
• Client-Server Model:- refers to a network in which certain computers have special
dedicated tasks, providing services to other computers (in the network).
• Cloud Computing:- is a term used to refer to a model of network computing where a
program or application runs on a connected server or servers rather than on a local
computing device such as a PC, tablet or smartphone.
• Grid Computing:- is the collection of computer resources from multiple locations to
reach a common goal.
6
• Internet bot:- is a software application that runs automated tasks over the Internet.
• Server:- is a system (software and suitable computer hardware) that responds to
requests across a computer network to provide or help to provide, a network service.
• Sphider:- is a lightweight web spider and search engine written in PHP, using
MySQL, as its backend database. It is a great tool for adding search functionality to
your website or building your custom search engine.
• Sphinx:- is a free software (open source fulltext search engine) designed to provide
full text search functionality to client applications.
• Utility Computing:- is the packaging of computing resources, such as computation,
storage and services as a metered service.
• Virtualization:- refers to the act of creating a virtual (rather than actual) version of
something, including but not limited to a virtual computer hardware platform,
operating system (OS), storage device, or computer network resources.
• Web Crawler:- is an internet bot that systematically browses the world wide web,
typically for the purpose of web indexing.
• Web Search Engine:- is a software system that is designed to search for information
on the world wide web.
• XAMPP:- is a free and open source cross-platform web server solution stack
package, consisting mainly of the Apache HTTP server, MySQL database, and
interpreters for scripts written in the PHP and Perl programming languages.
7
8
CHAPTER 2
LITERATURE REVIEW
2.0 INTRODUCTION
Cloud computing is undoubtedly a technology that has come to stay as several
organizations, governments, and individuals are encouraged to key into this emerging
smart technology. However, it is worthy of note that this technology is built upon already
existing technologies. The figure below illustrates the evolutional technological trend of cloud
computing.
Figure 2.1: Six computing paradigm (Voas and Zhang, 2009).
9
In this chapter, different definitions on the subject ‘cloud computing’ will be
appraised as well as brief discussions on the characteristics, technologies, service and
deployment models of cloud computing, impediments to its adoption, its feasibility, and
the google app engine.
2.1 DEFINITION OF CLOUD COMPUTING
Several definitions have been given on cloud computing by different authors.
However, the word ‘cloud computing’ has become a popular marketing term that needs
clarification through suitable definitions. The vaguest definition of cloud computing is
the one given by Landis, et al (2011) that defines it as “computing on the Internet, as
opposed to computing on a desktop”. This definition succeeds only on recognizing the
dependency of cloud computing on the Internet. Cisco (2009) in its own attempt defines
cloud computing as “IT resources and services that are abstracted from the underlying
infrastructure and provided “on-demand” and “at scale” in a multitenant environment”.
This next definition is a fairly good attempt as it points out three (3) key attributes of
cloud computing namely – on demand, at scale, and multitenant environment. Similarly,
Accenture (2011) defines cloud computing as “the dynamic provisioning of IT
capabilities (hardware, software, or services) from third parties over a network”. This
definition acknowledges the on demand, at scale and multitenant nature of cloud
computing. Another definition is that given by T-System (2008) which states as follows –
“cloud computing is the renting of infrastructure and software, as well as bandwidth,
under defined service conditions. These components should be adjusted daily to the needs
of the customer and offered with the utmost availability and security. Included in cloud
10
computing are end-2-end service level agreements (SLAs) and use-dependent service
invoices”. This definition is very elaborate but rather too long. Furthermore, Gartner
(2009) defines cloud computing as “the style of computing in which scalable and elastic
IT-enabled capabilities are delivered as a service to external customers using internet
technologies”. This is a good attempt. However, the most generally accepted definition
comes from United States National Institute for Standard and Technology (NIST) which
defines cloud computing as “a model for enabling convenient, on-demand network access
to a shared pool of configurable computing resources (e.g. networks, servers, storage,
applications, and services) that can be rapidly provisioned and released with minimal
management effort or service provider interaction”.
Of all these definitions, one affirmed fact by most of the authors is that cloud
computing is an internet-based on-demand service built on the concept of resource
sharing. The diagram below depicts a general view of a cloud environment which
illustrates provider’s response to clients’ fluctuating changes in demand.
11
Figure 2.2: General cloud and subscriber view (Badger, et al., 2011)
The above figure simply illustrates what happens in the cloud. At every time span,
some clients initiate access requiring the cloud provider’s service while some others
terminate access releasing the resources that they once held. At the same time, some other
clients may still be well engaged with the services they require from the service provider.
The service provider has several hardware to enable it effectively manage peak service
requirement by clients. The hardware not in use is turned off to save energy and cost
thereby boosting resource efficiency. Moreover, in case of hardware failure, the cloud is
able to relinquish the use of failed hardware and utilize working ones while the provider
replaces the old failing hardware with new ones in due course in order to maintain steady
service delivery in spite of service failures and service life expirations.
2.2 CHARACTERISTICS OF CLOUD COMPUTING
12
The generally accepted basic characteristics of cloud computing is the one given
by the National Institute for Standard and Technology (NIST) which proffers five
essential characteristics as follows:
• On-demand self service. That is the ability of a client to sign up and receive
services at will from any cloud provider.
• Broad network access. This refers to the ability of a client to access the cloud
provider’s services using any standard computing device with internet
connectivity like desktop, laptop, mobile phone, etc. The figure below shows
cloud computing capability of being accessed across several classes of users.
Figure 2.3: Service users using diverse computing tools (Sakr, 2010)
• Resource pooling. Regardless of the client’s location, the cloud provider’s
computing resources are readily available and can be accessed as desired by
each client to meet up its needs.
• Rapid elasticity. Due to varying demands in workloads by different clients,
cloud computing has the ability to scale up and down to meet up each client’s
demand.
13
• Measured service. Computing resource usages by clients are transparently
recorded to reflect the actual rate of usage by each client.
2.3 CLOUD COMPUTING TECHNOLOGY
Cloud computing technology is built based on some already existing
technologies like grid computing, utility computing, virtualization, data centre
computing, the Internet, and the web. The two emerging trends that converge to bring
about cloud computing is virtualization and application provisioning (T-systems, 2011).
Virtualization is a technology that combines or divides computing resources to
present one or many operating environments using methodologies like hardware and
software partitioning or aggregation, partial or complete machine simulation,
emulation, time-sharing and others. (Nanda & Chiueh, 2009). Virtualization allows
you to do more with your existing resources by decoupling the software (like servers)
from their underlying hardware. Without virtualization hardware is committed to a
single purpose whether it’s actively used or not; and when hardware fails the entire
configuration has to be rebuilt. (CipherSpace, 2012).
Virtualization is the key support mechanism to enable infrastructure-as-a-
service, and are of five (5) types namely – application, server, network, storage, and
desktop virtualization. The figure below shows the different types of virtualization.
14
Figure 2.4: Types of Virtualization (Petri, 2010)
Network virtualization replaces the traditional Wide Area Network (WAN)
which is normally owned and managed by each organization at a very high cost.
Storage virtualization offering like Amazon S3 (Simple Storage Service) is utilized by
social networking sites like Twitter, Flickr, etc for storage of data. Other examples of
storage virtualization include Microsoft Skydrive, and Apple’s MobileMe Service.
Server virtualization enables users to subscribe for virtual servers over the Internet.
The popular offerings are coming from VMware, Microsoft and Citrix. Application
virtualization presents applications over the cloud with each application packaged in a
separate virtual box to avoid conflict between different applications and guarantee
faster installation. Desktop virtualization enables the user to use his desktop as a virtual
one. Citrix and Sun are popular in this cloud offering. (Petri, 2010). Virtualization serves a
very essential role in enabling the pooling and sharing of IT resources for outright
allocation to clients in today’s data centres.
15
Data centre, sometimes called a server farm, is a facility used to house
computer systems and associated components, such as telecommunications and storage
systems. (Stryer, 2010). They are usually built in less populated areas with cheaper
energy rates and lower probability of natural disasters. Modern data centres usually consist
of thousands of inter-connected servers. The figure below shows a typical data centre facility.
Figure 2.5: A typical data centre (Stryer, 2010).
2.4 CLOUD COMPUTING SERVICE AND DEPLOYMENT MODELS
There are essentially three service models as agreed by several authors. They are
namely – Software as a service (SaaS), Platform as a service (PaaS), and Infrastructure as
a service (IaaS) (Badger, et al., 2011, Kepes, 2011, Sun, 2009, Landis & Blacharski,
2010).
16
SaaS stands for the applications that are designed for the end user, and delivered
over the web. In otherwise, software is presented in a browser to the end users as services
that can be shared by numerous clients on demand. Examples include Google Maps,
Google Apps for Business, and Salesforce.com.
PaaS provides you with the toolkits you need to facilitate for easy developing,
deploying, and management of applications. Examples include Google App Engine,
Microsoft Azure platform, Amazon Map Reduce, Amazon Simple Storage Service.
IaaS is the delivery of compute infrastructure (network connectivity, servers, data
centre space, operating system, virtualization technology, etc) as a service. Examples
include Amazon EC2, Rackspace cloud, Google Infrastructure cloud, and Microsoft
Azure. The figure below shows the three (3) main categories of cloud computing
services.
Figure 2.6: Categories of cloud computing services (Hofer & Karagiannis,
2011).
17
Sun Microsystems (2010) categorizes cloud computing into three deployment
models namely – public clouds, private clouds and hybrid clouds. However, several
others are of the view that there are four basic deployment models namely - public,
private, hybrid, and community clouds (Badger, 2011, Petri, 2010, Wikipedia, 2011).
Public cloud is run by third parties that sell cloud services, and jobs from different
customers may be mixed together on the servers, storage systems, and other infrastructure
within the cloud. The figure below illustrates a public cloud.
Figure 2.7: Public Cloud (Dustin et al., 2010)
Private cloud is on-demand infrastructure owned by a single
customer/organization. This infrastructure may be managed by the organization or
leveraged to a third party. The figure below illustrates a private cloud.
18
Figure 2.8: Private Cloud (Dustin et al., 2010)
Hybrid cloud is a combination of two or more clouds that remain unique entities
but are bound together by a uniform technology that enables data and application
portability. The figure below illustrates a hybrid cloud.
Figure 2.9: Hybrid Cloud (Prasad et al., 2013).
19
Community cloud refers to cloud infrastructure that is shared by several
organizations and supports a specific community that has shared concerns (e.g.
educational institutions, banking sector, etc). It may be managed by the organizations.
The figure below illustrates a community cloud.
Figure 2.10: A community cloud (Prasad et al., 2013).
2.5 IMPEDIMENTS TO CLOUD COMPUTING ADOPTION IN NIGERIA
The following are some of the addressable impediments to the feasibility of
cloud computing in Nigeria.
a) Unreliable Power Supply.
Unreliable power supply in this country had been a major setback to the
introduction of cloud computing in Nigeria. The president of the Association of
Telecommunications Companies of Nigeria (ATCON) identified inadequate power
supply as the major impediment to the growth of ICT in Nigeria. According to him,
“a pursuit of the liberalization agenda of the power sector as obtained in the
20
telecommunication sector is needed to solve the protracted issue of inadequate
power supply” (Omo-Ettu, 2011).
b) Lack of political will to the genuine growth of ICT.
The Director-General of National Information Technology Development
Agency (NITDA) stated that a major challenge militating against ICT development
in Nigeria is lack of political will from the decision makers as he cited that the IT
industries are under-funded, and reiterated the need for government to invest
substantially in science and technology (Anyaye, 2010). In another development, the
president of the Institute of Software Practitioners of Nigeria (ISPON) asserted that
in 2012 ICT recorded growth but there was no adequate development. He stressed
that we need to promote the indigenous software and infrastructure companies to
ensure growth and development of ICT in the country (Uwaje, 2013).
c) Corruption.
Experts have reasoned that Nigeria is one of the most corrupt nations in the
world today. Oruame (2008) stated that “... facts are emerging on how ICT projects
have merely ended up as conduit pipes with which billions of U.S. dollars have been
siphoned from the public treasury into private bank accounts”. Therefore, if these
trends remain unchecked, it would hamper the advancement of cloud computing in
Nigeria.
d) Persistency of poor internet services.
21
The CEO of Main One Cable Company which has laid a 7,000km fibre optic
cable linking West Africa to Europe, said that the absence of robust national
backbone has led to increased cost of moving capacity around the country.
Investigation reveals that to get connected from Lagos to London costs $600 per
megabyte as against $1,100 between Lagos and Abuja due to governments’ inability
to encourage investment geared towards strengthening backbone transmission
networks. According to her, $250 million had been invested so far by the company
in building the underwater cables and constructing distribution networks. She
opined that the federal government should conduct a review of the national
backbone infrastructure, manage the country’s national frequency spectrum resource
as well as encourage infrastructure sharing amongst telecoms operators in order to
improve internet penetration in the country (Opeke, 2011).
According to Global System for Mobile Communications Association
(GSMCA), MTN, Globacom, and Airtel have only deployed 8,000km, 10,000km,
and 4,600km of fibre backbone respectively making a total of 22,600km. This
results to only 28.6% internet penetration across the country. Also, some of these
providers offer skeletal services to the populace. This must change to enable cloud
computing to work viably in Nigeria.
e) Need for backbone infrastructure sharing/general communication problems.
Infrastructure sharing by mobile operators in Nigeria will no doubt reduce both
capital expenditure (CAPEX) and operating expenditure (OPEX). Ohakwe (2011) in
his blog stated that “operators need to share costs and invest in network technologies
that support transmission of large quantities of data such as optical fibre and
22
associated technologies”. Furthermore, the landing of undersea cables like Main 1
and Glo 1 and the deployment of enhanced 3G (3G+) and 4G technologies will
amplify the increasing demand for data services which is too expensive for
individual operators to duplicate, thus requiring the need for infrastructure sharing.
Furthermore, Ikekeonwu (2011) in a paper presentation on cloud computing in
Nigeria identified several communication problems which could hamper the smooth
take off of cloud computing in Nigeria. Some of these problems range from
broadband to backbone infrastructure. He pointed out the lack of focus on the part of
ISPs as all the ISPs (MTN, Globacom, Airtel, etc) target national coverage with
none thinking of being a regional operator or provider. For instance, Visafone
concentrating on eastern region, and making sure that coverage is highly optimized,
steady and efficient. Being a regional operator would result to cost effectiveness and
improved delivery since the cost would be less. As a result of these developments,
the broadband offerings of all the service providers in Nigeria are very
frustrating/unreliable due to inadequacy of infrastructure and funding. The next
section discusses the feasibility of cloud computing in Nigeria.
2.6 FEASIBILITIES OF CLOUD COMPUTING IN NIGERIA
Cloud computing offerings globally are taking centre stage in strategizing
businesses for more profitability and cost management. Nigeria is not an exception as
major players in the service provision sector are making some giant strives and
intensifying their efforts to create more awareness and contribute substantially in helping
companies migrant to the cloud.
23
The then Director for Telecommunication Standardization Bureau at the
International Telecommunication Union (ITU) said that cloud computing saves costs for
servers and storage, offers speed and streamlines application deployment without upfront
capital. He stressed that for this reason alone many organizations are now considering
adoption of cloud computing to provide more efficient and cost effective network
services (Johnson, 2010). Similarly, the Chief executive of Sunnet Systems says that
Nigerians should take advantage of the cloud computing technology to improve and drive
their businesses to greater heights. The companies - Sunnet and IBM collaborate to
provide dynamic infrastructure technology that would ensure that ISPs and businesses
remain on track maximizing their profits and reducing infrastructural risks. (Olagunju,
2011).
Cloud computing globally has come to stay, and Nigeria cannot afford to lack
behind. In Nigeria, the major cloud solution providers (like Microsoft, IBM, and Goggle)
are working round the clock to make the technology work out. This is done by them in
two ways – either providing services directly to organizations or via partnership with
other IT/service provider firms.
Microsoft runs large scale cloud services using their data centres around the
world. Their cloud services include Microsoft Azure, Microsoft Bing and Windows Live.
Microsoft in 2012 established a private cloud environment for Wema Bank Nigeria Plc.
The bank now uses MS Exchange 2010 for email messaging, MS SharePoint Server 2010
for collaboration and MS Lync Server 2010 for instant messaging and videoconferencing.
Similarly, Nigerian Airspace Management Agency (NAMA) has improved its services by
deploying Windows Server 2012 which contains lots of features to meet up with their
24
needs thereby cutting down IT costs amidst other advantages. Furthermore, Cisco and
NetApp are examples of service providers that partner with Microsoft to offer more
robust cloud services to its clients. Today, NetApp technology is being used by the
Central Bank of Nigeria (C.B.N.) as well as the top eight (8) banks in Nigeria. Moreover,
the CBN is championing the course of creating a common Software-as-a-service (SaaS)
as well as Infrastructure-as-a-service (IaaS) for all banks in Nigeria. The development of
having a common banking application and infrastructure provided and run by a third
party (NetApp technology) gave rise to the recent change of bank account numbers to a
uniform 10-digit number, popularly referred to as Nigerian Uniform Bank Account
Number (NUBAN). It is a laudable project as cost of infrastructure and software
provisions are no longer going to be borne by the individual banks alone, but are shared
among banks to reduce the cost of doing business and boost the profitability of these
banks.
IBM is currently managing the data centre of Airtel (Nigeria) as the later had
outsourced its infrastructure in Lagos to IBM. This in turn has driven down the cost of
using the services of Airtel, and would really lead to the company’s sustainability. This
implies that if the telecommunication industries outsource their infrastructure to a major
cloud solution provider as Airtel had done, cost of rendering services would be drawn
down drastically which invariably would lead to less pay in making use of their services.
To further enhance Nigerian businesses, IBM is partnering with Sunnet technology
solution provider to offer organizations a dynamic infrastructure and cloud computing
solution that would enable organizations ensure that their infrastructural risks are well
25
managed to promote their efficiency and reduce cost of running their businesses thereby
making them more profitable than ever.
Google (Nigeria) offers lots of cloud computing services rendering enormous
support to its clients and partners. Google Apps messaging tools which include email,
calendar, and instant messaging solutions helps people to communicate and stay
connected anytime anywhere as they wish. One of its key partners in Nigeria is Descasio
Ltd which has numerous clients like Coscharis Group, Transcorp, AMCOM, etc. With
Google Apps Engine cloud platform, data is never lost and searches can easily be
performed with much data storage space available to each user anywhere anytime for
hosting documents of different formats, and for easy downloads, enabling secure real-
time collaboration among workgroups, etc. For example, Gmail provides each user with
up to 10GB inbox storage space in the cloud, which is quiet enormous.
Wyse technology, a cloud provider, offers its services to Electronic Test
Company (eTC) in the conduct of examinations in Nigeria. The services of eTC are
transforming the way examinations are conducted in Nigeria. eTC has built several
centres across the nation’s universities with plans to extend it to other examinations like
WEAC, etc. With this development, testing will be fast and reliable devoid of inherent
fraud that characterized the traditional paper-based examinations which is time
consuming when it comes to marking, scoring and computation of the results. (Wyse,
2011).
Business Connexion offerings in Nigeria include IaaS, Messaging as a service,
Sharepoint-as-a-service, and also builds private clouds for clients – government and
private establishments. (Onwuegbuchi, 2013).
26
Main One, a leading provider of internet connectivity in West Africa, is really
widening its scope geared towards providing reliable and affordable broadband internet
services across the nation. Phase 3 Telecom is partnering with Main One towards the
realization of this ambition of extending Main One’s services from Lagos to various parts
of the country (Opeke, 2013).
Industry analysts opined that Nigeria has a cloud computing market potential of
over $1 billion if broadband infrastructure bottlenecks are quickly addressed to deepen
internet penetration (Uzor, 2013).
2.7 GOOGLE APP ENGINE
Google App Engine is an example of a Platform-as-a-Service (PaaS) offering run
on Google infrastructure. The applications can be built, maintained, and stored using a
Google App Engine account. Google provides a total of ten (10) applications that can be
deployed under a single account. The basic programming language supported by Google
App Engine is Java and PHP. Before deploying any application, the user must sign-up to
a google account, and use the account to register his first application.
To successfully get your developer environment right for deploying your Google
App Engine for Java (GAEJ) application, take the following steps:
• Create a Google e-mail account.
• Sign up for Google App Engine by going to the website –
http://appengine.google.com to log in with your email account.
• Register your first application following the necessary steps.
27
• Ensure that the Java Development Kit (JDK) in your machine is properly
configured.
• Download, install, and set up Eclipse IDE version that you desire, e.g. Eclipse 3.5
Galileo release.
• Setup the GAEJ Plug-in appropriately by connecting to the appropriate website.
• Write, test and deploy your first application.
Consequently, the researcher has been able to sign up for Google App Engine
account using his Google e-mail account, and registered his first application. The steps
the researcher followed to sign up for Google App Engine are as outlined below:-
• Open a Google email account. At this instance, the researcher opened the
account – [email protected]
• Go to the website – http://appengine.google.com to sign in with your Google
account. A screen similar to this below will be displayed.
Fig. 2.11: Start Google app engine dialog box
28
• Click on the button “Create Application”. This next screen is displayed as
shown below.
Fig. 2.12: Verify Your Account by SMS dialog box
• Supply the required information and mobile number. A verification code will
immediately be sent to the mobile number.
• Enter the account code appropriately in the dialog box that appears similar to
that shown below.
29
Fig. 2.13: Authentication Code Has Been Sent dialog box
• Enter the account code and send. The figure below is loaded for you to supply
the required information.
Figure 2.14 : Create an Application window
• Supply all the information needed and click on the box beside the phrase “I
accept these terms” and then click on “Create Application” button.
30
• If all is well, the application will be automatically registered and a notification
similar to that figure below will be displayed.
Fig 2.15: Successfully Created an Application – U are welcome!
After successful registration, the next step is to deploy your application(s) using
Eclipse with Google App Engine plug-in. This requires stable power supply and robust
internet connectivity. You can always go back to your Google App Engine account to see
your application. To add more applications to your account, you simply click on the
button “Create an Application”. The full Uniform Resource Locator (URL) to access
your already created application is: http://<application-id>.appspot.com/. For example:
http://chapfirstapp.appspot.com.
31
CHAPTER 3
METHODOLOGY AND SYSTEM ANALYSIS
3.0 INTRODUCTION
This chapter describes the methodology undertaken by the researcher in realizing
the application tagged “Cloud Share”. In other words, this chapter analyses the procedure
taken by the researcher in analysing the developed system.
3.1 METHODOLOGY AND SYSTEM ANALYSIS
The methodology undertaken to realize the cloud search engine tagged “Cloud
Share” is discussed below based on the context of software development life cycle.
There are six phases in software development life cycle namely – System Planning,
System Analysis, System Design, System Development, System Implementation and
System Maintenance.
In the System Planning phase, the work identified the need for a cloud based
search engine that can serve as a SaaS. Therefore, a prototype cloud search engine
tagged Cloud Share search engine is developed.
The System Analysis phase presents a description of the functionality of the
proposed system. This means conveying the anticipated behaviour of the system to be
constructed. A set of test cases are then considered like input for the program and the
corresponding output. Having established the above, the requirement gathering and
the system specification, the functionalities of the application is then detailed and
properly installed. In analyzing data, tools like grid charts, decision tables, system
Flowcharts, etc can be used. In this dissertation, the tool used is system flowchart.
32
In the System Design phase, plans are generated for building the system using
tools like a flow chart that has already being developed to realize the actual system.
In the System Development phase, three steps are involved – acquiring software,
acquiring hardware, and testing the new system. The following software are acquired
namely – Sphinx, Sphider, XAMPP, and Adobe CS4 Integrated Development
Environment. Sphinx is software with indexing database content. By design, sphinx
database can be integrated using native protocols of say MySQL. The API
implementation was done with PHP. In this work, the Sphinx is powered using the
following commands as shown below:
C:\Sphinx\bin>searchd.
Sphider is a lightweight web crawler and search engine written in Java and PHP
using MySQL as its backend database. XAMPP is an acronym that stands for Extended
Apache MySQL, PHP and Perl. It is a control panel that integrates different types of
servers. It is a browser based application that processes the PHP scripts and displays it on
the browser. MySQL database is the connectivity database configured with the Sphider.
Adobe Dreamweaver CS4 Integrated Development Environment (IDE) was used for
developing the user interface as well as connecting to the various class libraries of the
tools listed above.
33
CHAPTER 4
SYSTEM DESIGN
4.0 INTRODUCTION
In this chapter, a proposal for the design of the user interface is outlined
identifying all necessary outputs, inputs, and processes involved in the Cloud Share
Search Engine. In addition, the researcher will also determine the application
architecture, which shows programmers how to transform the logical design into
program modules and code. In otherwise, flow charts will be used to illustrate what
the new system will do and how it will do it.
4.1 SYSTEM DESIGN
In this work, an object oriented analysis and design (OOAD) method with PHP
technology is used for the client interface to enable the connectivity of it to the browser,
and MySQL server for the database backend interface. In realizing the interface, Adobe
Dreamweaver Integrated Development Environment is utilized to develop the design as
shown below.
34
Fig. 4.1: Cloud Share Interface Design
The following figure show a local server integration flow diagram for the
developed application (Cloud Share ) when powered, while the second is a flowchart
illustrating what the software would do when a query is typed into it for a search.
Linus/Windows Server
Sphider
XAMPP
htdocs
CloudShare Sphider
Index Sphinxapi Admin Database
Settings
35
Fig. 4.2: SERVER INTEGRATION FOR THE CLOUDSHARE (Author, 2013)
36
Hooks to the Search
Server Using the
SearchAPi
Start
Starts or Open the
Search UI
Accepts the
Search input
Displays: No result Found
for the Search
Searches through the
database content for
search result
Is the search
successful?
Scroll through the
affected rows and
doubleclick on any.
Stop
Displays: The Search
results
Stop
No
Yes
37
Fig. 4.3: CloudShare Searching Flowchart (Author, 2013)
38
CHAPTER FIVE
HYPOTHESIS TESTING AND EVALUATION
5.0 INTRODUCTION
In this chapter, the researcher wishes to establish the validity or otherwise of the
above postulated null hypothesis using the t-distribution test technique. The t-test is
worked out using the formula below:-
t = X - µH0
S/√n
With d.f. = n – 1
S = ∑�Xi – X �2
�n - 1�
Where
X = Sample Mean
µH0 = Population Mean
S = Standard deviation
n = Number of samples
Xi = Sample
d.f. = Degree of freedom
The two null hypotheses for testing are re-stated below:
H0 : There is no enormous challenge to the feasibility of cloud computing adoption by
organizations in Nigeria.
39
H0 : There is no enormous gain/benefit derivable by the adoption of cloud computing
by organizations in Nigeria.
5.1 TESTING OF THE NULL HYPOTHESIS
In order to test the two (2) null hypotheses, the researcher designed two (2) broad
research questions (see appendix ‘a’) which were distributed electronically to a sample of
sixteen (16) IT staffs of some of the organizations covered. They were successfully
retrieved for computation and analysis. The average percentages of each sampled
member was computed and applied appropriately in order to test each of the null
hypotheses.
We can prove its validity or otherwise by stating thus:-
H0 : µ < µH0
Ha : µ > µH0
Where,
µ = the sample mean = X
µH0 = the postulated mean = 20
The t-distribution test is used in this testing using the above stated formula.
40
5.1.1 TEST AND EVALUATION OF NULL HYPOTHESIS 1
To find X and S, the following computations are made as shown in the table below:
Sample (n) Average Rating (X) Xi -X (Xi – X )2
1 22.22 -2.4325 5.92
2 16.67 -7.9825 63.72
3 27.78 3.1275 9.78
4 33.33 8.6775 75.30
5 22.22 -2.4325 5.92
6 16.67 -7.9825 63.72
7 11.11 -13.5425 183.40
8 27.78 3.1275 9.78
9 33.33 8.6775 75.30
10 27.78 3.1275 9.78
11 33.33 8.6775 75.30
12 16.67 -7.9825 63.72
13 22.22 -2.4325 5.92
14 27.78 3.1275 9.78
15 33.33 8.6775 75.30
16 22.22 -2.4325 5.92
394.44 738.55
TABLE 5.1: COMPUTATION FOR TESTING H0 1
41
Mean = ∑X / n = 394.44 / 16 = 24.6525 = 24.65.
S = ∑(Xi – X)2
n -1
= (738.55/15)1/2 = 7.02
Calculating t at 95% confidence interval, which is a one-tailed test;
t = X - µH0
S/√n
= 24.65 - 20
7.02/(16)1/2
= 2.65
Using the t-table for 15 degree of freedom, we reject the null hypothesis if the calculated
t is greater than the critical t,
R : t > 1.75.
Since t calculated is greater than the critical t, we reject the null hypothesis which
states that there is no enormous challenge to the feasibility of cloud computing adoption
by organizations in Nigeria.
5.1.2 TEST AND EVALUATION OF THE NULL HYPOTHESIS 2
To verify the validity or otherwise of the second null hypothesis which states that
there is no enormous gain/benefit derivable by the adoption of cloud computing by
organizations in Nigeria, the following computations were made using the table shown
below:
42
Sample (n) Average Rating (X) Xi – X (Xi – X )2
1 33.33 9.371875 87.83
2 16.67 -7.288125 53.12
3 25.00 1.041875 1.09
4 25.00 1.041875 1.09
5 16.67 -7.288125 53.12
6 8.33 -15.628125 244.24
7 25.00 1.041875 1.09
8 16.67 -7.288125 53.12
9 33.33 9.371875 87.83
10 33.33 9.371875 87.83
11 16.67 -7.288125 53.12
12 25.00 1.041875 1.09
13 33.33 9.371875 87.83
14 33.33 9.371875 87.83
15 25.00 1.041875 1.09
16 16.67 -7.288125 53.12
383.33 954.41
TABLE 5.2: COMPUTATION FOR TESTING H0 2
43
Mean = ∑X / n = 383.33 / 16 = 23.958125 = 23.96.
S = ∑(X – X)2
n -1
= (954.41/15)1/2 = 7.98
Calculating t at 95% confidence interval, which is a one-tailed test;
t = X - µH0
S/√n
= 23.96 - 20
7.98/(16)1/2
= 1.98
Using the t-table for 15 degree of freedom, we reject the null hypothesis if the calculated
t is greater than the critical t,
R : t > 1.75.
Since t calculated (1.98) is greater than the critical t (1.75), we reject the null hypothesis
which states that there is no enormous gain/benefit derivable by the adoption of cloud
computing by organizations in Nigeria.
44
CHAPTER 6
SYSTEM IMPLEMENTATION, SUMMARY, CONCLUSION AND
RECOMMENDATION
6.0 INTRODUCTION
The implementation phase combines the coding, testing and the integration of the
various software components used to construct the system. The illustration of the
implementation of the Cloud Share search engine application designed using Adobe
Dreamweaver CS4 software and powered using the XAMPP control panel, Sphinx
database and Spider crawler were discussed. Furthermore, this chapter summarizes the
findings of this dissertation, provides conclusion, and proffers some recommendations
which if harnessed would lead to the rapid adoption of cloud computing by organizations
in Nigeria.
6.1 IMPLEMENTATION AND RESULTS
To implement the Cloud Share Search Engine, the XAMPP Control Panel
Application is started (fig. 6.1a & b). This action activates the localhost (fig, 6.2). The
sphider database is then created while calling up the sphinx software to complement the
search using the command prompt (figs 6.3a, 6.3b, 6.4a, & 6.5b). The directory of the
localhost is then changed to the Cloud Share search engine to call up the interface upon
which a query at a time can be issued and the search conducted to display results (figs.
6.5, 6.6a-d). The user can then connect to any webpage of choice. (figs. 6.7a-g). Several
figures and results are displayed below.
45
Figure 6.1a: XAMPP control panel application window
Figure 6.1b: XAMPP control panel window while running.
46
Figure 6.2: Server: localhost window
Figure 6.3a: New database sphider creation window.
47
Figure 6.3b: New database sphider creation window (2).
Figure 6.4a: The command Prompt window.
48
Figure 6:4b : The command Prompt – searchd.exe running.
49
Figure 6.5: Cloud Share search engine window.
Figure 6.6a: Result from a query.
50
Fig. 6.6b: Result from a query (2).
51
Fig. 6.6c: Result from a query (3).
Fig. 6.6d: Result from a query (4).
52
Fig. 6.7a:Result from the Internet displaying a link clicked
53
Fig. 6.7b:Result from the Internet displaying a link clicked (2).
54
Fig. 6.7c:Result from the Internet displaying a link clicked (3).
55
Fig. 6.7d:Result from the Internet displaying a link clicked (4)
Figure 6.7e: Result from the Internet displaying a link clicked (5).
56
Fig. 6.7f:Result from the Internet displaying a link clicked (6)
57
Fig. 6.7g:Result from the Internet displaying a link clicked (7).
6.2 SUMMARY
This study has investigated the extent to which cloud computing has been
introduced, and also verified most of the impediments to its smooth adoption such as
unstable electricity and general communication problems alongside some benefits that
organizations stand to gain when they adopt it. The scientific tool used is the t-
distribution test. The characteristics of cloud computing are on-demand self service,
broad network access, resource pooling, rapid elasticity and measured service. Basically,
cloud computing technology is built based on already existing technologies like utility
58
computing and virtualization. Its offerings comes in three service models (- Software-as-
a-Service, Platform-as-a-Service, and Infrastructure-as-a-Service), and four deployment
models ( - Private, Public, Community, & Hybrid Clouds). The use of a cloud computing
platform – Google App Engine – was illustrated to show how an application can be
registered, deployed and accessed.
A Software-as-a-Service (SaaS) offering tagged “Cloud Share” search engine was
developed by the researcher using Adobe Dreamweaver CS4 Integrated Development
Environment and utilizing Sphinx, Sphider and XAMPP control panel programs to
implement the software.
6.3 CONCLUSION
In Nigeria, several cloud computing projects are either under study or already in
place. Foremost of these projects is the result of partnerships between international
players and African/Nigerian IT firms. Examples of such partnership include Google and
Descasio companies, Sunnet and IBM companies, etc.
Based on the research questionnaire (see appendix ‘A’), the hypothesis and the
scientific testing of the hypothesis using t-distribution test, the researcher hereby
concludes that:-
There are enormous challenges to the adoption of cloud computing by
organizations in Nigeria.
There are significant gains/benefits derivable by the adoption of cloud computing
by organizations in Nigeria.
59
6.4 RECOMMENDATIONS
The future of cloud computing in Nigeria is bright if government and all
stakeholders would put all hands on deck to ensure that these identified
challenges/impediments to its feasibility are addressed squarely. On this note, the
researcher proffers the following recommendations which if implemented would enhance
the effective adoption of cloud computing in Nigeria.
The unreliability of power supply in the country needs to be taken seriously and
resolved as soon as possible. This is because electricity is very essential especially in the
running of data centres.
There should be intensified awareness creation by cloud service providers geared
at sensitizing the public on the benefits and risks of cloud adoption by organizations in
Nigeria.
More cloud service providers are needed in the country to encourage competition
which will result to the driving down of the cost of its services. This would make the
technology more appealing to organizations.
Cloud providers in Nigeria should be able to provide free trials of their services to
their targeted organizations at a stipulated period of time to encourage them to adopt the
technology.
More data centres should be established in the country to improve the access to
cloud computing resources, reduce costs of access, increase monitoring for security
purposes, and protect local content.
There should be a strong legal framework on data protection which should be in
line with international best practices. When this is properly put in place, clarification of
60
relations between data centre managers and clients, as well as service level agreements
would be enhanced.
The implementation of the submission of a committee set up by the federal
government to develop a national broadband strategy and roadmap for Nigeria would go
a long way in helping the growth of cloud computing in Nigeria. The implementation
period is between 2013 and 2018 (a five-year period) geared towards increasing internet
and broadband penetration across the country tremendously. The intention is to ensure
that all state capitals and urban cities will have metro-fibre infrastructure installed within
the period. The key objectives of the plan as highlighted include the promotion of
pervasive broadband deployment, increasing its adoption and usage, and ensuring
availability of broadband services at affordable rates.
61
REFERENCES
Adobe (2011) Adobe Dreamweaver CS6 tutorial.
http://www.bgsu.edu/downloads/cio/file85411.pdf.
Accenture (2010) Cloud computing – opportunities for Accenture Lagos.
Accenture (2011) Application deployment Guide version 1.0.
http://www.WebserviceDeploymentEnvironmentSetupGuide_V1[1].v.pdf
Agande, B. (2013) Jonathan promises full implementation of a national broadband roadmap,
May, 31. http://www.vanguardngr.com/2013/05/jonathan-promises-full-implementation-
of-national-broadband-roadmap/.
Agbonile, U. (2010). Why Infoware. http://www.infowarelimited.com/why-infoware.
Agbaje, J. & Munro, T. (2013) Dimension Data launches cloud services in Nigeria.
http://www.vanguardngr.com/2013/03/dimension-data-launches-cloud-services-in-
Nigeria.
Anyaye, C. O. (2010) Lack of political will militates against ICT development.
http://www.dailytrust.com.ng/index.php/it-world/36513-lack-of-political-will-
militates-against-ict-development.
Badger, L., Grance, T., et al. (2011) Cloud computing synopsis and recommendations.
http://csrc.nist.gov/publications/nistpubs/800-146/sp800-146.pdf.
Chappel, D. (2008) A short introduction to cloud platforms: An enterprise-oriented view.
http://davidchappel.com/CloudPlatform.
Cisco (2009) Cisco cloud computing – Data centre strategy, architecture, and solutions. Point
of view white paper for U.S. public sector, 1st edition.
Dustin, A. et al. (2010) Cloud computing use cases white paper version 3.0 ed., cloud
62
computing use case discussion group.
Gartner (2009) Gartner IT glossary – cloud computing.
http://www.gartner.com/it-glossary/cloud computing/
Gartner (2009) Gartner Highlights for attributes of cloud computing.
http://www.gartner.com/newsroom/id/1035013.
Global Technology Industry Discussion Series (2012) Cloud Computing: Issues and Impact.
http://www.ey.com/Publication/vwLUAssets/Cloud_computing_issues,_impacts_and
_insights/$File/Cloud%20computing%20issues%20and%20impacts_14Apr11.pdf.
Hofer, C. & Karagiannis, G. (2011) Cloud computing services: taxonomy and comparison.
http://doc.utwente.nl/78444/1/Hofer11cloud.pdf.
IBM (2011) IBM bags 10-years IT deal for Bharti Airtel’s African operations
http://articles.economictimes.indiatimes.com/2011-07-13/news/29768954_1_key-
operational-functions-african-operations-high-volume-business-model.
Ikekeonwu, G.A.M. (2010) Cloud computing in Nigeria [draft]. Department of Computer
Science, University of Nigeria, Nsukka.
Infoware (2011) Our solutions. http://www.infowarelimited.com/our-solutions/.
Johnson, M. (2010) Nigeria: Cloud computing saves money – ITU.
http://allafrica.com/stories/201005270582.html.
Katkade, G. B., Ambekar, P. V. (2011) Cloud computing. http://www.kkwpoly.org/.../CIT
REVIEW_2011.pdf.
Kepes, B. (2011) Understanding the cloud computing stack SaaS, PaaS, IaaS.
http://broadcast.rackspace.com/hosting_knowledge/whitepapers/Understanding-the-
Cloud-Computing-Stack.pdf.
63
Landis, C. & Blacharski, D. (2010) Cloud computing made easy.
http://www.slidesharenet/avil205/cloud-computing-made-easy.pdf
Mell, P. & Grance, T. (2011) The NIST definition of cloud computing.
http://csrc.nist.gov/publications/nistpubs/800-145/SP800-145.pdf
Microsoft (2012) Nigerian bank grows business and reduces IT cost by 20 percent with
focussed support. http://www.microsoft.com/africa/Press/Pages/CaseStudy.aspx
?id=15.
Microsoft (2012) Nigerian Airspace Management Agency (NAMA) government agency
improves services and costs through cloud computing.
http://www.microsoft.com/africa/Press/Pages/CaseStudy.aspx?id=16
Nanda, S. & Chiueh, T. (2009) A Survey on Virtualization Technologies.
www.ecsl.cs.sunysb.edu/tr/TR179.pdf.
Opeke, F. (2011) Poor internet service persists.
http://businessdayonline.com/NG/index.php/analysis/features/30448-poor-internet-
service-persists.
Opeke, F. (2013) Main One, Phase 3 take broadband awareness to P-harcourt.
www.vanguard.com/2013/03/main-one-phase-3-tele-broadband-awareness-to-p-
harcourt/.
Ohakwe, H. O. (2011) The future of Nigerian backbone infrastructure sharing.
http://henroblog.blogspot.com/2011/3/future-of-nigerian-backbone.html?m=1
Olagunji, P. (2011) Nigeria: Sunnet, IBM promise business efficiency with dynmic
infrastructure. Daily Independence Newspaper, Issue no. 568, 19th August 2011.
64
Omo-Ettu, T. (2011) ATCON wants telecommunications success replicated in power sector.
http://www.dailytrust.com.ng/~trust/index.php/it-world/36531-atcon-wants-telecom-
success-replicated-in-power-sector.
Onwuegbuchi, C. (2013). Business Connexion boosts cloud computing in Nigeria, targets
SMEs. http://www.nigeriacommunicationsweek.com.ng/printpdf/news/business-
connexion-boosts-cloud-computing-in-nigeria-targets-smes.
Oruame, S. (2008) Corruption is killing ICT in Nigeria.
http://computerworldparaguay.com/articles/2008/11/20/corruption-killing-ict-nigeria
Path (2008) Application architecture for cloud computing.
http://www.techrepublic.com/.../945923
Petri, G. (2010) Shedding light on cloud computing.
http://www.ca.com/files/whitepapers/mpe_cl...
Sakr, M. F. (2010). Introduction to Cloud Computing.
http://www.qatar.cmu.edu/~msakr/15319- s10/lectures/lecture02.pdf
Shimba, F. (2010) Cloud computing: Strategies for cloud computing adoption. Masters
Dissertation, Dublin, School of computing, Dublin institute of technology.
Stryer, P. (2010) Understanding data centers and cloud computing.
http://viewer.media.bitpipe.com/1078177630_947/1267474882_422/WP_DC_DataCe
nterCloudComputing1.pdf
Sun (2009) Take your business to a higher level. http://www.slideshare.net/danielfc/cloud-c...
Tsai, W. et al. (2010) Service-Oriented cloud computing architecture.
http://ieeexplore.ieee.org/.../05501650.pdf.
65
T-Systems (2011) White paper cloud computing. Alternative sourcing strategy for business
ICT. http://www.t-systemsus.com/umn/uti/508260_1/blobBinary/White+Paper+Cloud
+Computing+%257B%257BPDF%252C+351+KB%257D%257D.pdf.
Uwaje, C. (2013) Nigeria’s ICT industry is still underdeveloped.
http://www.thisdaylive.com/articles/nigeria-s-ict-industry-is-still-
underdeveloped/135910/
Uzor, B. (2013) New Revenue Window for Nigerian IT firms seen in Cloud Technology.
http://www.businessdayonline.com/NG/index.php/news/76-hot-topic/50402-new-
revenue-window-for-nigerian-it-firms-seen-in-cloud-technology?format=pdf
Uzor, B. (2012) Dataflex gives customers cloud computing, 22nd February, 2012.
http://www.businessdayonline.com/NG/index.php/markets/companies-and-
market/33585-dataflex-gives-customers-cloud-computing.
Voas, J., & Zhang, J. (2009) Cloud Computing: New Wine or Just a New Bottle? IEEE
ITPro, pp.15–17.
Wikipedia (2013) Web search engine. http://en.wikipedia.org/wiki/Web_search_engine
Wyse (2011) Nigeria chooses Wyse cloud client computing to transform education system for
millions of students.
66
APPENDIX ‘A’
QUESTIONNAIRE
1.) Kindly identify with a tick (√ ) the impediments/challenges you envisage that face the
adoption of cloud computing by organizations in Nigeria by choosing one of the three (3)
options in response to each of the identifiable challenge as stated in the table below:
No. Identifiable Challenge Options
Strongly Agree
Partially Agree
Disagree
1. Unstable Electricity
2. Poor Internet Connectivity
3. Lack of Adequate Infrastructure
4. Corruption
5. Security Issues
6. Lack of Awareness
7 Lack of Strong Legal Framework
8. Infrastructure Sharing Lack (Community Cloud)
9. Lack of Effective Network Coverage Nationally
67
2.) Kindly identify with a tick (√ ) the perceived gains, in your view, that organizations stand
to benefit by their adoption of cloud computing technology.
No. Identifiable Benefits Options
Strongly Agree
Partially Agree
Disagree
1. Effective Cost Management
2. Resource Sharing
3. Focus on Core Business
4. Enhanced Business Profitability
5. Zero/Minimal Capital Expenditure
6. Reduction in IT Staff
68
APPENDIX ‘B’
TABLE
Type Description Service provider(s)
IaaS Security services IBM
Infrastructure leasing, virtualized server. Business-- Connexion, Sunnet,
Google, Microsoft, IBM, HP,
Accenture,
Broadband solutions Main One, Glo One, Phase 3.
E-mail services Glo, MTN, Airtel, Etisalat,
Google.
Google Cloud Print, LinkedIn, Amazon
EC2-virtual machine, Amazon S3.
Google, LinkedIn, Amazon.
PaaS Data storage service IBM, Microsoft.
Physical infrastructure leasing services
for business customers (SMEs)
Google, Microsoft, IBM,
Accenture.
Customer relationship manager Google, Microsoft.
Microsoft Windows Azure platform Microsoft.
SaaS Messaging-as-a-service, Sharepoint-as-
a-service, Lync-as-a-service
Business Connexion, Microsoft.
Computer-based testing and
administration
eTC and Wyse
E-mail services Google, Yahoo, Opera.
Google App Engine Google
CaaS Basic communication service Google, Microsoft, IBM, HP.
Internet e-mail, Instant messaging,
Online music, video games
Yahoo, Gmail, YouTube,
Twither, Facebook.
Microsoft connected service framework Microsoft
Website hosting services Google
NaaS Network access service offerings Google, Microsoft, IBM, HP.
Flexible and on-demand bandwidth MTN, Globacom, Airtel, Etisalat.
69
Managed internet services MTN Business.
Table: Cloud Computing Service Providers in Nigeria (Author, 2013).
APPENDIX ‘C’
CODE LISTING
CLOUD DATABASE CONNECTION
<?php
$database="sphider";
$mysql_user = "root";
$mysql_password = "";
$mysql_host = "localhost";
$mysql_table_prefix = "";
$success = mysql_pconnect ($mysql_host, $mysql_user, $mysql_password);
if (!$success)
die ("<b>Cannot connect to database, check if username, password and host are
correct.</b>");
$success = mysql_select_db ($database);
if (!$success) {
print "<b>Cannot choose database, check if database name is correct.";
die();
}
?>
70
SPHIDER DATABASE
create table sites(
site_id int auto_increment not null primary key,
url varchar(255),
title varchar(255),
short_desc text,
indexdate date,
spider_depth int default 2,
required text,
disallowed text,
can_leave_domain bool) ENGINE = MYISAM;
create table links (
link_id int auto_increment primary key not null,
site_id int,
url varchar(255) not null,
title varchar(200),
description varchar(255),
fulltxt mediumtext,
indexdate date,
size float(2),
md5sum varchar(32),
key url (url),
key md5key (md5sum),
visible int default 0,
71
level int) ENGINE = MYISAM;
create table keywords (
keyword_id int primary key not null auto_increment,
keyword varchar(30) not null,
unique kw (keyword),
key keyword (keyword(10))) ENGINE = MYISAM;
create table link_keyword0 (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keyword1 (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keyword2 (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
72
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keyword3 (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keyword4 (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keyword5 (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keyword6 (
link_id int not null,
73
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keyword7 (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keyword8 (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keyword9 (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
74
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keyworda (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keywordb (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keywordc (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keywordd (
link_id int not null,
keyword_id int not null,
75
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keyworde (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table link_keywordf (
link_id int not null,
keyword_id int not null,
weight int(3),
domain int(4),
key linkid(link_id),
key keyid(keyword_id)) ENGINE = MYISAM;
create table categories(
category_id integer not null auto_increment primary key,
category text,
parent_num integer
) ENGINE = MYISAM;
create table site_category (
site_id integer,
76
category_id integer
) ENGINE = MYISAM;
create table temp (
link varchar(255),
level integer,
id varchar (32)
) ENGINE = MYISAM;
create table pending (
site_id integer,
temp_id varchar(32),
level integer,
count integer,
num integer) ENGINE = MYISAM;
create table query_log (
query varchar(255),
time timestamp(14),
elapsed float(2),
results int,
key query_key(query)
) ENGINE = MYISAM;
create table domains (
domain_id int auto_increment primary key not null,
domain varchar(255)
77
) ENGINE = MYISAM;
78
SPHINX API INTEGRATION
<?php // // Copyright (c) 2001-2012, Andrew Aksyonoff // Copyright (c) 2008-2012, Sphinx Technologies Inc // All rights reserved // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License. You should have // received a copy of the GPL license along with this program; if you // did not, you can find it at http://www.gnu.org/ // ///////////////////////////////////////////////////////////////////////////// // PHP version of Sphinx searchd client (PHP API) ///////////////////////////////////////////////////////////////////////////// /// known searchd commands define ( "SEARCHD_COMMAND_SEARCH", 0 ); define ( "SEARCHD_COMMAND_EXCERPT", 1 ); define ( "SEARCHD_COMMAND_UPDATE", 2 ); define ( "SEARCHD_COMMAND_KEYWORDS", 3 ); define ( "SEARCHD_COMMAND_PERSIST", 4 ); define ( "SEARCHD_COMMAND_STATUS", 5 ); define ( "SEARCHD_COMMAND_FLUSHATTRS", 7 ); /// current client-side command implementation versions define ( "VER_COMMAND_SEARCH", 0x119 ); define ( "VER_COMMAND_EXCERPT", 0x104 ); define ( "VER_COMMAND_UPDATE", 0x102 ); define ( "VER_COMMAND_KEYWORDS", 0x100 ); define ( "VER_COMMAND_STATUS", 0x100 ); define ( "VER_COMMAND_QUERY", 0x100 ); define ( "VER_COMMAND_FLUSHATTRS", 0x100 ); /// known searchd status codes define ( "SEARCHD_OK", 0 ); define ( "SEARCHD_ERROR", 1 ); define ( "SEARCHD_RETRY", 2 ); define ( "SEARCHD_WARNING", 3 ); /// known match modes define ( "SPH_MATCH_ALL", 0 ); define ( "SPH_MATCH_ANY", 1 );
79
define ( "SPH_MATCH_PHRASE", 2 ); define ( "SPH_MATCH_BOOLEAN", 3 ); define ( "SPH_MATCH_EXTENDED", 4 ); define ( "SPH_MATCH_FULLSCAN", 5 ); define ( "SPH_MATCH_EXTENDED2", 6 ); // extended engine V2 (TEMPORARY, WILL BE REMOVED) /// known ranking modes (ext2 only) define ( "SPH_RANK_PROXIMITY_BM25", 0 ); ///< default mode, phrase proximity major factor and BM25 minor one define ( "SPH_RANK_BM25", 1 ); ///< statistical mode, BM25 ranking only (faster but worse quality) define ( "SPH_RANK_NONE", 2 ); ///< no ranking, all matches get a weight of 1 define ( "SPH_RANK_WORDCOUNT", 3 ); ///< simple word-count weighting, rank is a weighted sum of per-field keyword occurence counts define ( "SPH_RANK_PROXIMITY", 4 ); define ( "SPH_RANK_MATCHANY", 5 ); define ( "SPH_RANK_FIELDMASK", 6 ); define ( "SPH_RANK_SPH04", 7 ); define ( "SPH_RANK_EXPR", 8 ); define ( "SPH_RANK_TOTAL", 9 ); /// known sort modes define ( "SPH_SORT_RELEVANCE", 0 ); define ( "SPH_SORT_ATTR_DESC", 1 ); define ( "SPH_SORT_ATTR_ASC", 2 ); define ( "SPH_SORT_TIME_SEGMENTS", 3 ); define ( "SPH_SORT_EXTENDED", 4 ); define ( "SPH_SORT_EXPR", 5 ); /// known filter types define ( "SPH_FILTER_VALUES", 0 ); define ( "SPH_FILTER_RANGE", 1 ); define ( "SPH_FILTER_FLOATRANGE", 2 ); /// known attribute types define ( "SPH_ATTR_INTEGER", 1 ); define ( "SPH_ATTR_TIMESTAMP", 2 ); define ( "SPH_ATTR_ORDINAL", 3 ); define ( "SPH_ATTR_BOOL", 4 ); define ( "SPH_ATTR_FLOAT", 5 ); define ( "SPH_ATTR_BIGINT", 6 ); define ( "SPH_ATTR_STRING", 7 ); define ( "SPH_ATTR_MULTI", 0x40000001 ); define ( "SPH_ATTR_MULTI64", 0x40000002 );
80
/// known grouping functions define ( "SPH_GROUPBY_DAY", 0 ); define ( "SPH_GROUPBY_WEEK", 1 ); define ( "SPH_GROUPBY_MONTH", 2 ); define ( "SPH_GROUPBY_YEAR", 3 ); define ( "SPH_GROUPBY_ATTR", 4 ); define ( "SPH_GROUPBY_ATTRPAIR", 5 ); // important properties of PHP's integers: // - always signed (one bit short of PHP_INT_SIZE) // - conversion from string to int is saturated // - float is double // - div converts arguments to floats // - mod converts arguments to ints // the packing code below works as follows: // - when we got an int, just pack it // if performance is a problem, this is the branch users should aim for // // - otherwise, we got a number in string form // this might be due to different reasons, but we assume that this is // because it didn't fit into PHP int // // - factor the string into high and low ints for packing // - if we have bcmath, then it is used // - if we don't, we have to do it manually (this is the fun part) // // - x64 branch does factoring using ints // - x32 (ab)uses floats, since we can't fit unsigned 32-bit number into an int // // unpacking routines are pretty much the same. // - return ints if we can // - otherwise format number into a string /// pack 64-bit signed function sphPackI64 ( $v ) { assert ( is_numeric($v) ); // x64 if ( PHP_INT_SIZE>=8 ) { $v = (int)$v; return pack ( "NN", $v>>32, $v&0xFFFFFFFF ); }
81
// x32, int if ( is_int($v) ) return pack ( "NN", $v < 0 ? -1 : 0, $v ); // x32, bcmath if ( function_exists("bcmul") ) { if ( bccomp ( $v, 0 ) == -1 ) $v = bcadd ( "18446744073709551616", $v ); $h = bcdiv ( $v, "4294967296", 0 ); $l = bcmod ( $v, "4294967296" ); return pack ( "NN", (float)$h, (float)$l ); // conversion to float is intentional; int would lose 31st bit } // x32, no-bcmath $p = max(0, strlen($v) - 13); $lo = abs((float)substr($v, $p)); $hi = abs((float)substr($v, 0, $p)); $m = $lo + $hi*1316134912.0; // (10 ^ 13) % (1 << 32) = 1316134912 $q = floor($m/4294967296.0); $l = $m - ($q*4294967296.0); $h = $hi*2328.0 + $q; // (10 ^ 13) / (1 << 32) = 2328 if ( $v<0 ) { if ( $l==0 ) $h = 4294967296.0 - $h; else { $h = 4294967295.0 - $h; $l = 4294967296.0 - $l; } } return pack ( "NN", $h, $l ); } /// pack 64-bit unsigned function sphPackU64 ( $v ) { assert ( is_numeric($v) ); // x64 if ( PHP_INT_SIZE>=8 )
82
{ assert ( $v>=0 ); // x64, int if ( is_int($v) ) return pack ( "NN", $v>>32, $v&0xFFFFFFFF ); // x64, bcmath if ( function_exists("bcmul") ) { $h = bcdiv ( $v, 4294967296, 0 ); $l = bcmod ( $v, 4294967296 ); return pack ( "NN", $h, $l ); } // x64, no-bcmath $p = max ( 0, strlen($v) - 13 ); $lo = (int)substr ( $v, $p ); $hi = (int)substr ( $v, 0, $p ); $m = $lo + $hi*1316134912; $l = $m % 4294967296; $h = $hi*2328 + (int)($m/4294967296); return pack ( "NN", $h, $l ); } // x32, int if ( is_int($v) ) return pack ( "NN", 0, $v ); // x32, bcmath if ( function_exists("bcmul") ) { $h = bcdiv ( $v, "4294967296", 0 ); $l = bcmod ( $v, "4294967296" ); return pack ( "NN", (float)$h, (float)$l ); // conversion to float is intentional; int would lose 31st bit } // x32, no-bcmath $p = max(0, strlen($v) - 13); $lo = (float)substr($v, $p); $hi = (float)substr($v, 0, $p); $m = $lo + $hi*1316134912.0;
83
$q = floor($m / 4294967296.0); $l = $m - ($q * 4294967296.0); $h = $hi*2328.0 + $q; return pack ( "NN", $h, $l ); } // unpack 64-bit unsigned function sphUnpackU64 ( $v ) { list ( $hi, $lo ) = array_values ( unpack ( "N*N*", $v ) ); if ( PHP_INT_SIZE>=8 ) { if ( $hi<0 ) $hi += (1<<32); // because php 5.2.2 to 5.2.5 is totally fucked up again if ( $lo<0 ) $lo += (1<<32); // x64, int if ( $hi<=2147483647 ) return ($hi<<32) + $lo; // x64, bcmath if ( function_exists("bcmul") ) return bcadd ( $lo, bcmul ( $hi, "4294967296" ) ); // x64, no-bcmath $C = 100000; $h = ((int)($hi / $C) << 32) + (int)($lo / $C); $l = (($hi % $C) << 32) + ($lo % $C); if ( $l>$C ) { $h += (int)($l / $C); $l = $l % $C; } if ( $h==0 ) return $l; return sprintf ( "%d%05d", $h, $l ); } // x32, int if ( $hi==0 ) { if ( $lo>0 ) return $lo; return sprintf ( "%u", $lo );
84
} $hi = sprintf ( "%u", $hi ); $lo = sprintf ( "%u", $lo ); // x32, bcmath if ( function_exists("bcmul") ) return bcadd ( $lo, bcmul ( $hi, "4294967296" ) ); // x32, no-bcmath $hi = (float)$hi; $lo = (float)$lo; $q = floor($hi/10000000.0); $r = $hi - $q*10000000.0; $m = $lo + $r*4967296.0; $mq = floor($m/10000000.0); $l = $m - $mq*10000000.0; $h = $q*4294967296.0 + $r*429.0 + $mq; $h = sprintf ( "%.0f", $h ); $l = sprintf ( "%07.0f", $l ); if ( $h=="0" ) return sprintf( "%.0f", (float)$l ); return $h . $l; } // unpack 64-bit signed function sphUnpackI64 ( $v ) { list ( $hi, $lo ) = array_values ( unpack ( "N*N*", $v ) ); // x64 if ( PHP_INT_SIZE>=8 ) { if ( $hi<0 ) $hi += (1<<32); // because php 5.2.2 to 5.2.5 is totally fucked up again if ( $lo<0 ) $lo += (1<<32); return ($hi<<32) + $lo; } // x32, int if ( $hi==0 ) { if ( $lo>0 ) return $lo;
85
return sprintf ( "%u", $lo ); } // x32, int elseif ( $hi==-1 ) { if ( $lo<0 ) return $lo; return sprintf ( "%.0f", $lo - 4294967296.0 ); } $neg = ""; $c = 0; if ( $hi<0 ) { $hi = ~$hi; $lo = ~$lo; $c = 1; $neg = "-"; } $hi = sprintf ( "%u", $hi ); $lo = sprintf ( "%u", $lo ); // x32, bcmath if ( function_exists("bcmul") ) return $neg . bcadd ( bcadd ( $lo, bcmul ( $hi, "4294967296" ) ), $c ); // x32, no-bcmath $hi = (float)$hi; $lo = (float)$lo; $q = floor($hi/10000000.0); $r = $hi - $q*10000000.0; $m = $lo + $r*4967296.0; $mq = floor($m/10000000.0); $l = $m - $mq*10000000.0 + $c; $h = $q*4294967296.0 + $r*429.0 + $mq; if ( $l==10000000 ) { $l = 0; $h += 1; } $h = sprintf ( "%.0f", $h ); $l = sprintf ( "%07.0f", $l ); if ( $h=="0" )
86
return $neg . sprintf( "%.0f", (float)$l ); return $neg . $h . $l; } function sphFixUint ( $value ) { if ( PHP_INT_SIZE>=8 ) { // x64 route, workaround broken unpack() in 5.2.2+ if ( $value<0 ) $value += (1<<32); return $value; } else { // x32 route, workaround php signed/unsigned braindamage return sprintf ( "%u", $value ); } } /// sphinx searchd client class class SphinxClient { var $_host; ///< searchd host (default is "localhost") var $_port; ///< searchd port (default is 9312) var $_offset; ///< how many records to seek from result-set start (default is 0) var $_limit; ///< how many records to return from result-set starting at offset (default is 20) var $_mode; ///< query matching mode (default is SPH_MATCH_ALL) var $_weights; ///< per-field weights (default is 1 for all fields) var $_sort; ///< match sorting mode (default is SPH_SORT_RELEVANCE) var $_sortby; ///< attribute to sort by (defualt is "") var $_min_id; ///< min ID to match (default is 0, which means no limit) var $_max_id; ///< max ID to match (default is 0, which means no limit) var $_filters; ///< search filters var $_groupby; ///< group-by attribute name var $_groupfunc; ///< group-by function (to pre-process group-by attribute value with) var $_groupsort; ///< group-by sorting clause (to sort groups in result set with) var $_groupdistinct;///< group-by count-distinct attribute var $_maxmatches; ///< max matches to retrieve var $_cutoff; ///< cutoff to stop searching at (default is 0) var $_retrycount; ///< distributed retries count var $_retrydelay; ///< distributed retries delay
87
var $_anchor; ///< geographical anchor point var $_indexweights; ///< per-index weights var $_ranker; ///< ranking mode (default is SPH_RANK_PROXIMITY_BM25) var $_rankexpr; ///< ranking mode expression (for SPH_RANK_EXPR) var $_maxquerytime; ///< max query time, milliseconds (default is 0, do not limit) var $_fieldweights; ///< per-field-name weights var $_overrides; ///< per-query attribute values overrides var $_select; ///< select-list (attributes or expressions, with optional aliases) var $_error; ///< last error message var $_warning; ///< last warning message var $_connerror; ///< connection error vs remote error flag var $_reqs; ///< requests array for multi-query var $_mbenc; ///< stored mbstring encoding var $_arrayresult; ///< whether $result["matches"] should be a hash or an array var $_timeout; ///< connect timeout ///////////////////////////////////////////////////////////////////////////// // common stuff ///////////////////////////////////////////////////////////////////////////// /// create a new client object and fill defaults function SphinxClient () { // per-client-object settings $this->_host = "localhost"; $this->_port = 9312; $this->_path = false; $this->_socket = false; // per-query settings $this->_offset = 0; $this->_limit = 20; $this->_mode = SPH_MATCH_ALL; $this->_weights = array (); $this->_sort = SPH_SORT_RELEVANCE; $this->_sortby = ""; $this->_min_id = 0; $this->_max_id = 0; $this->_filters = array (); $this->_groupby = ""; $this->_groupfunc = SPH_GROUPBY_DAY; $this->_groupsort = "@group desc"; $this->_groupdistinct= ""; $this->_maxmatches = 1000;
88
$this->_cutoff = 0; $this->_retrycount = 0; $this->_retrydelay = 0; $this->_anchor = array (); $this->_indexweights= array (); $this->_ranker = SPH_RANK_PROXIMITY_BM25; $this->_rankexpr = ""; $this->_maxquerytime= 0; $this->_fieldweights= array(); $this->_overrides = array(); $this->_select = "*"; $this->_error = ""; // per-reply fields (for single-query case) $this->_warning = ""; $this->_connerror = false; $this->_reqs = array (); // requests storage (for multi-query case) $this->_mbenc = ""; $this->_arrayresult = false; $this->_timeout = 0; } function __destruct() { if ( $this->_socket !== false ) fclose ( $this->_socket ); } /// get last error message (string) function GetLastError () { return $this->_error; } /// get last warning message (string) function GetLastWarning () { return $this->_warning; } /// get last error flag (to tell network connection errors from searchd errors or broken responses) function IsConnectError() { return $this->_connerror; }
89
/// set searchd host name (string) and port (integer) function SetServer ( $host, $port = 0 ) { assert ( is_string($host) ); if ( $host[0] == '/') { $this->_path = 'unix://' . $host; return; } if ( substr ( $host, 0, 7 )=="unix://" ) { $this->_path = $host; return; } $this->_host = $host; if ( is_int($port) ) if ( $port ) $this->_port = $port; $this->_path = ''; } /// set server connection timeout (0 to remove) function SetConnectTimeout ( $timeout ) { assert ( is_numeric($timeout) ); $this->_timeout = $timeout; } function _Send ( $handle, $data, $length ) { if ( feof($handle) || fwrite ( $handle, $data, $length ) !== $length ) { $this->_error = 'connection unexpectedly closed (timed out?)'; $this->_connerror = true; return false; } return true; } ///////////////////////////////////////////////////////////////////////////// /// enter mbstring workaround mode
90
function _MBPush () { $this->_mbenc = ""; if ( ini_get ( "mbstring.func_overload" ) & 2 ) { $this->_mbenc = mb_internal_encoding(); mb_internal_encoding ( "latin1" ); } } /// leave mbstring workaround mode function _MBPop () { if ( $this->_mbenc ) mb_internal_encoding ( $this->_mbenc ); } /// connect to searchd server function _Connect () { if ( $this->_socket!==false ) { // we are in persistent connection mode, so we have a socket // however, need to check whether it's still alive if ( !@feof ( $this->_socket ) ) return $this->_socket; // force reopen $this->_socket = false; } $errno = 0; $errstr = ""; $this->_connerror = false; if ( $this->_path ) { $host = $this->_path; $port = 0; } else { $host = $this->_host; $port = $this->_port; }
91
if ( $this->_timeout<=0 ) $fp = @fsockopen ( $host, $port, $errno, $errstr ); else $fp = @fsockopen ( $host, $port, $errno, $errstr, $this->_timeout ); if ( !$fp ) { if ( $this->_path ) $location = $this->_path; else $location = "{$this->_host}:{$this->_port}"; $errstr = trim ( $errstr ); $this->_error = "connection to $location failed (errno=$errno, msg=$errstr)"; $this->_connerror = true; return false; } // send my version // this is a subtle part. we must do it before (!) reading back from searchd. // because otherwise under some conditions (reported on FreeBSD for instance) // TCP stack could throttle write-write-read pattern because of Nagle. if ( !$this->_Send ( $fp, pack ( "N", 1 ), 4 ) ) { fclose ( $fp ); $this->_error = "failed to send client protocol version"; return false; } // check version list(,$v) = unpack ( "N*", fread ( $fp, 4 ) ); $v = (int)$v; if ( $v<1 ) { fclose ( $fp ); $this->_error = "expected searchd protocol version 1+, got version '$v'"; return false; } return $fp; } /// get and check response packet from searchd server function _GetResponse ( $fp, $client_ver ) {
92
$response = ""; $len = 0; $header = fread ( $fp, 8 ); if ( strlen($header)==8 ) { list ( $status, $ver, $len ) = array_values ( unpack ( "n2a/Nb", $header ) ); $left = $len; while ( $left>0 && !feof($fp) ) { $chunk = fread ( $fp, min ( 8192, $left ) ); if ( $chunk ) { $response .= $chunk; $left -= strlen($chunk); } } } if ( $this->_socket === false ) fclose ( $fp ); // check response $read = strlen ( $response ); if ( !$response || $read!=$len ) { $this->_error = $len ? "failed to read searchd response (status=$status, ver=$ver, len=$len, read=$read)" : "received zero-sized searchd response"; return false; } // check status if ( $status==SEARCHD_WARNING ) { list(,$wlen) = unpack ( "N*", substr ( $response, 0, 4 ) ); $this->_warning = substr ( $response, 4, $wlen ); return substr ( $response, 4+$wlen ); } if ( $status==SEARCHD_ERROR ) { $this->_error = "searchd error: " . substr ( $response, 4 ); return false; } if ( $status==SEARCHD_RETRY ) {
93
$this->_error = "temporary searchd error: " . substr ( $response, 4 ); return false; } if ( $status!=SEARCHD_OK ) { $this->_error = "unknown status code '$status'"; return false; } // check version if ( $ver<$client_ver ) { $this->_warning = sprintf ( "searchd command v.%d.%d older than client's v.%d.%d, some options might not work", $ver>>8, $ver&0xff, $client_ver>>8, $client_ver&0xff ); } return $response; } ///////////////////////////////////////////////////////////////////////////// // searching ///////////////////////////////////////////////////////////////////////////// /// set offset and count into result set, /// and optionally set max-matches and cutoff limits function SetLimits ( $offset, $limit, $max=0, $cutoff=0 ) { assert ( is_int($offset) ); assert ( is_int($limit) ); assert ( $offset>=0 ); assert ( $limit>0 ); assert ( $max>=0 ); $this->_offset = $offset; $this->_limit = $limit; if ( $max>0 ) $this->_maxmatches = $max; if ( $cutoff>0 ) $this->_cutoff = $cutoff; } /// set maximum query time, in milliseconds, per-index /// integer, 0 means "do not limit" function SetMaxQueryTime ( $max ) { assert ( is_int($max) );
94
assert ( $max>=0 ); $this->_maxquerytime = $max; } /// set matching mode function SetMatchMode ( $mode ) { assert ( $mode==SPH_MATCH_ALL || $mode==SPH_MATCH_ANY || $mode==SPH_MATCH_PHRASE || $mode==SPH_MATCH_BOOLEAN || $mode==SPH_MATCH_EXTENDED || $mode==SPH_MATCH_FULLSCAN || $mode==SPH_MATCH_EXTENDED2 ); $this->_mode = $mode; } /// set ranking mode function SetRankingMode ( $ranker, $rankexpr="" ) { assert ( $ranker===0 || $ranker>=1 && $ranker<SPH_RANK_TOTAL ); assert ( is_string($rankexpr) ); $this->_ranker = $ranker; $this->_rankexpr = $rankexpr; } /// set matches sorting mode function SetSortMode ( $mode, $sortby="" ) { assert ( $mode==SPH_SORT_RELEVANCE || $mode==SPH_SORT_ATTR_DESC || $mode==SPH_SORT_ATTR_ASC || $mode==SPH_SORT_TIME_SEGMENTS || $mode==SPH_SORT_EXTENDED || $mode==SPH_SORT_EXPR ); assert ( is_string($sortby) ); assert ( $mode==SPH_SORT_RELEVANCE || strlen($sortby)>0 ); $this->_sort = $mode; $this->_sortby = $sortby; } /// bind per-field weights by order /// DEPRECATED; use SetFieldWeights() instead function SetWeights ( $weights )
95
{ assert ( is_array($weights) ); foreach ( $weights as $weight ) assert ( is_int($weight) ); $this->_weights = $weights; } /// bind per-field weights by name function SetFieldWeights ( $weights ) { assert ( is_array($weights) ); foreach ( $weights as $name=>$weight ) { assert ( is_string($name) ); assert ( is_int($weight) ); } $this->_fieldweights = $weights; } /// bind per-index weights by name function SetIndexWeights ( $weights ) { assert ( is_array($weights) ); foreach ( $weights as $index=>$weight ) { assert ( is_string($index) ); assert ( is_int($weight) ); } $this->_indexweights = $weights; } /// set IDs range to match /// only match records if document ID is beetwen $min and $max (inclusive) function SetIDRange ( $min, $max ) { assert ( is_numeric($min) ); assert ( is_numeric($max) ); assert ( $min<=$max ); $this->_min_id = $min; $this->_max_id = $max; } /// set values set filter /// only match records where $attribute value is in given set function SetFilter ( $attribute, $values, $exclude=false )
96
{ assert ( is_string($attribute) ); assert ( is_array($values) ); assert ( count($values) ); if ( is_array($values) && count($values) ) { foreach ( $values as $value ) assert ( is_numeric($value) ); $this->_filters[] = array ( "type"=>SPH_FILTER_VALUES, "attr"=>$attribute, "exclude"=>$exclude, "values"=>$values ); } } /// set range filter /// only match records if $attribute value is beetwen $min and $max (inclusive) function SetFilterRange ( $attribute, $min, $max, $exclude=false ) { assert ( is_string($attribute) ); assert ( is_numeric($min) ); assert ( is_numeric($max) ); assert ( $min<=$max ); $this->_filters[] = array ( "type"=>SPH_FILTER_RANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max ); } /// set float range filter /// only match records if $attribute value is beetwen $min and $max (inclusive) function SetFilterFloatRange ( $attribute, $min, $max, $exclude=false ) { assert ( is_string($attribute) ); assert ( is_float($min) ); assert ( is_float($max) ); assert ( $min<=$max ); $this->_filters[] = array ( "type"=>SPH_FILTER_FLOATRANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max ); } /// setup anchor point for geosphere distance calculations /// required to use @geodist in filters and sorting /// latitude and longitude must be in radians function SetGeoAnchor ( $attrlat, $attrlong, $lat, $long ) {
97
assert ( is_string($attrlat) ); assert ( is_string($attrlong) ); assert ( is_float($lat) ); assert ( is_float($long) ); $this->_anchor = array ( "attrlat"=>$attrlat, "attrlong"=>$attrlong, "lat"=>$lat, "long"=>$long ); } /// set grouping attribute and function function SetGroupBy ( $attribute, $func, $groupsort="@group desc" ) { assert ( is_string($attribute) ); assert ( is_string($groupsort) ); assert ( $func==SPH_GROUPBY_DAY || $func==SPH_GROUPBY_WEEK || $func==SPH_GROUPBY_MONTH || $func==SPH_GROUPBY_YEAR || $func==SPH_GROUPBY_ATTR || $func==SPH_GROUPBY_ATTRPAIR ); $this->_groupby = $attribute; $this->_groupfunc = $func; $this->_groupsort = $groupsort; } /// set count-distinct attribute for group-by queries function SetGroupDistinct ( $attribute ) { assert ( is_string($attribute) ); $this->_groupdistinct = $attribute; } /// set distributed retries count and delay function SetRetries ( $count, $delay=0 ) { assert ( is_int($count) && $count>=0 ); assert ( is_int($delay) && $delay>=0 ); $this->_retrycount = $count; $this->_retrydelay = $delay; } /// set result set format (hash or array; hash by default) /// PHP specific; needed for group-by-MVA result sets that may contain duplicate IDs function SetArrayResult ( $arrayresult ) {
98
assert ( is_bool($arrayresult) ); $this->_arrayresult = $arrayresult; } /// set attribute values override /// there can be only one override per attribute /// $values must be a hash that maps document IDs to attribute values function SetOverride ( $attrname, $attrtype, $values ) { assert ( is_string ( $attrname ) ); assert ( in_array ( $attrtype, array ( SPH_ATTR_INTEGER, SPH_ATTR_TIMESTAMP, SPH_ATTR_BOOL, SPH_ATTR_FLOAT, SPH_ATTR_BIGINT ) ) ); assert ( is_array ( $values ) ); $this->_overrides[$attrname] = array ( "attr"=>$attrname, "type"=>$attrtype, "values"=>$values ); } /// set select-list (attributes or expressions), SQL-like syntax function SetSelect ( $select ) { assert ( is_string ( $select ) ); $this->_select = $select; } ////////////////////////////////////////////////////////////////////////////// /// clear all filters (for multi-queries) function ResetFilters () { $this->_filters = array(); $this->_anchor = array(); } /// clear groupby settings (for multi-queries) function ResetGroupBy () { $this->_groupby = ""; $this->_groupfunc = SPH_GROUPBY_DAY; $this->_groupsort = "@group desc"; $this->_groupdistinct= ""; } /// clear all attribute value overrides (for multi-queries) function ResetOverrides ()
99
{ $this->_overrides = array (); } ////////////////////////////////////////////////////////////////////////////// /// connect to searchd server, run given search query through given indexes, /// and return the search results function Query ( $query, $index="*", $comment="" ) { assert ( empty($this->_reqs) ); $this->AddQuery ( $query, $index, $comment ); $results = $this->RunQueries (); $this->_reqs = array (); // just in case it failed too early if ( !is_array($results) ) return false; // probably network error; error message should be already filled $this->_error = $results[0]["error"]; $this->_warning = $results[0]["warning"]; if ( $results[0]["status"]==SEARCHD_ERROR ) return false; else return $results[0]; } /// helper to pack floats in network byte order function _PackFloat ( $f ) { $t1 = pack ( "f", $f ); // machine order list(,$t2) = unpack ( "L*", $t1 ); // int in machine order return pack ( "N", $t2 ); } /// add query to multi-query batch /// returns index into results array from RunQueries() call function AddQuery ( $query, $index="*", $comment="" ) { // mbstring workaround $this->_MBPush (); // build request $req = pack ( "NNNN", $this->_offset, $this->_limit, $this->_mode, $this->_ranker );
100
if ( $this->_ranker==SPH_RANK_EXPR ) $req .= pack ( "N", strlen($this->_rankexpr) ) . $this->_rankexpr; $req .= pack ( "N", $this->_sort ); // (deprecated) sort mode $req .= pack ( "N", strlen($this->_sortby) ) . $this->_sortby; $req .= pack ( "N", strlen($query) ) . $query; // query itself $req .= pack ( "N", count($this->_weights) ); // weights foreach ( $this->_weights as $weight ) $req .= pack ( "N", (int)$weight ); $req .= pack ( "N", strlen($index) ) . $index; // indexes $req .= pack ( "N", 1 ); // id64 range marker $req .= sphPackU64 ( $this->_min_id ) . sphPackU64 ( $this->_max_id ); // id64 range // filters $req .= pack ( "N", count($this->_filters) ); foreach ( $this->_filters as $filter ) { $req .= pack ( "N", strlen($filter["attr"]) ) . $filter["attr"]; $req .= pack ( "N", $filter["type"] ); switch ( $filter["type"] ) { case SPH_FILTER_VALUES: $req .= pack ( "N", count($filter["values"]) ); foreach ( $filter["values"] as $value ) $req .= sphPackI64 ( $value ); break; case SPH_FILTER_RANGE: $req .= sphPackI64 ( $filter["min"] ) . sphPackI64 ( $filter["max"] ); break; case SPH_FILTER_FLOATRANGE: $req .= $this->_PackFloat ( $filter["min"] ) . $this->_PackFloat ( $filter["max"] ); break; default: assert ( 0 && "internal error: unhandled filter type" ); } $req .= pack ( "N", $filter["exclude"] ); } // group-by clause, max-matches count, group-sort clause, cutoff count $req .= pack ( "NN", $this->_groupfunc, strlen($this->_groupby) ) . $this->_groupby;
101
$req .= pack ( "N", $this->_maxmatches ); $req .= pack ( "N", strlen($this->_groupsort) ) . $this->_groupsort; $req .= pack ( "NNN", $this->_cutoff, $this->_retrycount, $this->_retrydelay ); $req .= pack ( "N", strlen($this->_groupdistinct) ) . $this->_groupdistinct; // anchor point if ( empty($this->_anchor) ) { $req .= pack ( "N", 0 ); } else { $a =& $this->_anchor; $req .= pack ( "N", 1 ); $req .= pack ( "N", strlen($a["attrlat"]) ) . $a["attrlat"]; $req .= pack ( "N", strlen($a["attrlong"]) ) . $a["attrlong"]; $req .= $this->_PackFloat ( $a["lat"] ) . $this->_PackFloat ( $a["long"] ); } // per-index weights $req .= pack ( "N", count($this->_indexweights) ); foreach ( $this->_indexweights as $idx=>$weight ) $req .= pack ( "N", strlen($idx) ) . $idx . pack ( "N", $weight ); // max query time $req .= pack ( "N", $this->_maxquerytime ); // per-field weights $req .= pack ( "N", count($this->_fieldweights) ); foreach ( $this->_fieldweights as $field=>$weight ) $req .= pack ( "N", strlen($field) ) . $field . pack ( "N", $weight ); // comment $req .= pack ( "N", strlen($comment) ) . $comment; // attribute overrides $req .= pack ( "N", count($this->_overrides) ); foreach ( $this->_overrides as $key => $entry ) { $req .= pack ( "N", strlen($entry["attr"]) ) . $entry["attr"]; $req .= pack ( "NN", $entry["type"], count($entry["values"]) ); foreach ( $entry["values"] as $id=>$val ) { assert ( is_numeric($id) ); assert ( is_numeric($val) ); $req .= sphPackU64 ( $id );
102
switch ( $entry["type"] ) { case SPH_ATTR_FLOAT: $req .= $this->_PackFloat ( $val ); break; case SPH_ATTR_BIGINT: $req .= sphPackI64 ( $val ); break; default: $req .= pack ( "N", $val ); break; } } } // select-list $req .= pack ( "N", strlen($this->_select) ) . $this->_select; // mbstring workaround $this->_MBPop (); // store request to requests array $this->_reqs[] = $req; return count($this->_reqs)-1; } /// connect to searchd, run queries batch, and return an array of result sets function RunQueries () { if ( empty($this->_reqs) ) { $this->_error = "no queries defined, issue AddQuery() first"; return false; } // mbstring workaround $this->_MBPush (); if (!( $fp = $this->_Connect() )) { $this->_MBPop (); return false; } // send query, get response $nreqs = count($this->_reqs); $req = join ( "", $this->_reqs ); $len = 8+strlen($req);
103
$req = pack ( "nnNNN", SEARCHD_COMMAND_SEARCH, VER_COMMAND_SEARCH, $len, 0, $nreqs ) . $req; // add header if ( !( $this->_Send ( $fp, $req, $len+8 ) ) || !( $response = $this->_GetResponse ( $fp, VER_COMMAND_SEARCH ) ) ) { $this->_MBPop (); return false; } // query sent ok; we can reset reqs now $this->_reqs = array (); // parse and return response return $this->_ParseSearchResponse ( $response, $nreqs ); } /// parse and return search query (or queries) response function _ParseSearchResponse ( $response, $nreqs ) { $p = 0; // current position $max = strlen($response); // max position for checks, to protect against broken responses $results = array (); for ( $ires=0; $ires<$nreqs && $p<$max; $ires++ ) { $results[] = array(); $result =& $results[$ires]; $result["error"] = ""; $result["warning"] = ""; // extract status list(,$status) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; $result["status"] = $status; if ( $status!=SEARCHD_OK ) { list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; $message = substr ( $response, $p, $len ); $p += $len; if ( $status==SEARCHD_WARNING ) { $result["warning"] = $message; } else
104
{ $result["error"] = $message; continue; } } // read schema $fields = array (); $attrs = array (); list(,$nfields) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; while ( $nfields-->0 && $p<$max ) { list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; $fields[] = substr ( $response, $p, $len ); $p += $len; } $result["fields"] = $fields; list(,$nattrs) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; while ( $nattrs-->0 && $p<$max ) { list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; $attr = substr ( $response, $p, $len ); $p += $len; list(,$type) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; $attrs[$attr] = $type; } $result["attrs"] = $attrs; // read match count list(,$count) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; list(,$id64) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; // read matches $idx = -1; while ( $count-->0 && $p<$max ) { // index into result array $idx++; // parse document id and weight if ( $id64 ) { $doc = sphUnpackU64 ( substr ( $response, $p, 8 ) ); $p += 8; list(,$weight) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
105
} else { list ( $doc, $weight ) = array_values ( unpack ( "N*N*", substr ( $response, $p, 8 ) ) ); $p += 8; $doc = sphFixUint($doc); } $weight = sprintf ( "%u", $weight ); // create match entry if ( $this->_arrayresult ) $result["matches"][$idx] = array ( "id"=>$doc, "weight"=>$weight ); else $result["matches"][$doc]["weight"] = $weight; // parse and create attributes $attrvals = array (); foreach ( $attrs as $attr=>$type ) { // handle 64bit ints if ( $type==SPH_ATTR_BIGINT ) { $attrvals[$attr] = sphUnpackI64 ( substr ( $response, $p, 8 ) ); $p += 8; continue; } // handle floats if ( $type==SPH_ATTR_FLOAT ) { list(,$uval) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; list(,$fval) = unpack ( "f*", pack ( "L", $uval ) ); $attrvals[$attr] = $fval; continue; } // handle everything else as unsigned ints list(,$val) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; if ( $type==SPH_ATTR_MULTI ) { $attrvals[$attr] = array (); $nvalues = $val;
106
while ( $nvalues-->0 && $p<$max ) { list(,$val) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; $attrvals[$attr][] = sphFixUint($val); } } else if ( $type==SPH_ATTR_MULTI64 ) { $attrvals[$attr] = array (); $nvalues = $val; while ( $nvalues>0 && $p<$max ) { $attrvals[$attr][] = sphUnpackI64 ( substr ( $response, $p, 8 ) ); $p += 8; $nvalues -= 2; } } else if ( $type==SPH_ATTR_STRING ) { $attrvals[$attr] = substr ( $response, $p, $val ); $p += $val; } else { $attrvals[$attr] = sphFixUint($val); } } if ( $this->_arrayresult ) $result["matches"][$idx]["attrs"] = $attrvals; else $result["matches"][$doc]["attrs"] = $attrvals; } list ( $total, $total_found, $msecs, $words ) = array_values ( unpack ( "N*N*N*N*", substr ( $response, $p, 16 ) ) ); $result["total"] = sprintf ( "%u", $total ); $result["total_found"] = sprintf ( "%u", $total_found ); $result["time"] = sprintf ( "%.3f", $msecs/1000 ); $p += 16; while ( $words-->0 && $p<$max ) { list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; $word = substr ( $response, $p, $len ); $p += $len; list ( $docs, $hits ) = array_values ( unpack ( "N*N*", substr ( $response, $p, 8 ) ) ); $p += 8;
107
$result["words"][$word] = array ( "docs"=>sprintf ( "%u", $docs ), "hits"=>sprintf ( "%u", $hits ) ); } } $this->_MBPop (); return $results; } ///////////////////////////////////////////////////////////////////////////// // excerpts generation ///////////////////////////////////////////////////////////////////////////// /// connect to searchd server, and generate exceprts (snippets) /// of given documents for given query. returns false on failure, /// an array of snippets on success function BuildExcerpts ( $docs, $index, $words, $opts=array() ) { assert ( is_array($docs) ); assert ( is_string($index) ); assert ( is_string($words) ); assert ( is_array($opts) ); $this->_MBPush (); if (!( $fp = $this->_Connect() )) { $this->_MBPop(); return false; } ///////////////// // fixup options ///////////////// if ( !isset($opts["before_match"]) ) $opts["before_match"] = "<b>"; if ( !isset($opts["after_match"]) ) $opts["after_match"] = "</b>"; if ( !isset($opts["chunk_separator"]) ) $opts["chunk_separator"] = " ... "; if ( !isset($opts["limit"]) ) $opts["limit"] = 256; if ( !isset($opts["limit_passages"]) ) $opts["limit_passages"] = 0; if ( !isset($opts["limit_words"]) ) $opts["limit_words"] = 0; if ( !isset($opts["around"]) ) $opts["around"] = 5; if ( !isset($opts["exact_phrase"]) ) $opts["exact_phrase"] = false;
108
if ( !isset($opts["single_passage"]) ) $opts["single_passage"] = false; if ( !isset($opts["use_boundaries"]) ) $opts["use_boundaries"] = false; if ( !isset($opts["weight_order"]) ) $opts["weight_order"] = false; if ( !isset($opts["query_mode"]) ) $opts["query_mode"] = false; if ( !isset($opts["force_all_words"]) ) $opts["force_all_words"] = false; if ( !isset($opts["start_passage_id"]) ) $opts["start_passage_id"] = 1; if ( !isset($opts["load_files"]) ) $opts["load_files"] = false; if ( !isset($opts["html_strip_mode"]) ) $opts["html_strip_mode"] = "index"; if ( !isset($opts["allow_empty"]) ) $opts["allow_empty"] = false; if ( !isset($opts["passage_boundary"]) ) $opts["passage_boundary"] = "none"; if ( !isset($opts["emit_zones"]) ) $opts["emit_zones"] = false; if ( !isset($opts["load_files_scattered"]) ) $opts["load_files_scattered"] = false; ///////////////// // build request ///////////////// // v.1.2 req $flags = 1; // remove spaces if ( $opts["exact_phrase"] ) $flags |= 2; if ( $opts["single_passage"] ) $flags |= 4; if ( $opts["use_boundaries"] ) $flags |= 8; if ( $opts["weight_order"] ) $flags |= 16; if ( $opts["query_mode"] ) $flags |= 32; if ( $opts["force_all_words"] ) $flags |= 64; if ( $opts["load_files"] ) $flags |= 128; if ( $opts["allow_empty"] ) $flags |= 256; if ( $opts["emit_zones"] ) $flags |= 512; if ( $opts["load_files_scattered"] ) $flags |= 1024; $req = pack ( "NN", 0, $flags ); // mode=0, flags=$flags $req .= pack ( "N", strlen($index) ) . $index; // req index $req .= pack ( "N", strlen($words) ) . $words; // req words // options $req .= pack ( "N", strlen($opts["before_match"]) ) . $opts["before_match"]; $req .= pack ( "N", strlen($opts["after_match"]) ) . $opts["after_match"]; $req .= pack ( "N", strlen($opts["chunk_separator"]) ) . $opts["chunk_separator"]; $req .= pack ( "NN", (int)$opts["limit"], (int)$opts["around"] ); $req .= pack ( "NNN", (int)$opts["limit_passages"], (int)$opts["limit_words"], (int)$opts["start_passage_id"] ); // v.1.2
109
$req .= pack ( "N", strlen($opts["html_strip_mode"]) ) . $opts["html_strip_mode"]; $req .= pack ( "N", strlen($opts["passage_boundary"]) ) . $opts["passage_boundary"]; // documents $req .= pack ( "N", count($docs) ); foreach ( $docs as $doc ) { assert ( is_string($doc) ); $req .= pack ( "N", strlen($doc) ) . $doc; } //////////////////////////// // send query, get response //////////////////////////// $len = strlen($req); $req = pack ( "nnN", SEARCHD_COMMAND_EXCERPT, VER_COMMAND_EXCERPT, $len ) . $req; // add header if ( !( $this->_Send ( $fp, $req, $len+8 ) ) || !( $response = $this->_GetResponse ( $fp, VER_COMMAND_EXCERPT ) ) ) { $this->_MBPop (); return false; } ////////////////// // parse response ////////////////// $pos = 0; $res = array (); $rlen = strlen($response); for ( $i=0; $i<count($docs); $i++ ) { list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) ); $pos += 4; if ( $pos+$len > $rlen ) { $this->_error = "incomplete reply"; $this->_MBPop (); return false; }
110
$res[] = $len ? substr ( $response, $pos, $len ) : ""; $pos += $len; } $this->_MBPop (); return $res; } ///////////////////////////////////////////////////////////////////////////// // keyword generation ///////////////////////////////////////////////////////////////////////////// /// connect to searchd server, and generate keyword list for a given query /// returns false on failure, /// an array of words on success function BuildKeywords ( $query, $index, $hits ) { assert ( is_string($query) ); assert ( is_string($index) ); assert ( is_bool($hits) ); $this->_MBPush (); if (!( $fp = $this->_Connect() )) { $this->_MBPop(); return false; } ///////////////// // build request ///////////////// // v.1.0 req $req = pack ( "N", strlen($query) ) . $query; // req query $req .= pack ( "N", strlen($index) ) . $index; // req index $req .= pack ( "N", (int)$hits ); //////////////////////////// // send query, get response //////////////////////////// $len = strlen($req); $req = pack ( "nnN", SEARCHD_COMMAND_KEYWORDS, VER_COMMAND_KEYWORDS, $len ) . $req; // add header if ( !( $this->_Send ( $fp, $req, $len+8 ) ) ||
111
!( $response = $this->_GetResponse ( $fp, VER_COMMAND_KEYWORDS ) ) ) { $this->_MBPop (); return false; } ////////////////// // parse response ////////////////// $pos = 0; $res = array (); $rlen = strlen($response); list(,$nwords) = unpack ( "N*", substr ( $response, $pos, 4 ) ); $pos += 4; for ( $i=0; $i<$nwords; $i++ ) { list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) ); $pos += 4; $tokenized = $len ? substr ( $response, $pos, $len ) : ""; $pos += $len; list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) ); $pos += 4; $normalized = $len ? substr ( $response, $pos, $len ) : ""; $pos += $len; $res[] = array ( "tokenized"=>$tokenized, "normalized"=>$normalized ); if ( $hits ) { list($ndocs,$nhits) = array_values ( unpack ( "N*N*", substr ( $response, $pos, 8 ) ) ); $pos += 8; $res [$i]["docs"] = $ndocs; $res [$i]["hits"] = $nhits; } if ( $pos > $rlen ) { $this->_error = "incomplete reply"; $this->_MBPop (); return false; } } $this->_MBPop ();
112
return $res; } function EscapeString ( $string ) { $from = array ( '\\', '(',')','|','-','!','@','~','"','&', '/', '^', '$', '=' ); $to = array ( '\\\\', '\(','\)','\|','\-','\!','\@','\~','\"', '\&', '\/', '\^', '\$', '\=' ); return str_replace ( $from, $to, $string ); } ///////////////////////////////////////////////////////////////////////////// // attribute updates ///////////////////////////////////////////////////////////////////////////// /// batch update given attributes in given rows in given indexes /// returns amount of updated documents (0 or more) on success, or -1 on failure function UpdateAttributes ( $index, $attrs, $values, $mva=false ) { // verify everything assert ( is_string($index) ); assert ( is_bool($mva) ); assert ( is_array($attrs) ); foreach ( $attrs as $attr ) assert ( is_string($attr) ); assert ( is_array($values) ); foreach ( $values as $id=>$entry ) { assert ( is_numeric($id) ); assert ( is_array($entry) ); assert ( count($entry)==count($attrs) ); foreach ( $entry as $v ) { if ( $mva ) { assert ( is_array($v) ); foreach ( $v as $vv ) assert ( is_int($vv) ); } else assert ( is_int($v) ); } } // build request
113
$this->_MBPush (); $req = pack ( "N", strlen($index) ) . $index; $req .= pack ( "N", count($attrs) ); foreach ( $attrs as $attr ) { $req .= pack ( "N", strlen($attr) ) . $attr; $req .= pack ( "N", $mva ? 1 : 0 ); } $req .= pack ( "N", count($values) ); foreach ( $values as $id=>$entry ) { $req .= sphPackU64 ( $id ); foreach ( $entry as $v ) { $req .= pack ( "N", $mva ? count($v) : $v ); if ( $mva ) foreach ( $v as $vv ) $req .= pack ( "N", $vv ); } } // connect, send query, get response if (!( $fp = $this->_Connect() )) { $this->_MBPop (); return -1; } $len = strlen($req); $req = pack ( "nnN", SEARCHD_COMMAND_UPDATE, VER_COMMAND_UPDATE, $len ) . $req; // add header if ( !$this->_Send ( $fp, $req, $len+8 ) ) { $this->_MBPop (); return -1; } if (!( $response = $this->_GetResponse ( $fp, VER_COMMAND_UPDATE ) )) { $this->_MBPop (); return -1; } // parse response
114
list(,$updated) = unpack ( "N*", substr ( $response, 0, 4 ) ); $this->_MBPop (); return $updated; } ///////////////////////////////////////////////////////////////////////////// // persistent connections ///////////////////////////////////////////////////////////////////////////// function Open() { if ( $this->_socket !== false ) { $this->_error = 'already connected'; return false; } if ( !$fp = $this->_Connect() ) return false; // command, command version = 0, body length = 4, body = 1 $req = pack ( "nnNN", SEARCHD_COMMAND_PERSIST, 0, 4, 1 ); if ( !$this->_Send ( $fp, $req, 12 ) ) return false; $this->_socket = $fp; return true; } function Close() { if ( $this->_socket === false ) { $this->_error = 'not connected'; return false; } fclose ( $this->_socket ); $this->_socket = false; return true; } ////////////////////////////////////////////////////////////////////////// // status //////////////////////////////////////////////////////////////////////////
115
function Status () { $this->_MBPush (); if (!( $fp = $this->_Connect() )) { $this->_MBPop(); return false; } $req = pack ( "nnNN", SEARCHD_COMMAND_STATUS, VER_COMMAND_STATUS, 4, 1 ); // len=4, body=1 if ( !( $this->_Send ( $fp, $req, 12 ) ) || !( $response = $this->_GetResponse ( $fp, VER_COMMAND_STATUS ) ) ) { $this->_MBPop (); return false; } $res = substr ( $response, 4 ); // just ignore length, error handling, etc $p = 0; list ( $rows, $cols ) = array_values ( unpack ( "N*N*", substr ( $response, $p, 8 ) ) ); $p += 8; $res = array(); for ( $i=0; $i<$rows; $i++ ) for ( $j=0; $j<$cols; $j++ ) { list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4; $res[$i][] = substr ( $response, $p, $len ); $p += $len; } $this->_MBPop (); return $res; }Zx ////////////////////////////////////////////////////////////////////////// // flush ////////////////////////////////////////////////////////////////////////// function FlushAttributes () { $this->_MBPush (); if (!( $fp = $this->_Connect() )) { $this->_MBPop();
116
return -1; } $req = pack ( "nnN", SEARCHD_COMMAND_FLUSHATTRS, VER_COMMAND_FLUSHATTRS, 0 ); // len=0 if ( !( $this->_Send ( $fp, $req, 8 ) ) || !( $response = $this->_GetResponse ( $fp, VER_COMMAND_FLUSHATTRS ) ) ) { $this->_MBPop (); return -1; } $tag = -1; if ( strlen($response)==4 ) list(,$tag) = unpack ( "N*", $response ); else $this->_error = "unexpected response length"; $this->_MBPop (); return $tag; } }