Skip to content

Commit

Permalink
Added capability to load db from file
Browse files Browse the repository at this point in the history
Also added sample db dump.
Resolves HospitalRun#13
  • Loading branch information
jkleinsc committed Dec 29, 2015
1 parent 3a8164c commit 77256ae
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 16 deletions.
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ To start the frontend please do the following:
- Start the server by running `ember serve` in the repo folder.
- Go to [http://localhost:4200/](http://localhost:4200/) in a browser and login with username `hradmin` and password `test`.

## Loading sample data
If you would like to load sample data, you can do so by navigating to **Load DB** under the Adminstration menu. You should see the following screen:
![Load DB screenshot](screenshots/load-db.png)

Click on ***Choose File*** and select the file **sample-data.txt** which is included in root directory of the repo at [sample-data.txt](sample-data.txt).
Next, click on ***Load File***. When the database load is complete a message will appear indicating if the load was successful.

## Testing

### Fixtures for Acceptance Tests
Expand All @@ -39,15 +46,17 @@ Fixtures are PouchDB dumps that are generated with [pouchdb-dump-cli](https://gi

To create a fixture, run `pouchdb-dump http://localhost:5984/main -u hradmin -p test | cat > tests/fixtures/${name_of_fixture}.txt`.

To use a fixture, use `loadPouchDump(`${name_of_fixture})` in your acceptance test. For example,
To use a fixture, use `runWithPouchDump(${name_of_fixture}, function(){..});` in your acceptance test. For example,

```
test('visiting /patients', function(assert) {
loadPouchDump('default');
authenticateUser();
visit('/patients');
andThen(function() {
assert.equal(currentURL(), '/patients');
runWithPouchDump('default', function() {
//Actual test code here
authenticateUser();
visit('/patients');
andThen(function() {
assert.equal(currentURL(), '/patients');
});
});
});
```
Expand Down
34 changes: 34 additions & 0 deletions app/admin/loaddb/controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Ember from 'ember';
import ModalHelper from 'hospitalrun/mixins/modal-helper';
import ProgressDialog from 'hospitalrun/mixins/progress-dialog';
export default Ember.Controller.extend(ModalHelper, ProgressDialog, {
database: Ember.inject.service(),
fileSystem: Ember.inject.service('filesystem'),
progressMessage: 'Please wait while your database is loaded.',
progressTitle: 'Loading Database',
syncResults: null,

actions: {
loadFile: function() {
var fileSystem = this.get('fileSystem'),
fileToImport = this.get('importFile');
if (!fileToImport || !fileToImport.type) {
this.displayAlert('Select File To Load', 'Please select file to load.');
} else {
this.showProgressModal();
this.set('syncResults');
fileSystem. fileToString(fileToImport).then((fileAsString) => {
var database = this.get('database');
this.set('importFile');
this.set('model.importFileName');
database.loadDBFromDump(fileAsString).then((results) => {
this.closeProgressModal();
this.set('syncResults', results);
}).catch((err) => {
this.displayAlert('Error Loading', `The database could not be imported. The error was:${JSON.stringify(err)}`);
});
});
}
}
}
});
18 changes: 18 additions & 0 deletions app/admin/loaddb/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import AbstractEditRoute from 'hospitalrun/routes/abstract-edit-route';
import Ember from 'ember';
import UserSession from 'hospitalrun/mixins/user-session';
export default AbstractEditRoute.extend(UserSession, {
hideNewButton: true,
editTitle: 'Load DB',

beforeModel: function() {
if (!this.currentUserCan('load_db')) {
this.transitionTo('application');
}
},

// No model needed for import.
model: function() {
return Ember.RSVP.resolve(Ember.Object.create({}));
}
});
27 changes: 27 additions & 0 deletions app/admin/loaddb/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div class="panel panel-primary">
<div class="panel-body">
{{#em-form model=model submitButton=false }}
{{file-upload label="File To Load" property="importFileName" selectedFile=importFile }}
<button class="btn btn-default" {{action 'loadFile'}}>Load File</button>
{{/em-form}}
{{#if syncResults}}
<h4>File Load Successful</h4>
<div class="form-group col-xs-3">
<label>Start Time</label>
<p class="form-control-static">{{date-format syncResults.start_time format="l h:mm A"}}</p>
</div>
<div class="form-group col-xs-3">
<label>End Time</label>
<p class="form-control-static">{{date-format syncResults.end_time format="l h:mm A"}}</p>
</div>
<div class="form-group col-xs-3">
<label>Docs Read</label>
<p class="form-control-static">{{syncResults.docs_read}}</p>
</div>
<div class="form-group col-xs-3">
<label>Docs Written</label>
<p class="form-control-static">{{syncResults.docs_written}}</p>
</div>
{{/if}}
</div>
</div>
30 changes: 20 additions & 10 deletions app/admin/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,26 @@ export default AbstractModuleRoute.extend({
allowSearch: false,
moduleName: 'admin',
sectionTitle: 'Admin',
subActions: [{
text: 'Address Options',
linkTo: 'admin.address'
}, {
text: 'Lookup Lists',
linkTo: 'admin.lookup'
}, {
text: 'Users',
linkTo: 'users.index'
}],
subActions: function() {
var options = [{
text: 'Address Options',
linkTo: 'admin.address'
}, {
text: 'Lookup Lists',
linkTo: 'admin.lookup'
}];
if (this.currentUserCan('load_db')) {
options.push({
text: 'Load DB',
linkTo: 'admin.loaddb'
});
}
options.push({
text: 'Users',
linkTo: 'users.index'
});
return options;
}.property(),

editPath: function() {
return 'users.edit';
Expand Down
6 changes: 6 additions & 0 deletions app/mixins/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,12 @@ export default Ember.Mixin.create({
route: 'admin.address',
capability: 'update_config'
},
{
title: 'Load DB',
iconClass: 'octicon-plus',
route: 'admin.loaddb',
capability: 'load_db'
},
{
title: 'Users',
iconClass: 'octicon-chevron-right',
Expand Down
3 changes: 3 additions & 0 deletions app/mixins/user-session.js
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,9 @@ export default Ember.Mixin.create({
'Pharmacist',
'System Administrator'
],
load_db: [
'System Administrator'
],
override_invoice: [
'Business Office',
'Hospital Administrator',
Expand Down
1 change: 1 addition & 0 deletions app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Router.map(function() {
resetNamespace: true
}, function() {
this.route('address');
this.route('loaddb');
this.route('lookup', { path: '/' });
this.route('users', {
resetNamespace: true
Expand Down
22 changes: 22 additions & 0 deletions app/services/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,28 @@ export default Ember.Service.extend(PouchAdapterUtils, {
type: type
});
},

/**
* Load the specified db dump into the database.
* @param {String} dbDump A couchdb dump string produced by pouchdb-dump-cli.
* @returns {Promise} A promise that resolves once the dump has been loaded.
*/
loadDBFromDump: function(dbDump) {
return new Ember.RSVP.Promise((resolve, reject) => {
var db = new PouchDB('dbdump', {
adapter: 'memory'
});
db.load(dbDump).then(() => {
var mainDB = this.get('mainDB');
db.replicate.to(mainDB).on('complete', (info) => {
resolve(info);
}).on('error', (err) => {
reject(err);
});
});
});
},

_mapPouchData: function(rows) {
var mappedRows = [];
if (rows) {
Expand Down
16 changes: 16 additions & 0 deletions app/services/filesystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,22 @@ export default Ember.Service.extend({
});
},

/**
* Read the specified file into a string
* @param {File} file to read
* @returns {Promise} returns a Promise that resolves with the data url
* for the file.
*/
fileToString: function(file) {
return new Ember.RSVP.Promise(function(resolve) {
var reader = new FileReader();
reader.onloadend = function(e) {
resolve(e.target.result);
};
reader.readAsText(file);
});
},

/**
* Property to to determine if file system API is available.
*/
Expand Down
9 changes: 9 additions & 0 deletions sample-data.txt

Large diffs are not rendered by default.

Binary file added screenshots/load-db.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 77256ae

Please sign in to comment.