Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/khueue/prolongo

MongoDB Driver for Prolog
https://github.com/khueue/prolongo

Last synced: 3 months ago
JSON representation

MongoDB Driver for Prolog

Awesome Lists containing this project

README

        

MongoDB Driver for Prolog
=========================

A MongoDB driver compatible with SWI-Prolog that implements basic CRUD
functionality. Several things have yet to be implemented (authentication,
GridFS, etc.), but the driver can be used for simple use cases.

## Release History

### Version 1.1.1 (2016-09-13)

* Updated implementation to be compatible with the current MongoDB
version (currently 3.2.9). (In particular, `mongo:list_collection_names/2`
was updated to stop using removed MongoDB functionality.)
* Tested on SWI-Prolog 7.2.3.

### Version 1.1.0 (2012-09-10)

* BSON parser is now an external dependency (separate repository).
* Updated BSON parser to handle new binary 'uuid' subtype.
* Rewritten exception handling, exceptions now follow:
`mongo_error(DescriptionAtom, ListOfRelatedVars)`.
* Fix buggy hex_bytes/2 (used when handling object_id).
* Hopefully improved compilation on Windows (now includes stdint.h).
* Test suite can be run in parallel by separate Prolog sessions.
* Better API documentation (in the code).
* Minor performance improvements and code cleanup.
* Internal module usage rewritten.
* Now tested on MongoDB 2.2.0.
* Prepared for SWI-Prolog 6.2.0.

### Version 1.0.0 (2012-08-11)

* First real release.
* Fix issue #1 ("Two tests failing on Swi-Prolog 6.0.2").
* Add runnable example program (simple todo).

## Dependencies

* **SWI-Prolog** - Tested on Mac OS X using SWI 7.2.3.
* **MongoDB** - Tested on Mac OS X using MongoDB 3.2.9.
* **BSON parser** - Found at .

## Installation and Usage

1. Clone the BSON parser found at ,
switch to a certain release if you like (e.g. `git checkout v1.0.0`) and
build it according to its instructions.
2. Clone prolongo (and possibly switch to a release, `git checkout v1.0.0`).
3. Edit the path to the BSON loader script found in `load.pl`. The path
should be relative to prolongo's root (so you don't have to edit
anything if you clone both BSON and prolongo into the same parent
folder).
4. Run `make` to run the tests (will also run the BSON tests). Some
of the tests require a MongoDB instance running on localhost on the
default port.
5. See the example below, the tests (`*.plt`) in the `src` folder as well
as the API documentation in the source code for more usage information.

## Usage Example

A small to-do application (also found in the examples folder):

```prolog
#!/usr/bin/env swipl --quiet -O -t todo -f

% Usage: Run `examples/todo.pl` from the project root.

% Setup prolongo load paths and load the library.
:- [load].
:- use_module(mongo(mongo), []). % Empty import forces use of namespace.

todo :-
print_welcome,
setup_call_cleanup(
mongo:new_connection(Connection),
todo_run(Connection),
mongo:free_connection(Connection)).

print_welcome :-
format('--- Simple Todo ---~n'),
format('Terminate input with a period.~n~n').

todo_run(Connection) :-
mongo:get_database(Connection, 'prolongo_example_todo', Database),
mongo:get_collection(Database, 'items', Collection),
action(list, Collection).

action(list, Collection) :- !,
list_items(Collection),
new_action(Collection).
action(add, Collection) :- !,
add_item(Collection),
new_action(Collection).
action(delete, Collection) :- !,
delete_item(Collection),
new_action(Collection).
action(quit, _Collection) :- !,
format('Bye!~n').
action(_Unknown, Collection) :-
format('Unknown alternative.~n'),
new_action(Collection).

new_action(Collection) :-
format('~nEnter list/add/delete/quit: '),
read(Action),
action(Action, Collection).

list_items(Collection) :-
mongo:find_all(Collection, [], [], Docs),
print_items(Docs).

print_items(Docs) :-
format('Id~26|Label~45|Priority~n'),
print_items_aux(Docs).

print_items_aux([]).
print_items_aux([Doc|Docs]) :-
bson:doc_get(Doc, '_id', object_id(Id)),
bson:doc_get(Doc, label, Label),
bson:doc_get(Doc, priority, Priority),
format('~w~26|~w~45|~w~n', [Id,Label,Priority]),
print_items_aux(Docs).

add_item(Collection) :-
format('Label: '),
read(Label),
format('Priority: '),
read(Priority),
Doc = [label-Label,priority-Priority],
mongo:insert(Collection, Doc).

delete_item(Collection) :-
format('Id: '),
read(Id),
mongo:delete(Collection, ['_id'-object_id(Id)]).
```

Consult the file and make sure you have a MongoDB instance running on
localhost, then run it:

```
?- todo.
--- Simple Todo ---
Id Label Priority

Enter list/add/delete/quit: add.
Label: 'Make tea'.
Priority: 1.

Enter list/add/delete/quit: add.
Label: 'Go for a walk'.
Priority: 2.

Enter list/add/delete/quit: list.
Id Label Priority
4dff66bd4c594ffa3e17cb70 Make tea 1
4dff66eb4c594ffa3e17cb71 Go for a walk 2

Enter list/add/delete/quit: delete.
Id: '4dff66eb4c594ffa3e17cb71'.

Enter list/add/delete/quit: list.
Id Label Priority
4dff66bd4c594ffa3e17cb70 Make tea 1

Enter list/add/delete/quit: quit.
Bye!
```

## Todo

* Reduce amount of arguments to CRUD predicates.

## Issues

* RequestId and ResponseId are completely ignored (set to 0) in
mongo message headers.

## License

Licensed under the MIT license which can be found in the file
`LICENSE` in the project root.

## Coding Guidelines

* Use empty imports (use_module(mymodule, [])) in order to not
pollute the namespace.
* Always use module prefixes (mymodule:predicate(...)) in order to
clarify where things are coming from.
* Always use the "made-up" module prefix "core:" when calling
built-in predicates. This is completely unnecessary, and doesn't even
work in all cases, but I think it is a good idea as long as it doesn't
cause any problems. This decision may need to be revised when
compatibility between different Prologs is investigated.
* Avoid the if-then-else construct. It just looks ugly.
* Avoid disjunctions. They are ugly, and can be replaced by properly
written helpers. Think: premises are "and", clauses are "or".
* Use cuts where appropriate, and try to keep each cut on a line by
itself unless its placement is obvious and consistent in each clause.
PlUnit is excellent at pointing out when tests succeed but leave
choice points.
* Try to avoid spaces within lists and structures, but always use
spaces between arguments.
* Predicates, atoms, etc. should use "this_naming_style" while variables
should use "ThisNamingStyle".
* Try to stick to the PlDoc structure.
* If in doubt, consult: .