Skip to content

Commit

Permalink
DBHandler class functions with test cases
Browse files Browse the repository at this point in the history
Address data-driven-science#5

The DBHandler class works with two test cases. The dbhandle.py script
uses DBHandler for all its functions.

 * The tests in the test/ directory are broken.

 * There are still issues when the tests shutdown their own database
   instance. It is probably better to start the database and then test
   rather than allow the tests to start their own DB instances
  • Loading branch information
wd15 committed Apr 16, 2015
1 parent 6c89668 commit 87be3d8
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 89 deletions.
96 changes: 47 additions & 49 deletions dbhandle.py
Original file line number Diff line number Diff line change
@@ -1,67 +1,65 @@
import click
import subprocess
import pymongo
from ddsmdb.dbhandler import DBHandler
import json
import pprint

@click.command()
@click.option('--run/--no-run', default=None, help="run mongod with `--dbpath`")
@click.option('--launch/--no-launch', default=True, help="run mongod with `--dbpath`")
@click.option('--info/--no-info', default=False, help="the names of the databases")
@click.option('--create', default=None, help="create a database, specify a name")
@click.option('--delete', default=None, help="delete a database, specify a name")
@click.option('--shutdown/--no-shutdown', default=None, help='shutdown the database server using `--dbpath`')
@click.option('--create/--no-create', default=False, help="create a database")
@click.option('--delete/--no-delete', default=False, help="delete a database")
@click.option('--dbname', default=None, help="the name of the db")
@click.option('--shutdown/--no-shutdown', default=False, help='shutdown the database server using `--dbpath`')
@click.option('--dbpath', default=None, help='specify the dbpath to run or remove')
@click.option('--verbose/--no-verbose', default=False, help="dump mongod output to stdout")
@click.option('--port', default=None, type=int, help="the port number")
@click.option('--host', default=None, help="the host")
@click.option('--jsonfile', default=None, help="upload JSON data to database")
@click.option('--view/--no-view', default=False, help="dump the data in the database to screeen")

def handle(run, info, create, delete, shutdown, dbpath):
if run:
dbrun(dbpath)

client = pymongo.MongoClient('localhost', 27017)
def handle(launch,
info,
create,
delete,
dbname,
shutdown,
dbpath,
verbose,
port,
host,
jsonfile,
view):

handler = DBHandler(port=port, dbpath=dbpath, host=host, launch=launch, verbose=verbose)

if create or delete or jsonfile or view:
if not dbname:
dbname = click.prompt('enter a db name', type=str)

if create:
dbcreate(client, create)
handler.create(dbname)

if info:
dbinfo(client)
info = handler.info()
click.echo(info)

if delete:
dbdelete(client, delete)
handler.delete(dbname)

if jsonfile:
with open(jsonfile, 'r') as f:
data = json.load(f)
handler.create(dbname)
handler.set_data(dbname, data)

if view:
data = handler.get_data(dbname)
pp = pprint.PrettyPrinter(indent=2)
pp.pprint(data)

if shutdown:
dbshutdown(dbpath)
handler.shutdown()

def dbrun(dbpath):
command = ['mongod']
if dbpath:
command.append('--dbpath')
command.append(dbpath)
subprocess.Popen(command)

def dbcreate(client, dbname):
db = client[dbname]
collection = db['setup-collection']
collection.insert({'setup-data' : True})

def dbinfo(client):
click.echo('list of databases')
for name in client.database_names():
click.echo('database: {0}'.format(name))

def dbdelete(client, dbname):
if click.confirm('Do you want to delete the {0} database?'.format(dbname)):
client.drop_database(dbname)
click.echo('deleted the {0} database'.format(dbname))

def dbsetup():
#Add some test data to the database
pass

def dbshutdown(dbpath):
command = ['mongod']
command.append('--shutdown')
if dbpath:
command.append('--dbpath')
command.append(dbpath)
subprocess.call(command)

if __name__ == "__main__":
handle()

