{"action":"created","issue":{"url":"https://api.github.com/repos/oracle/node-oracledb/issues/388","repository_url":"https://api.github.com/repos/oracle/node-oracledb","labels_url":"https://api.github.com/repos/oracle/node-oracledb/issues/388/labels{/name}","comments_url":"https://api.github.com/repos/oracle/node-oracledb/issues/388/comments","events_url":"https://api.github.com/repos/oracle/node-oracledb/issues/388/events","html_url":"https://github.com/oracle/node-oracledb/pull/388","id":142687687,"number":388,"title":"Make API compatible with Promises","user":{"login":"jrop","id":1404053,"avatar_url":"https://avatars.githubusercontent.com/u/1404053?v=3","gravatar_id":"","url":"https://api.github.com/users/jrop","html_url":"https://github.com/jrop","followers_url":"https://api.github.com/users/jrop/followers","following_url":"https://api.github.com/users/jrop/following{/other_user}","gists_url":"https://api.github.com/users/jrop/gists{/gist_id}","starred_url":"https://api.github.com/users/jrop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jrop/subscriptions","organizations_url":"https://api.github.com/users/jrop/orgs","repos_url":"https://api.github.com/users/jrop/repos","events_url":"https://api.github.com/users/jrop/events{/privacy}","received_events_url":"https://api.github.com/users/jrop/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":7,"created_at":"2016-03-22T15:35:07Z","updated_at":"2016-03-22T23:03:22Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/oracle/node-oracledb/pulls/388","html_url":"https://github.com/oracle/node-oracledb/pull/388","diff_url":"https://github.com/oracle/node-oracledb/pull/388.diff","patch_url":"https://github.com/oracle/node-oracledb/pull/388.patch"},"body":"I am opening this pull request for discussion.  Theoretically, this does not break the current API, but extends it to return a Promise _and_ also call an (optionally) provided node-style callback.\r\n\r\n## Concept\r\n\r\nThe concept is to convert a method of the form:\r\n\r\n```js\r\nfunction someAsyncFunction(callback) {\r\n    // ... do async work, and at some point later do:\r\n    callback(err, result);\r\n}\r\n```\r\n\r\n...and converted to support both Promises _and_ callbacks:\r\n\r\n```js\r\nfunction someAsyncFunction(callback) {\r\n    // make a callback that wraps the passed one that automatically resolves/rejects an internal promise\r\n    callback = deferred(callback);\r\n\r\n    // ... do async work, and at some point later do:\r\n    callback(err, result);\r\n\r\n    // return the promise that gets resolved by a line similar to the one above:\r\n    return callback.promise;\r\n}\r\n```\r\n\r\n## Extended Oracle API\r\n\r\nWhat the commit contained in this pull request allows for is a backward compatible node-style callback API, while supporting promises.  This means that this is still valid code:\r\n\r\n```js\r\noracle.getConnection(CONFIG, (err, conn) => {\r\n\tconn.execute('SELECT * FROM MY_TABLE WHERE ROWNUM < 5', { }, { resultSet: true }, (err, res) => {\r\n\t\tres.resultSet.getRow((err, row) => {\r\n\t\t\tconsole.log(row)\r\n\t\t})\r\n\t})\r\n})\r\n```\r\n\r\nBut more interestingly, the API methods also return promises, which means that when using a version of Node.js that supports generators, and also utilizing the Node module `co` (that allows generators to support promises), this code can now be written:\r\n\r\n```js\r\nco(function * () {\r\n\ttry {\r\n\t\tconst conn = yield oracle.getConnection(CONFIG)\r\n\t\tconst res = yield conn.execute('SELECT * FROM CSUD_PCI WHERE ROWNUM < 5', { }, { resultSet: true })\r\n\r\n\t\tlet row = null\r\n\t\twhile (row = yield res.resultSet.getRow()) {\r\n\t\t\tconsole.log(row)\r\n\t\t}\r\n\t\tyield res.resultSet.close()\r\n\t\tyield conn.release()\r\n\t} catch (e) {\r\n\t\t// handle error and cleanup resources\r\n\t}\r\n})\r\n```"},"comment":{"url":"https://api.github.com/repos/oracle/node-oracledb/issues/comments/200071178","html_url":"https://github.com/oracle/node-oracledb/pull/388#issuecomment-200071178","issue_url":"https://api.github.com/repos/oracle/node-oracledb/issues/388","id":200071178,"user":{"login":"cjbj","id":200778,"avatar_url":"https://avatars.githubusercontent.com/u/200778?v=3","gravatar_id":"","url":"https://api.github.com/users/cjbj","html_url":"https://github.com/cjbj","followers_url":"https://api.github.com/users/cjbj/followers","following_url":"https://api.github.com/users/cjbj/following{/other_user}","gists_url":"https://api.github.com/users/cjbj/gists{/gist_id}","starred_url":"https://api.github.com/users/cjbj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cjbj/subscriptions","organizations_url":"https://api.github.com/users/cjbj/orgs","repos_url":"https://api.github.com/users/cjbj/repos","events_url":"https://api.github.com/users/cjbj/events{/privacy}","received_events_url":"https://api.github.com/users/cjbj/received_events","type":"User","site_admin":false},"created_at":"2016-03-22T23:03:22Z","updated_at":"2016-03-22T23:03:22Z","body":"@jrop it sounds like you are OK with @dmcghan's implementation?  Can you test it and let us know?  \r\n\r\nAs a rule, PR's need to follow https://github.com/oracle/node-oracledb/blob/master/CONTRIBUTING.md and have the OCA accepted."}}