{"action":"opened","number":8,"pull_request":{"url":"https://api.github.com/repos/TryGhost/GQL/pulls/8","id":50322059,"html_url":"https://github.com/TryGhost/GQL/pull/8","diff_url":"https://github.com/TryGhost/GQL/pull/8.diff","patch_url":"https://github.com/TryGhost/GQL/pull/8.patch","issue_url":"https://api.github.com/repos/TryGhost/GQL/issues/8","number":8,"state":"open","locked":false,"title":"Refactor + add lodash style tools for processing statements","user":{"login":"ErisDS","id":101513,"avatar_url":"https://avatars.githubusercontent.com/u/101513?v=3","gravatar_id":"","url":"https://api.github.com/users/ErisDS","html_url":"https://github.com/ErisDS","followers_url":"https://api.github.com/users/ErisDS/followers","following_url":"https://api.github.com/users/ErisDS/following{/other_user}","gists_url":"https://api.github.com/users/ErisDS/gists{/gist_id}","starred_url":"https://api.github.com/users/ErisDS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ErisDS/subscriptions","organizations_url":"https://api.github.com/users/ErisDS/orgs","repos_url":"https://api.github.com/users/ErisDS/repos","events_url":"https://api.github.com/users/ErisDS/events{/privacy}","received_events_url":"https://api.github.com/users/ErisDS/received_events","type":"User","site_admin":false},"body":"The idea here is I'm refactoring knexify to:\r\n\r\n1. move out some of the code that really should not be in it (I want to convert it to a plugin for bookshelf if possible)\r\n2. move the duplicate code that loops through statements and recursively loops through groups\r\n\r\nI'm doing some work inside of Ghost, and found myself repeating the same recursive loop pattern, and so I think it makes sense to add tools for doing that to gql, and then move the context-aware code back out of gql into Ghost, but using these tools.\r\n\r\n----\r\n\r\n### Functionality:\r\n\r\nThe two tools provided here are `eachStatement` and `findStatement`. \r\n\r\n`eachStatement` takes a set of statements and a function to call for each statement. It optionally also takes an extra function to call for each group. It is used in knexify both with and without the optional group function, here's the simple example:\r\n\r\n```\r\neachStatement(filter.statements, function (statement) {\r\n    statement.prop = processProperty(statement.prop);\r\n});\r\n```\r\n\r\n`findStatement` takes a set of statements, and then an object with the key value pairs you want to match. E.g. calling `findStatement(statements, {prop: 'page'})` would return true if any statement has `prop: 'page'` in it.\r\n\r\nIn some cases, you might want to pass it an entire statement to match against, and define which keys are the ones you care about.\r\n\r\nE.g. calling `findStatement(statements, {prop: 'page', op: '=', value: true}, 'prop')` would do exactly the same as the previous example. \r\n\r\nYou can pass arrays as the final arg to findStatement, or regexes as values also works e.g. ``findStatement(statements, {prop:  /^tags/, op: 'IN', value: 'stuff'}, ['prop', 'op'])` will return true if there is a statement which has a prop starting with 'tags' and the operator 'IN'.\r\n\r\n---\r\n\r\n### Usage:\r\n\r\nThere are currently two ways that you 'could' use these functions externally (e.g. in Ghost) and in the vein of naming things is hard, I can't decide which I prefer.\r\n\r\nYou could do:\r\n\r\n```\r\nvar _ = require('lodash');\r\n_.mixin(require('ghost-gql').json);\r\n\r\n_.eachStatement(statements...);\r\n```\r\n\r\nOr you could do\r\n\r\n```\r\nvar gql = require('ghost-gql');\r\ngql.json.eachStatement(statements...);\r\n```\r\n\r\nThe `gql.json` part made sense to me as you're talking about the json format you get back from gql... however reading it back I'm not sure... perhaps I should just rename that to 'lodash' so that you get `_.mixin(require('ghost-gql').lodash);` or something similar.\r\n\r\n","created_at":"2015-11-10T22:37:32Z","updated_at":"2015-11-10T22:37:32Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/TryGhost/GQL/pulls/8/commits","review_comments_url":"https://api.github.com/repos/TryGhost/GQL/pulls/8/comments","review_comment_url":"https://api.github.com/repos/TryGhost/GQL/pulls/comments{/number}","comments_url":"https://api.github.com/repos/TryGhost/GQL/issues/8/comments","statuses_url":"https://api.github.com/repos/TryGhost/GQL/statuses/dd3b9b09dd4c6783caa2744b4bcde1fd6906a4ca","head":{"label":"ErisDS:add-findstatement","ref":"add-findstatement","sha":"dd3b9b09dd4c6783caa2744b4bcde1fd6906a4ca","user":{"login":"ErisDS","id":101513,"avatar_url":"https://avatars.githubusercontent.com/u/101513?v=3","gravatar_id":"","url":"https://api.github.com/users/ErisDS","html_url":"https://github.com/ErisDS","followers_url":"https://api.github.com/users/ErisDS/followers","following_url":"https://api.github.com/users/ErisDS/following{/other_user}","gists_url":"https://api.github.com/users/ErisDS/gists{/gist_id}","starred_url":"https://api.github.com/users/ErisDS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ErisDS/subscriptions","organizations_url":"https://api.github.com/users/ErisDS/orgs","repos_url":"https://api.github.com/users/ErisDS/repos","events_url":"https://api.github.com/users/ErisDS/events{/privacy}","received_events_url":"https://api.github.com/users/ErisDS/received_events","type":"User","site_admin":false},"repo":{"id":39654814,"name":"GQL","full_name":"ErisDS/GQL","owner":{"login":"ErisDS","id":101513,"avatar_url":"https://avatars.githubusercontent.com/u/101513?v=3","gravatar_id":"","url":"https://api.github.com/users/ErisDS","html_url":"https://github.com/ErisDS","followers_url":"https://api.github.com/users/ErisDS/followers","following_url":"https://api.github.com/users/ErisDS/following{/other_user}","gists_url":"https://api.github.com/users/ErisDS/gists{/gist_id}","starred_url":"https://api.github.com/users/ErisDS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ErisDS/subscriptions","organizations_url":"https://api.github.com/users/ErisDS/orgs","repos_url":"https://api.github.com/users/ErisDS/repos","events_url":"https://api.github.com/users/ErisDS/events{/privacy}","received_events_url":"https://api.github.com/users/ErisDS/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ErisDS/GQL","description":"Filter query language for working with Ghost's API","fork":true,"url":"https://api.github.com/repos/ErisDS/GQL","forks_url":"https://api.github.com/repos/ErisDS/GQL/forks","keys_url":"https://api.github.com/repos/ErisDS/GQL/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ErisDS/GQL/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ErisDS/GQL/teams","hooks_url":"https://api.github.com/repos/ErisDS/GQL/hooks","issue_events_url":"https://api.github.com/repos/ErisDS/GQL/issues/events{/number}","events_url":"https://api.github.com/repos/ErisDS/GQL/events","assignees_url":"https://api.github.com/repos/ErisDS/GQL/assignees{/user}","branches_url":"https://api.github.com/repos/ErisDS/GQL/branches{/branch}","tags_url":"https://api.github.com/repos/ErisDS/GQL/tags","blobs_url":"https://api.github.com/repos/ErisDS/GQL/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ErisDS/GQL/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ErisDS/GQL/git/refs{/sha}","trees_url":"https://api.github.com/repos/ErisDS/GQL/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ErisDS/GQL/statuses/{sha}","languages_url":"https://api.github.com/repos/ErisDS/GQL/languages","stargazers_url":"https://api.github.com/repos/ErisDS/GQL/stargazers","contributors_url":"https://api.github.com/repos/ErisDS/GQL/contributors","subscribers_url":"https://api.github.com/repos/ErisDS/GQL/subscribers","subscription_url":"https://api.github.com/repos/ErisDS/GQL/subscription","commits_url":"https://api.github.com/repos/ErisDS/GQL/commits{/sha}","git_commits_url":"https://api.github.com/repos/ErisDS/GQL/git/commits{/sha}","comments_url":"https://api.github.com/repos/ErisDS/GQL/comments{/number}","issue_comment_url":"https://api.github.com/repos/ErisDS/GQL/issues/comments{/number}","contents_url":"https://api.github.com/repos/ErisDS/GQL/contents/{+path}","compare_url":"https://api.github.com/repos/ErisDS/GQL/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ErisDS/GQL/merges","archive_url":"https://api.github.com/repos/ErisDS/GQL/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ErisDS/GQL/downloads","issues_url":"https://api.github.com/repos/ErisDS/GQL/issues{/number}","pulls_url":"https://api.github.com/repos/ErisDS/GQL/pulls{/number}","milestones_url":"https://api.github.com/repos/ErisDS/GQL/milestones{/number}","notifications_url":"https://api.github.com/repos/ErisDS/GQL/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ErisDS/GQL/labels{/name}","releases_url":"https://api.github.com/repos/ErisDS/GQL/releases{/id}","created_at":"2015-07-24T20:10:25Z","updated_at":"2015-07-24T13:29:04Z","pushed_at":"2015-11-10T22:09:31Z","git_url":"git://github.com/ErisDS/GQL.git","ssh_url":"git@github.com:ErisDS/GQL.git","clone_url":"https://github.com/ErisDS/GQL.git","svn_url":"https://github.com/ErisDS/GQL","homepage":null,"size":108,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"TryGhost:master","ref":"master","sha":"b3b51264e74ff197ec35489d8be2478640c9a1b3","user":{"login":"TryGhost","id":2178663,"avatar_url":"https://avatars.githubusercontent.com/u/2178663?v=3","gravatar_id":"","url":"https://api.github.com/users/TryGhost","html_url":"https://github.com/TryGhost","followers_url":"https://api.github.com/users/TryGhost/followers","following_url":"https://api.github.com/users/TryGhost/following{/other_user}","gists_url":"https://api.github.com/users/TryGhost/gists{/gist_id}","starred_url":"https://api.github.com/users/TryGhost/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TryGhost/subscriptions","organizations_url":"https://api.github.com/users/TryGhost/orgs","repos_url":"https://api.github.com/users/TryGhost/repos","events_url":"https://api.github.com/users/TryGhost/events{/privacy}","received_events_url":"https://api.github.com/users/TryGhost/received_events","type":"Organization","site_admin":false},"repo":{"id":39627251,"name":"GQL","full_name":"TryGhost/GQL","owner":{"login":"TryGhost","id":2178663,"avatar_url":"https://avatars.githubusercontent.com/u/2178663?v=3","gravatar_id":"","url":"https://api.github.com/users/TryGhost","html_url":"https://github.com/TryGhost","followers_url":"https://api.github.com/users/TryGhost/followers","following_url":"https://api.github.com/users/TryGhost/following{/other_user}","gists_url":"https://api.github.com/users/TryGhost/gists{/gist_id}","starred_url":"https://api.github.com/users/TryGhost/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TryGhost/subscriptions","organizations_url":"https://api.github.com/users/TryGhost/orgs","repos_url":"https://api.github.com/users/TryGhost/repos","events_url":"https://api.github.com/users/TryGhost/events{/privacy}","received_events_url":"https://api.github.com/users/TryGhost/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/TryGhost/GQL","description":"Filter query language for working with Ghost's API","fork":false,"url":"https://api.github.com/repos/TryGhost/GQL","forks_url":"https://api.github.com/repos/TryGhost/GQL/forks","keys_url":"https://api.github.com/repos/TryGhost/GQL/keys{/key_id}","collaborators_url":"https://api.github.com/repos/TryGhost/GQL/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/TryGhost/GQL/teams","hooks_url":"https://api.github.com/repos/TryGhost/GQL/hooks","issue_events_url":"https://api.github.com/repos/TryGhost/GQL/issues/events{/number}","events_url":"https://api.github.com/repos/TryGhost/GQL/events","assignees_url":"https://api.github.com/repos/TryGhost/GQL/assignees{/user}","branches_url":"https://api.github.com/repos/TryGhost/GQL/branches{/branch}","tags_url":"https://api.github.com/repos/TryGhost/GQL/tags","blobs_url":"https://api.github.com/repos/TryGhost/GQL/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/TryGhost/GQL/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/TryGhost/GQL/git/refs{/sha}","trees_url":"https://api.github.com/repos/TryGhost/GQL/git/trees{/sha}","statuses_url":"https://api.github.com/repos/TryGhost/GQL/statuses/{sha}","languages_url":"https://api.github.com/repos/TryGhost/GQL/languages","stargazers_url":"https://api.github.com/repos/TryGhost/GQL/stargazers","contributors_url":"https://api.github.com/repos/TryGhost/GQL/contributors","subscribers_url":"https://api.github.com/repos/TryGhost/GQL/subscribers","subscription_url":"https://api.github.com/repos/TryGhost/GQL/subscription","commits_url":"https://api.github.com/repos/TryGhost/GQL/commits{/sha}","git_commits_url":"https://api.github.com/repos/TryGhost/GQL/git/commits{/sha}","comments_url":"https://api.github.com/repos/TryGhost/GQL/comments{/number}","issue_comment_url":"https://api.github.com/repos/TryGhost/GQL/issues/comments{/number}","contents_url":"https://api.github.com/repos/TryGhost/GQL/contents/{+path}","compare_url":"https://api.github.com/repos/TryGhost/GQL/compare/{base}...{head}","merges_url":"https://api.github.com/repos/TryGhost/GQL/merges","archive_url":"https://api.github.com/repos/TryGhost/GQL/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/TryGhost/GQL/downloads","issues_url":"https://api.github.com/repos/TryGhost/GQL/issues{/number}","pulls_url":"https://api.github.com/repos/TryGhost/GQL/pulls{/number}","milestones_url":"https://api.github.com/repos/TryGhost/GQL/milestones{/number}","notifications_url":"https://api.github.com/repos/TryGhost/GQL/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/TryGhost/GQL/labels{/name}","releases_url":"https://api.github.com/repos/TryGhost/GQL/releases{/id}","created_at":"2015-07-24T10:48:20Z","updated_at":"2015-10-15T20:02:50Z","pushed_at":"2015-11-10T17:22:42Z","git_url":"git://github.com/TryGhost/GQL.git","ssh_url":"git@github.com:TryGhost/GQL.git","clone_url":"https://github.com/TryGhost/GQL.git","svn_url":"https://github.com/TryGhost/GQL","homepage":null,"size":195,"stargazers_count":5,"watchers_count":5,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":6,"forks":3,"open_issues":6,"watchers":5,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/TryGhost/GQL/pulls/8"},"html":{"href":"https://github.com/TryGhost/GQL/pull/8"},"issue":{"href":"https://api.github.com/repos/TryGhost/GQL/issues/8"},"comments":{"href":"https://api.github.com/repos/TryGhost/GQL/issues/8/comments"},"review_comments":{"href":"https://api.github.com/repos/TryGhost/GQL/pulls/8/comments"},"review_comment":{"href":"https://api.github.com/repos/TryGhost/GQL/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/TryGhost/GQL/pulls/8/commits"},"statuses":{"href":"https://api.github.com/repos/TryGhost/GQL/statuses/dd3b9b09dd4c6783caa2744b4bcde1fd6906a4ca"}},"merged":false,"mergeable":null,"mergeable_state":"unknown","merged_by":null,"comments":0,"review_comments":0,"commits":2,"additions":378,"deletions":61,"changed_files":5}}