Expand Down
1 change: 1 addition & 0 deletions ddsmdb/data/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"a": 1}, {"b": 2}]
4 changes: 4 additions & 0 deletions ddsmdb/data/zero.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
{'a' : 1},
{'b' : 2}
]
115 changes: 75 additions & 40 deletions ddsmdb/dbhandler.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import subprocess
import pymongo
import os
import time

class DBHandler(object):
"""
Expand All @@ -13,80 +14,114 @@ class DBHandler(object):
>>> testport = 27018
>>> dbname = 'test-db'
>>> db = DBHandler(port=testport)
>>> handler = DBHandler(port=testport, verbose=False)
Create a new database, check that it exists, delete it and
shutdown the daemon.
>>> db.create(dbname)
>>> assert 'test-db' in db.info()
>>> db.delete(dbname)
>>> handler.create(dbname)
>>> assert dbname in handler.info()
Shutdown the daemon.
>>> db.shutdown()
Start up the deamon.
>>> db0 = DBHandler(port=testport)
Use a separate instance to access the database.
>>> db1 = DBHandler(port=testport)
Add some data to the database.
Create a database.
>>> handler.set_data(dbname, {'my data' : 1})
>>> assert handler.get_data(dbname)[0]['my data'] == 1
>>> db1.create(dbname)
>>> db1.append_data(dbname, {'my-data' : 1})
>>> print db.get_data()
"""
def __init__(self, port=27017, dbpath=None, host='localhost'):

def __init__(self, port=None, dbpath=None, host=None, launch=True, verbose=False):
if not dbpath:
dbpath = os.getenv("MONGO_DBPATH", None)
try:
self.client = pymongo.MongoClient(host, port)
except pymongo.errors.ConnectionFailure:
self.launch(port=port, dbpath=dbpath)
self.client = pymongo.MongoClient(host, port)
if launch:
self.launch(port=port, dbpath=dbpath, verbose=verbose)
if host is None:
host = 'localhost'
for count in range(10, 0, -1):
try:
self.client = pymongo.MongoClient(host, port)
except pymongo.errors.ConnectionFailure:
if count == 1:
raise
time.sleep(5)
else:
break

self.dbpath = dbpath
self.collection = 'setup-collection'
self.verbose = verbose

def launch(self, port=27017, dbpath=None):
def launch(self, port=None, dbpath=None, verbose=False):
command = ['mongod']
if dbpath:
command.append('--dbpath')
command.append(dbpath)
command.append('--port')
command.append(str(port))
subprocess.Popen(command)
if port:
command.append('--port')
command.append(str(port))
if verbose:
stdout = None
else:
stdout = open(os.devnull, 'w')
subprocess.Popen(command, stdout=stdout)

def create(self, dbname):
db = self.client[dbname]
collection = db[self.collection]
collection.insert({'setup-data' : True})

self.delete(dbname)
db = self.client[dbname]
collection = db.test
collection.insert({})
collection.drop()

def info(self):
return self.client.database_names()

def delete(self, dbname):
self.client.drop_database(dbname)

def append_data(self, dbname, data):
def set_data(self, dbname, data):
db = self.client[dbname]
collection = db[self.collection]
collection = db.test
collection.drop()
collection = db.test
collection.insert(data)

def get_data(self, dbname):
db = self.client[dbname]
return db[self.collection].get()
return list(db.test.find())

def shutdown(self):
command = ['mongod']
command.append('--shutdown')
if self.dbpath:
command.append('--dbpath')
command.append(self.dbpath)
subprocess.call(command)
if self.verbose:
stdout = None
else:
stdout = open(os.devnull, 'w')
subprocess.Popen(command, stdout=stdout)

def test():
"""
Load a small json file and then check that the data is in the
database. The test needs the check that a JSON object that is a
list is read into the database correctly and extracted correctly.
"""

import json
base = os.path.split(__file__)[0]
filepath = os.path.join(base, 'data', 'small.json')
with open(filepath, 'r') as f:
data = json.load(f)

testport = 27018
dbname = 'test-db'
handler = DBHandler(port=testport, verbose=False)

handler.create(dbname)
handler.set_data(dbname, data)
new_data = handler.get_data(dbname)


assert data == new_data



0 comments on commit 87be3d8

Please sign in to comment.