diff --git a/Adapter/adapter_config.js b/Adapter/adapter_config.js index e0d01729..5f34b48c 100644 --- a/Adapter/adapter_config.js +++ b/Adapter/adapter_config.js @@ -30,6 +30,7 @@ global.api_dir = path.join(adapter_dir, "api"); global.spi_dir = path.join(adapter_dir, "impl"); global.spi_doc_dir = path.join(spi_dir, "SPI-documentation"); global.api_doc_dir = path.join(parent_dir, "API-documentation"); +global.backend_doc_dir = path.join(parent_dir, "Backend-documentation"); global.converters_dir = path.join(parent_dir, "Converters"); global.spi_module = path.join(spi_dir, "SPI.js"); diff --git a/Adapter/impl/mysql/mysql_service_provider.js b/Adapter/impl/mysql/mysql_service_provider.js index 954f136a..b5434a53 100644 --- a/Adapter/impl/mysql/mysql_service_provider.js +++ b/Adapter/impl/mysql/mysql_service_provider.js @@ -52,26 +52,8 @@ exports.loadRequiredModules = function() { }; -var MysqlDefaultConnectionProperties = { - "implementation" : "mysql", - "database" : "test", - - "mysql_host" : "localhost", - "mysql_port" : 3306, - "mysql_user" : "root", - "mysql_password" : "", - "mysql_charset" : "UTF8MB4", - "mysql_sql_mode" : "STRICT_ALL_TABLES", - "mysql_socket" : null, - "debug" : true, - "mysql_trace" : false, - "mysql_debug" : false, - "mysql_pool_size": 10 -}; - - exports.getDefaultConnectionProperties = function() { - return MysqlDefaultConnectionProperties; + return require(path.join(backend_doc_dir,"mysql_properties.js")); }; diff --git a/Adapter/impl/ndb/ndb_service_provider.js b/Adapter/impl/ndb/ndb_service_provider.js index db911cfa..23b1a1ce 100644 --- a/Adapter/impl/ndb/ndb_service_provider.js +++ b/Adapter/impl/ndb/ndb_service_provider.js @@ -35,7 +35,7 @@ catch(e) { var udebug = unified_debug.getLogger("ndb_service_provider.js"); var NdbDefaultConnectionProperties = - require(path.join(spi_doc_dir, "NDB_Properties")); + require(path.join(backend_doc_dir, "ndb_properties")); exports.loadRequiredModules = function() { var err, ldp, module, msg; diff --git a/Backend-documentation/mysql.md b/Backend-documentation/mysql.md new file mode 100644 index 00000000..d7d6f815 --- /dev/null +++ b/Backend-documentation/mysql.md @@ -0,0 +1,18 @@ +``` +var MysqlDefaultConnectionProperties = { + "implementation" : "mysql", + "database" : "test", + + "mysql_host" : "localhost", + "mysql_port" : 3306, + "mysql_user" : "root", + "mysql_password" : "", + "mysql_charset" : "UTF8MB4", + "mysql_sql_mode" : "STRICT_ALL_TABLES", + "mysql_socket" : null, + "debug" : true, + "mysql_trace" : false, + "mysql_debug" : false, + "mysql_pool_size": 10 +}; +``` diff --git a/Backend-documentation/mysql_properties.js b/Backend-documentation/mysql_properties.js new file mode 100644 index 00000000..011960f9 --- /dev/null +++ b/Backend-documentation/mysql_properties.js @@ -0,0 +1,26 @@ +/* + MySQL Connection Properties + +*/ + +var MysqlDefaultConnectionProperties = { + "implementation" : "mysql", + "database" : "test", + + "mysql_host" : "localhost", + "mysql_port" : 3306, + "mysql_user" : "root", + "mysql_password" : "", + "mysql_charset" : "UTF8MB4", + "mysql_sql_mode" : "STRICT_ALL_TABLES", + "mysql_socket" : null, + "debug" : true, + "mysql_trace" : false, + "mysql_debug" : false, + "mysql_pool_size": 10 +}; + + +/* This file is valid JavaScript +*/ +module.exports = MysqlDefaultConnectionProperties; diff --git a/Backend-documentation/ndb.md b/Backend-documentation/ndb.md new file mode 100644 index 00000000..cb952975 --- /dev/null +++ b/Backend-documentation/ndb.md @@ -0,0 +1,41 @@ +``` +var NdbDefaultConnectionProperties = { + "implementation" : "ndb", // This must always be "ndb". + + "ndb_connectstring" : "localhost:1186", // MySQL Cluster Connect String + "database" : "test", // MySQL Database name + "mysql_user" : "root", + + /* The next 3 properties control the behavior when opening a connection. */ + "ndb_connect_retries" : 4, // if < 0, keep trying forever + "ndb_connect_delay" : 5, // full seconds between connection retries + "ndb_connect_verbose" : 0, // enable extra console output + + "linger_on_close_msec": 500, /* When a client closes a DBConnectionPool, + the underlying connection is kept open + for this many milliseconds in case + another client tries to re-open it. + */ + + "use_ndb_async_api" : false, /* If true, some operations will be + executed using asynchronous calls for + improved concurrency. If false, the + number of operations in transit will be + limited to one per uv worker thread. + */ + + "ndb_session_pool_min" : 4, + "ndb_session_pool_max" : 100, /* Each NdbConnectionPool maintains a + pool of DBSessions (and their underlying + Ndb objects). These parameters set + guidelines for the size of that pool. + */ + + "ndb_session_concurrency" : 4 /* The number of concurrent transactions + in an Ndb Session. Only one + transaction at a time is visible to the + user, but one may start before previous + ones have finished executing. + */ +}; +``` diff --git a/Backend-documentation/ndb_properties.js b/Backend-documentation/ndb_properties.js new file mode 100644 index 00000000..774c33ef --- /dev/null +++ b/Backend-documentation/ndb_properties.js @@ -0,0 +1,50 @@ + + +/* + NDB Connection Properties + +*/ + +var NdbDefaultConnectionProperties = { + "implementation" : "ndb", // This must always be "ndb". + + "ndb_connectstring" : "localhost:1186", // MySQL Cluster Connect String + "database" : "test", // MySQL Database name + "mysql_user" : "root", + + /* The next 3 properties control the behavior when opening a connection. */ + "ndb_connect_retries" : 4, // if < 0, keep trying forever + "ndb_connect_delay" : 5, // full seconds between connection retries + "ndb_connect_verbose" : 0, // enable extra console output + + "linger_on_close_msec": 500, /* When a client closes a DBConnectionPool, + the underlying connection is kept open + for this many milliseconds in case + another client tries to re-open it. + */ + + "use_ndb_async_api" : false, /* If true, some operations will be + executed using asynchronous calls for + improved concurrency. If false, the + number of operations in transit will be + limited to one per uv worker thread. + */ + + "ndb_session_pool_min" : 4, + "ndb_session_pool_max" : 100, /* Each NdbConnectionPool maintains a + pool of DBSessions (and their underlying + Ndb objects). These parameters set + guidelines for the size of that pool. + */ + + "ndb_session_concurrency" : 4 /* The number of concurrent transactions + in an Ndb Session. Only one + transaction at a time is visible to the + user, but one may start before previous + ones have finished executing. + */ +}; + +/* This file is valid JavaScript +*/ +module.exports = NdbDefaultConnectionProperties; diff --git a/README.md b/README.md index 4d48551c..661ab518 100644 --- a/README.md +++ b/README.md @@ -1,107 +1,173 @@ -MySQL Cluster NoSQL API for Node.JS -=================================== +MySQL-JS +======== INTRODUCTION ------------ -The NoSQL API for Node.JS provides a lightweight domain object model for -JavaScript. You write code using common JavaScript objects, and use simple -API calls to read and write those objects to the database, like this: +This package provides a fast, easy, and safe framework for building +database applications in Node.js. It is organized around the concept +of a database *session*, which allows standard JavaScript objects to be +read from and written to a database. +This example uses a session to store a single object into a MySQL table: ``` - var nosql = require("mysql-js"); - - function onSession(err, session) { - var data = new Tweet(username, message); - session.persist(data); - } +var nosql = require("mysql-js"); + +var connectionProperties = { + "implementation" : "mysql", + "database" : "test", + "mysql_host" : "localhost", + "mysql_port" : 3306, + "mysql_user" : "test", + "mysql_password" : "", +}; + +nosql.openSession(connectionProperties).then( + function(session) { + var user = { id: 1, name: "Database Jones"}; + return session.persist("user", user); + } +).then( + function() { + console.log("Complete"); + nosql.closeAllOpenSessionFactories(); + } +); +``` + - nosql.openSession(onSession); +QUICK INSTALL +------------- +MySQL-JS can be installed using NPM: + +``` +npm install https://github.com/mysql/mysql-js/archive/2014-10-06.tar.gz ``` -More sample code is available in the samples/ directory. - The API includes two backend adapters: +SUPPORTED DATABASES AND CONNECTION PROPERTIES +--------------------------------------------- +MySQL-JS provides a common data management API over a variety of back-end +database connections. Two database adapters are currently supported. +The *mysql* adapter provides generic support for any MySQL database, +based on all-JavaScript mysql connector node-mysql. +The *ndb* adapter provides optimized high-performance access to MySQL Cluster +using the NDB API. - - The "ndb" adapter, which uses the native NDB API to provide - high-performance native access to MySQL Cluster. +Each backend adapter supports its own set of connection properties. ++ [MySQL Connection Properties](Backend-documentation/mysql.md) ++ [NDB Connection Properties](Backend-documentation/ndb.md) - - The "mysql" adapter, which connects to any MySQL Server using the node-mysql - driver, available from https://github.com/felixge/node-mysql/ +SESSION +------- +The central concept of mysql-js is the *session* class. A session provides +a context for database operations and transactions. Each independent user +context should have a distinct session. For instance, in a web application, +handling each HTTP request involves opening a session, using the session to +access the database, and then closing the session. + + +### Session methods + +Most methods on session() are available on several varieties: they may take +either a mapped object or a literal table name; they may take a callback, or +rely on the returned promise for continuation; and they may take any number +of extra arguments after a callback. + +Each of the following methods is *asynchronous* and *returns a promise*: ++ *find()* Find an instance in the database using a primary or unique key. +++ find(Constructor, keys, [callback], [...]) +++ find(Projection, keys, [callback], [...]) +++ find(tableName, keys, [callback], [...]) ++ *load(instance, [callback], [...])* Loads a specific instance from the database +based on the primary or unique key present in the object. ++ *persist()* Insert an instance into the database. +++ persist(instance, [callback], [...]) +++ persist(Constructor, values, [callback], [...]) +++ persist(tableName, values, [callback], [...]) ++ *remove()* Delete an instance by primary or unique key. +++ remove(instance, [callback], [...]) +++ remove(Constructor, keys, [callback], [...]) +++ remove(tableName, keys, [callback], [...]) ++ *update()* Update an instance by primary or unique key without necessarily retrieving it. +++ update(instance, [callback], [...]) +++ update(Constructor, keys, values, [callback], [...]) +++ update(tableName, keys, values, [callback], [...]) ++ *save()* Write an object to the database without checking for existence; could result in either an update or an insert. +++ save(instance, [callback], [...]) +++ save(Constructor, values, [callback], [...]) +++ save(tableName, values, [callback], [...]) ++ *createQuery()* Create an object that can be used to query the database +++ createQuery(instance, [callback], [...]) +++ createQuery(Constructor, [callback], [...]) +++ createQuery(tableName, [callback], [...]) ++ *getMapping()* Resolve and fetch mappings for a table or class +++ getMapping(object, [callback], [...]) +++ getMapping(Constructor, [callback], [...]) +++ getMapping(tableName, [callback], [...]) ++ *close([callback], [...])* Close the current session + +The following methods are *immediate*: ++ createBatch(). Returns a batch. ++ listBatches(). Returns an array of batches. ++ isClosed(). Returns boolean. ++ isBatch(). Returns boolean. ++ currentTransaction(). Returns a Transaction. + +See the [Complete documentation for Session](API-documentaiton/Session) + + +PROMISES +-------- +The majority of the asynchronous API methods in mysql-js return a +Promises/A+ compatible promise. -REQUIREMENTS ------------- -Building the ndb backend requires an installed copy of MySQL Cluster 7.x -including headers and shared library files. The MySQL architecture must match -the node architecture: if node.js is 64-bit, then MySQL must also be 64-bit. If -node is 32-bit, MySQL must be 32-bit. -The mysql backend requires version 2.0 of node-mysql, an all-JavaScript -MySQL client. +NOSQL +----- -### WINDOWS REQURIREMENTS LIST ### -1. Microsoft Visual Studio -2. MySQL Cluster -3. Python 2.6 or 2.7 -4. Node.JS -5. node-gyp ++ *ConnectionProperties(adapterName)*: *Constructor*. Creates a ConnectionProperties + object containing default values for all properties. ++ *TableMapping(tableName)*: *Constructor*. Creates a new TableMapping. ++ *Projection(mappedConstructor)*: *Constructor*. Creates a new Projection. ++ *connect(properties, [mappings], [callback], [...]): *ASYNC*. The callback +or promise receives a SessionFactory. ++ *openSession(properties, [mappings], [callback], [...]): *ASYNC*. An implicit +SessionFactory is opened if needed; the callback or promise receives a Session. ++ *getOpenSessionFactories()* Returns an array ++ *closeAllOpenSessionFactories()* Returns undefined +See the [Complete documentation for the top-level API](API-documentation/Mynode) -BUILDING --------- -The installation script is interactive. It will try to locate a suitable copy -of MySQL, and it will prompt you to accept its choice or enter an alternative. +MAPPED JAVASCRIPT OBJECTS +------------------------- -* To build the module in place, type: - ```node configure.js``` + describe mapping + put an table mapping code example + link to table mapping docs + -* After configuring, build a binary. The -d argument to node-gyp makes it a -"debug" binary - ```node-gyp configure build -d``` +CONVERTERS +---------- -* After testing the debug binary, on platforms other than Windows, it is -possible to build an optimized (non-debug) binary. *Non-debug builds are -generally not possible on Windows, and usually result in link-time errors.* - ```node-gyp rebuild``` +BATCHES +------- -DIRECTORY STRUCTURE -------------------- -