Skip to content

Commit

Permalink
each record will now be saved with a uuid, added basic web listening …
Browse files Browse the repository at this point in the history
…interface
  • Loading branch information
mrjjwright committed Mar 17, 2010
1 parent 4797b18 commit 109fa66
Show file tree
Hide file tree
Showing 10 changed files with 417 additions and 104 deletions.
15 changes: 12 additions & 3 deletions README.md
Expand Up @@ -77,7 +77,7 @@ The above function applies the form of the predicate to each member of the array
See the [nosqlite tests](http://github.com/mrjjwright/NoSQLite/blob/master/test/test_nosqlite.coffee) for more info as well as the [docco](http://jashkenas.github.com/docco/) styled docs in the docs directory. See the [nosqlite tests](http://github.com/mrjjwright/NoSQLite/blob/master/test/test_nosqlite.coffee) for more info as well as the [docco](http://jashkenas.github.com/docco/) styled docs in the docs directory.


Web mode Web mode
------------------- ========================


You can start nosqlite in web mode by executing You can start nosqlite in web mode by executing


Expand All @@ -95,16 +95,25 @@ Here is how to use the web API.


The API only reads query params and the HTTP post body so you can map it to any url you want to. The API only reads query params and the HTTP post body so you can map it to any url you want to.


Query Params Global Query Params
-----------------------


* __db__ (optional) - All requests by default will be executed against the db passed into NoSQLite when it is created. If the param `db` is supplied then NoSQLite will invoke a method against the named sqlite file using the delegate to resolve the path name to the file (see delegate documentation below). * __db__ (optional) - All requests by default will be executed against the db passed into NoSQLite when it is created. If the param `db` is supplied then NoSQLite will invoke a method against the named sqlite file using the delegate to resolve the path name to the file (see delegate documentation below).


* __table__ - The table name in SQLite. The NoSQLite API is oriented around one table per object, so you will always be dealing with one table. * __table__ - The table name in SQLite. The NoSQLite API is oriented around one table per object, so you will always be dealing with one table.


* __method__ - The method on NoSQLite to call. One of `find`, `save`, `find_or_save_all`, `push` or `pull`.


Web API Methods
-----------------------

* __pull__ - `/pull?table=foo` - Pulls all the records in table foo from the remote source that are not in the local db table foo. The records are returned as JSON in the HTTP body.





Currently Requires Currently Requires
---------------- ========================


* [node](http://nodejs.org) * [node](http://nodejs.org)
* [CoffeeScript](http://jashkenas.github.com/coffee-script/) - fun, clean way to write JavaScript. Includes Cake to run the Cakefile and tests. * [CoffeeScript](http://jashkenas.github.com/coffee-script/) - fun, clean way to write JavaScript. Includes Cake to run the Cakefile and tests.
Expand Down
92 changes: 67 additions & 25 deletions nosqlite.coffee
@@ -1,5 +1,6 @@
require "underscore" require "underscore"
sql: require "./sql" sql: require "./sql"
process.mixin require "./uuid"


# NoSQLite - SQLite for Javascript # NoSQLite - SQLite for Javascript
# --------------------------------- # ---------------------------------
Expand All @@ -14,12 +15,17 @@ class NoSQLite
# params: # params:
# * A HTML 5 compatible JS object. # * A HTML 5 compatible JS object.
# * (optional) If set to `true` will create a core data compatible schema. # * (optional) If set to `true` will create a core data compatible schema.
constructor: (db, core_data_mode) -> constructor: (db, options) ->
sys.debug("creating instance of NoSQLite") sys.debug("creating instance of NoSQLite")


@db: db @db: db
@table_descriptions: [] @table_descriptions: []
@core_data_mode=core_data_mode @options = {
core_data_mode: false
no_guid: false
}
@options = _.extend(@options, options) if options?



# Finds an object or objects in the SQLite by running a query # Finds an object or objects in the SQLite by running a query
# derived from the supplied predicate on the supplied table. # derived from the supplied predicate on the supplied table.
Expand All @@ -35,10 +41,10 @@ class NoSQLite
self: this self: this
table: table table: table
predicate: predicate predicate: predicate
@hash_flag: true


try try
db.query(select.escaped, (select) -> db.query(select.escaped, (select) ->
#sys.puts(sys.inspect(select))
callback(null, select) callback(null, select)
) )
catch the_err catch the_err
Expand Down Expand Up @@ -136,9 +142,17 @@ class NoSQLite
# If the objects already exist in the database NoSQL will overwrite them for you with an update # If the objects already exist in the database NoSQL will overwrite them for you with an update
# As always, we'll call you back when everything is ready! # As always, we'll call you back when everything is ready!
save: (table, obj, callback) -> save: (table, obj, callback) ->

#augment object with guid unless options say not to
if @options_no_guid is false
if not _.isArray(obj)
obj.guid: uuid()
else for o in obj
o.guid: uuid()

inserts: [] inserts: []
inserts: sql.insert(table, table_obj, @core_data_mode) for table_obj in obj if _.isArray(obj) inserts: sql.insert(table, table_obj, @options.core_data_mode) for table_obj in obj if _.isArray(obj)
inserts.push(sql.insert(table, obj, @core_data_mode)) if not _.isArray(obj) inserts.push(sql.insert(table, obj, @options.core_data_mode)) if not _.isArray(obj)
the_obj: if _.isArray(obj) then obj[0] else obj the_obj: if _.isArray(obj) then obj[0] else obj
self: this self: this
db: @db db: @db
Expand Down Expand Up @@ -170,8 +184,8 @@ class NoSQLite
debug "received error: " + err debug "received error: " + err
self.parse_error(err) self.parse_error(err)
compensating_sql: switch self.errobj.code compensating_sql: switch self.errobj.code
when NO_SUCH_TABLE then sql.create_table(table, the_obj, self.core_data_mode).sql when NO_SUCH_TABLE then sql.create_table(table, the_obj, self.options.core_data_mode).sql
when NO_SUCH_COLUMN then sql.add_column(table, self.errobj.column, null, self.core_data_mode).sql when NO_SUCH_COLUMN then sql.add_column(table, self.errobj.column, null, self.options.core_data_mode).sql
else null else null


sys.debug "compensating sql: " + compensating_sql sys.debug "compensating sql: " + compensating_sql
Expand Down Expand Up @@ -223,35 +237,63 @@ class NoSQLite


# Web API # Web API
# -------------------------------------- # --------------------------------------
write_res: (response, err, result) ->
if err?
response.writeHead(500, {"Content-Type": "text/plain"})
response.write(err)
else
response.writeHead(200, {"Content-Type": "text/plain"})
response.write(JSON.stringify(result))
response.close();

# Starts a webserver on the supplied port to serve http requests # Starts a webserver on the supplied port to serve http requests
# for the instance's associated database. # for the instance's associated database.
# If NoSQLite has already started a webserver on that port # If NoSQLite has already started a webserver on that port
# this method returns silently. # this method returns silently.
listen: (port) -> listen: (port, host) ->
host: "127.0.0.1" if not host?
port: 5000 if not port?
http: require "http" if not http? http: require "http" if not http?
obj_json: ""
self: this self: this
http.createServer( (request, response) -> server: http.createServer( (request, response) ->
# Parse the url to see what the user wants to do body: ""
url: require("url").parse(request.url, true) url: require("url").parse(request.url, true)
if not url.query? or not url.query.method?
response.writeHead(500, {"Content-Type": "text/plain"})
response.write("Must supply method param")
response.close();
return
table: url.query.table table: url.query.table
request.addListener"data", (data) -> # Parse the url to see what the user wants to do
obj_json += data request.setBodyEncoding('utf8');
request.addListener "done", -> request.addListener "data", (data) ->
obj: JSON.parse(obj_json) body += data
request.addListener "end", ->
switch url.query.method switch url.query.method
when "save" when "save"
self.save(table, obj, (err, res) -> obj: JSON.parse(body)
response.writeHead(200, {"Content-Type": "text/plain"}) self.save(table, obj, (err, result) ->
response.write("Success") self.write_res(response, err, result)
response.close(); )
when "find"
predicate: JSON.parse(body)
self.find(table, predicate, (err, result) ->
self.write_res(response, err, result)
)
when "find_or_save"
args: JSON.parse(body)
self.find_or_save(table, args[0], args[1], (err, result) ->
self.write_res(response, err, result)
) )
else else
response.writeHead(200, {"Content-Type": "text/plain"}) response.writeHead(500, {"Content-Type": "text/plain"})
response.write(obj_json + "\n") response.write("Unrecognized method: ${url.query.method}")
response.close(); response.close();
).listen(port) )

server.listen(port, host)
return server




NO_SUCH_TABLE: 0 NO_SUCH_TABLE: 0
NO_SUCH_COLUMN: 1 NO_SUCH_COLUMN: 1
Expand All @@ -261,8 +303,8 @@ String.prototype.trim: ->
return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1") return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1")


# connect to NoSQLite this way. # connect to NoSQLite this way.
exports.connect: (db, core_data_mode) -> exports.connect: (db, options) ->
return new NoSQLite(db, core_data_mode) return new NoSQLite(db, options)






0 comments on commit 109fa66

Please sign in to comment.