{"action":"created","comment":{"url":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls/comments/212315609","pull_request_review_id":148919018,"id":212315609,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIxMjMxNTYwOQ==","diff_hunk":"@@ -881,4 +969,288 @@ private String pg(CQLTermNode node) throws QueryValidationException {\n     }\n     return index2sql(node.getIndex(), node, numberMatch);\n   }\n+\n+  /**\n+   * Normalize a term for FT searching. Escape quotes, masking, etc\n+   *\n+   * @param term\n+   * @return\n+   */\n+  private String FTTerm(String term) throws QueryValidationException {\n+    StringBuilder res = new StringBuilder();\n+    for (int i = 0; i < term.length(); i++) {\n+      // CQL specials\n+      char c = term.charAt(i);\n+      switch (c) {\n+        case '?':\n+          throw new QueryValidationException(\"CQL: single character mask unsupported (?)\");\n+        case '*':\n+          if (i == term.length() - 1) {\n+            res.append(\":*\");\n+            continue;\n+          } else {\n+            throw new QueryValidationException(\"CQL: only right truncation supported\");\n+          }\n+        case '\\\\':\n+          if (i == term.length() - 1) {\n+            continue;\n+          }\n+          i++;\n+          c = term.charAt(i);\n+          break;\n+        case '^':\n+          throw new QueryValidationException(\"CQL: anchoring unsupported (^)\");\n+      }\n+      if (c == '\\'') {\n+        if (res.length() > 0) {\n+          res.append(\"''\"); // double up single quotes\n+        } // but not in the beginning of the term, won't work.\n+        continue;\n+      }\n+      // escape for FT\n+      if (\"&!|()<>*:\\\\\".indexOf(c) != -1) {\n+        res.append(\"\\\\\");\n+      }\n+      res.append(c);\n+    }\n+    return res.toString();\n+  }\n+\n+  /**\n+   * Translates a term node.\n+   *\n+   * @param node\n+   * @return\n+   * @throws QueryValidationException\n+   */\n+  private String pgFT(CQLTermNode node, JSONObject ftIndex, String index) throws QueryValidationException {\n+    String comparator = node.getRelation().getBase();\n+    if (!node.getRelation().getModifiers().isEmpty()) {\n+      throw new QueryValidationException(\"CQL: Unsupported modifier \"\n+        + node.getRelation().getModifiers().get(0).getType());\n+    }\n+    final String fld = index2sqlText(this.jsonField, index);\n+    if ((comparator.equals(\"=\") || comparator.equals(\"<>\")\n+      || comparator.equals(\"adj\") || comparator.equals(\"any\") || comparator.equals(\"all\"))\n+      && ftIndex != null) { // fulltext search\n+      if (node.getTerm().isEmpty() && (comparator.equals(\"=\") || comparator.equals(\"adj\")\n+        || comparator.equals(\"any\") || comparator.equals(\"all\"))) {\n+        // field = \"\" means that the field is defined, for any value, even empty\n+        String sql = fld + \" ~ ''\";\n+        logger.log(Level.FINE, \"pgFT(): special case: empty term ''='' {0}\", sql);\n+        return sql;\n+      }\n+      String[] words = node.getTerm().trim().split(\"\\\\s+\");  // split at whitespace\n+      for (int i = 0; i < words.length; i++) {\n+        words[i] = FTTerm(words[i]);\n+      }\n+      String tsTerm = \"\";\n+      switch (comparator) {\n+        case \"=\":\n+        case \"adj\":\n+          tsTerm = String.join(\"<->\", words);\n+          break;\n+        case \"any\":\n+          tsTerm = String.join(\" | \", words);\n+          break;\n+        case \"all\":\n+          tsTerm = String.join(\" & \", words);\n+          break;\n+        case \"<>\":\n+          tsTerm = \"!(\" + String.join(\"<->\", words) + \")\";\n+          break;\n+      }\n+      logger.log(Level.FINE, \"pgFT(): term={0} ts={1}\",\n+        new Object[]{node.getTerm(), tsTerm});\n+      return \"to_tsvector('english', \" + fld + \") \"\n+        + \"@@ to_tsquery('english','\" + tsTerm + \"')\";\n+    } else {\n+      return pgFtNonTs(index, node, comparator, fld);\n+    }\n+  }\n+\n+  private String pgFtNonTs(String index, CQLTermNode node, String comparator, final String fld) throws QueryValidationException {\n+    // not fulltext, regular search\n+    boolean found = false;\n+    for (String idxType : Arrays.asList(\"index\", \"uniqueIndex\", \"fullTextIndex\")) {\n+      if (dbTable.has(idxType)) {\n+        JSONArray indexArr = dbTable.getJSONArray(idxType);\n+        if (findItem(indexArr, \"fieldName\", index) != null) {\n+          found = true;\n+          logger.log(Level.FINE, \"pgFT(): Found {0} {1}\",\n+            new Object[]{idxType, index});\n+        }\n+      }\n+    }\n+    if (!found) {\n+      String sub = subQuery1FT(node, index);\n+      if (sub != null) {\n+        return sub;\n+      }\n+      sub = subQuery2FT(node, index);\n+      if (sub != null) {\n+        return sub;\n+      }\n+      throw new QueryValidationException(\"CQL: No index '\" + index + \"'\");\n+    }\n+    if ((comparator.equals(\"=\") && node.getTerm().isEmpty())) {\n+      // field = \"\" means that the field is defined, for any value, even empty\n+      // We should check if we have an index for the field, or a foreignKey\n+      // Is this the right place to handle this? For now, we only get here with\n+      // fulltext indexes, so this is ok.\n+      String sql = fld + \" ~ ''\";\n+      logger.log(Level.FINE, \"pgFT(): special case: empty term ''='' {0}\", sql);\n+      return sql;\n+    }\n+    switch (comparator) {\n+      case \"==\":\n+        comparator = \"=\";\n+        break;\n+      case \"=\": // exact match\n+      case \"<>\":\n+      case \"<\":\n+      case \"<=\":\n+      case \">\":\n+      case \">=\":\n+        break;\n+      default:\n+        throw new QueryValidationException(\"CQL: Unknown comparator '\" + comparator + \"'\");\n+    }\n+    String sql = fld + \" \" + comparator + \" '\" + FTTerm(node.getTerm()) + \"'\";\n+    // Quote escaping? Truncation? Special characters?\n+    // Should not use full FTTerm, it does truncation etc in a funny way\n+    logger.log(Level.FINE, \"pgFT():  sql={0} in={1} js={2}\",\n+      new Object[]{sql, fld, this.jsonField});\n+    return sql;\n+  }\n+\n+  /**\n+   * Handle a subquery. For example when searching an item, by a material type\n+   * name.\n+   *\n+   * cql: materialtype.name = \"book\"\n+   *\n+   * sql: materialtypeid in (select id from materialtype where name = \"book\")\n+   *\n+   * @param node\n+   * @param index\n+   * @return\n+   * @throws QueryValidationException\n+   */\n+  private String subQuery1FT(CQLTermNode node, String index) throws QueryValidationException {\n+    //System.out.println(\"CQL2PgJSON.subQuery1FT() starting: \" + node.toCQL())\n+    String[] idxParts = index.split(\"\\\\.\");\n+    if (idxParts.length != 2) {\n+      logger.log(Level.SEVERE, \"subQuery1FT(): needs two-part index name, not ''{0}''\", index);\n+      return null;\n+    }\n+    if (!dbTable.has(\"foreignKeys\")) {\n+      logger.log(Level.SEVERE, \"subQuery1FT(): No foreign keys defined for ''{0}''\", dbTable.getString(\"tableName\"));\n+      return null;\n+    }\n+    JSONObject fkey = findItem(dbTable.getJSONArray(\"foreignKeys\"),\n+      \"targetTable\", idxParts[0]);\n+    //System.out.println(\"CQL2PgJSON.subQuery1FT(): Found foreignKey '\" + fkey)\n+\n+    if (fkey == null) {\n+      logger.log(Level.SEVERE, \"subQuery1FT(): No foreignKey ''{0}'' found\", idxParts[0]);\n+      return null;\n+    }\n+    if (!fkey.has(\"fieldName\") || !fkey.has(\"targetTable\")) {\n+      logger.log(Level.SEVERE, \"subQuery1FT(): Malformed foreignKey section {0}\", fkey);\n+      return null;\n+    }\n+    String fkField = fkey.getString(\"fieldName\"); // tagId\n+    String fkTable = fkey.getString(\"targetTable\");  // tags\n+    try {\n+      // This is nasty. Make a new constructor that takes the dbSchema as a JsonObject,\n+      // so we don't need to convert back and forth! Also, get the .jsonb right!\n+      CQL2PgJSON c = new CQL2PgJSON(fkTable + \".jsonb\", dbSchema.toString());\n+      String term = node.getTerm();\n+      if (term.isEmpty()) {\n+        term = \"\\\"\\\"\";\n+      }\n+      String subCql = idxParts[1] + \" \" + node.getRelation() + \" \" + term;\n+      //System.out.println(\"CQL2PgJSON.subQuery1FT() sub cql: \" + subCql)\n+      String subSql = c.cql2pgJson(subCql);\n+      //System.out.println(\"CQL2PgJSON.subQuery1FT() sub sql: \" + subSql)\n+      String fld = index2sqlText(this.jsonField, fkField);\n+      String sql = fld + \" in ( SELECT jsonb->>'id' from \" + fkTable","path":"src/main/java/org/z3950/zing/cql/cql2pgjson/CQL2PgJSON.java","position":357,"original_position":357,"commit_id":"43025785b46d38ecaf33080f082fee33d872dffd","original_commit_id":"43025785b46d38ecaf33080f082fee33d872dffd","user":{"login":"id-jenkins","id":16718781,"node_id":"MDQ6VXNlcjE2NzE4Nzgx","avatar_url":"https://avatars0.githubusercontent.com/u/16718781?v=4","gravatar_id":"","url":"https://api.github.com/users/id-jenkins","html_url":"https://github.com/id-jenkins","followers_url":"https://api.github.com/users/id-jenkins/followers","following_url":"https://api.github.com/users/id-jenkins/following{/other_user}","gists_url":"https://api.github.com/users/id-jenkins/gists{/gist_id}","starred_url":"https://api.github.com/users/id-jenkins/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/id-jenkins/subscriptions","organizations_url":"https://api.github.com/users/id-jenkins/orgs","repos_url":"https://api.github.com/users/id-jenkins/repos","events_url":"https://api.github.com/users/id-jenkins/events{/privacy}","received_events_url":"https://api.github.com/users/id-jenkins/received_events","type":"User","site_admin":false},"body":"![MINOR](https://sonarsource.github.io/sonar-github/severity-minor.png 'Severity: MINOR') Immediately return this expression instead of assigning it to the temporary variable \"sql\". [![rule](https://sonarsource.github.io/sonar-github/rule.png)](https://sonarcloud.io/coding_rules#rule_key=squid%3AS1488)\n","created_at":"2018-08-23T13:48:38Z","updated_at":"2018-08-23T13:48:38Z","html_url":"https://github.com/folio-org/cql2pgjson-java/pull/68#discussion_r212315609","pull_request_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls/68","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls/comments/212315609"},"html":{"href":"https://github.com/folio-org/cql2pgjson-java/pull/68#discussion_r212315609"},"pull_request":{"href":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls/68"}}},"pull_request":{"url":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls/68","id":210435306,"node_id":"MDExOlB1bGxSZXF1ZXN0MjEwNDM1MzA2","html_url":"https://github.com/folio-org/cql2pgjson-java/pull/68","diff_url":"https://github.com/folio-org/cql2pgjson-java/pull/68.diff","patch_url":"https://github.com/folio-org/cql2pgjson-java/pull/68.patch","issue_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/issues/68","number":68,"state":"open","locked":false,"title":"re-implement the fulltext query translation","user":{"login":"heikkilevanto","id":13780339,"node_id":"MDQ6VXNlcjEzNzgwMzM5","avatar_url":"https://avatars1.githubusercontent.com/u/13780339?v=4","gravatar_id":"","url":"https://api.github.com/users/heikkilevanto","html_url":"https://github.com/heikkilevanto","followers_url":"https://api.github.com/users/heikkilevanto/followers","following_url":"https://api.github.com/users/heikkilevanto/following{/other_user}","gists_url":"https://api.github.com/users/heikkilevanto/gists{/gist_id}","starred_url":"https://api.github.com/users/heikkilevanto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/heikkilevanto/subscriptions","organizations_url":"https://api.github.com/users/heikkilevanto/orgs","repos_url":"https://api.github.com/users/heikkilevanto/repos","events_url":"https://api.github.com/users/heikkilevanto/events{/privacy}","received_events_url":"https://api.github.com/users/heikkilevanto/received_events","type":"User","site_admin":false},"body":"Loads 'schema.json' and checks if we have a fulltext index on the given field,\r\nand (only) in that case makes a fullquery sql with tsvector stuff.","created_at":"2018-08-23T12:44:48Z","updated_at":"2018-08-23T13:48:38Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9456dd4a0e2672cb6eba5c5440d2b021c8f8c5ae","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls/68/commits","review_comments_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls/68/comments","review_comment_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls/comments{/number}","comments_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/issues/68/comments","statuses_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/statuses/43025785b46d38ecaf33080f082fee33d872dffd","head":{"label":"folio-org:fulltext","ref":"fulltext","sha":"43025785b46d38ecaf33080f082fee33d872dffd","user":{"login":"folio-org","id":16495055,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE2NDk1MDU1","avatar_url":"https://avatars2.githubusercontent.com/u/16495055?v=4","gravatar_id":"","url":"https://api.github.com/users/folio-org","html_url":"https://github.com/folio-org","followers_url":"https://api.github.com/users/folio-org/followers","following_url":"https://api.github.com/users/folio-org/following{/other_user}","gists_url":"https://api.github.com/users/folio-org/gists{/gist_id}","starred_url":"https://api.github.com/users/folio-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/folio-org/subscriptions","organizations_url":"https://api.github.com/users/folio-org/orgs","repos_url":"https://api.github.com/users/folio-org/repos","events_url":"https://api.github.com/users/folio-org/events{/privacy}","received_events_url":"https://api.github.com/users/folio-org/received_events","type":"Organization","site_admin":false},"repo":{"id":76249786,"node_id":"MDEwOlJlcG9zaXRvcnk3NjI0OTc4Ng==","name":"cql2pgjson-java","full_name":"folio-org/cql2pgjson-java","owner":{"login":"folio-org","id":16495055,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE2NDk1MDU1","avatar_url":"https://avatars2.githubusercontent.com/u/16495055?v=4","gravatar_id":"","url":"https://api.github.com/users/folio-org","html_url":"https://github.com/folio-org","followers_url":"https://api.github.com/users/folio-org/followers","following_url":"https://api.github.com/users/folio-org/following{/other_user}","gists_url":"https://api.github.com/users/folio-org/gists{/gist_id}","starred_url":"https://api.github.com/users/folio-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/folio-org/subscriptions","organizations_url":"https://api.github.com/users/folio-org/orgs","repos_url":"https://api.github.com/users/folio-org/repos","events_url":"https://api.github.com/users/folio-org/events{/privacy}","received_events_url":"https://api.github.com/users/folio-org/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/folio-org/cql2pgjson-java","description":"CQL to PostgreSQL JSON converter","fork":false,"url":"https://api.github.com/repos/folio-org/cql2pgjson-java","forks_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/forks","keys_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/keys{/key_id}","collaborators_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/teams","hooks_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/hooks","issue_events_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/issues/events{/number}","events_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/events","assignees_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/assignees{/user}","branches_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/branches{/branch}","tags_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/tags","blobs_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/git/refs{/sha}","trees_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/git/trees{/sha}","statuses_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/statuses/{sha}","languages_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/languages","stargazers_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/stargazers","contributors_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/contributors","subscribers_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/subscribers","subscription_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/subscription","commits_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/commits{/sha}","git_commits_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/git/commits{/sha}","comments_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/comments{/number}","issue_comment_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/issues/comments{/number}","contents_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/contents/{+path}","compare_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/compare/{base}...{head}","merges_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/merges","archive_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/downloads","issues_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/issues{/number}","pulls_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls{/number}","milestones_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/milestones{/number}","notifications_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/labels{/name}","releases_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/releases{/id}","deployments_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/deployments","created_at":"2016-12-12T11:19:35Z","updated_at":"2018-07-06T03:38:03Z","pushed_at":"2018-08-23T13:47:10Z","git_url":"git://github.com/folio-org/cql2pgjson-java.git","ssh_url":"git@github.com:folio-org/cql2pgjson-java.git","clone_url":"https://github.com/folio-org/cql2pgjson-java.git","svn_url":"https://github.com/folio-org/cql2pgjson-java","homepage":"http://www.indexdata.com/cql-java","size":311,"stargazers_count":1,"watchers_count":1,"language":"Java","has_issues":false,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":1,"watchers":1,"default_branch":"master"}},"base":{"label":"folio-org:master","ref":"master","sha":"c02ae4c0c0a54dd6fa9fb7b2a1e14cddabf62486","user":{"login":"folio-org","id":16495055,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE2NDk1MDU1","avatar_url":"https://avatars2.githubusercontent.com/u/16495055?v=4","gravatar_id":"","url":"https://api.github.com/users/folio-org","html_url":"https://github.com/folio-org","followers_url":"https://api.github.com/users/folio-org/followers","following_url":"https://api.github.com/users/folio-org/following{/other_user}","gists_url":"https://api.github.com/users/folio-org/gists{/gist_id}","starred_url":"https://api.github.com/users/folio-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/folio-org/subscriptions","organizations_url":"https://api.github.com/users/folio-org/orgs","repos_url":"https://api.github.com/users/folio-org/repos","events_url":"https://api.github.com/users/folio-org/events{/privacy}","received_events_url":"https://api.github.com/users/folio-org/received_events","type":"Organization","site_admin":false},"repo":{"id":76249786,"node_id":"MDEwOlJlcG9zaXRvcnk3NjI0OTc4Ng==","name":"cql2pgjson-java","full_name":"folio-org/cql2pgjson-java","owner":{"login":"folio-org","id":16495055,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE2NDk1MDU1","avatar_url":"https://avatars2.githubusercontent.com/u/16495055?v=4","gravatar_id":"","url":"https://api.github.com/users/folio-org","html_url":"https://github.com/folio-org","followers_url":"https://api.github.com/users/folio-org/followers","following_url":"https://api.github.com/users/folio-org/following{/other_user}","gists_url":"https://api.github.com/users/folio-org/gists{/gist_id}","starred_url":"https://api.github.com/users/folio-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/folio-org/subscriptions","organizations_url":"https://api.github.com/users/folio-org/orgs","repos_url":"https://api.github.com/users/folio-org/repos","events_url":"https://api.github.com/users/folio-org/events{/privacy}","received_events_url":"https://api.github.com/users/folio-org/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/folio-org/cql2pgjson-java","description":"CQL to PostgreSQL JSON converter","fork":false,"url":"https://api.github.com/repos/folio-org/cql2pgjson-java","forks_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/forks","keys_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/keys{/key_id}","collaborators_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/teams","hooks_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/hooks","issue_events_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/issues/events{/number}","events_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/events","assignees_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/assignees{/user}","branches_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/branches{/branch}","tags_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/tags","blobs_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/git/refs{/sha}","trees_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/git/trees{/sha}","statuses_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/statuses/{sha}","languages_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/languages","stargazers_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/stargazers","contributors_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/contributors","subscribers_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/subscribers","subscription_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/subscription","commits_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/commits{/sha}","git_commits_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/git/commits{/sha}","comments_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/comments{/number}","issue_comment_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/issues/comments{/number}","contents_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/contents/{+path}","compare_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/compare/{base}...{head}","merges_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/merges","archive_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/downloads","issues_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/issues{/number}","pulls_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls{/number}","milestones_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/milestones{/number}","notifications_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/labels{/name}","releases_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/releases{/id}","deployments_url":"https://api.github.com/repos/folio-org/cql2pgjson-java/deployments","created_at":"2016-12-12T11:19:35Z","updated_at":"2018-07-06T03:38:03Z","pushed_at":"2018-08-23T13:47:10Z","git_url":"git://github.com/folio-org/cql2pgjson-java.git","ssh_url":"git@github.com:folio-org/cql2pgjson-java.git","clone_url":"https://github.com/folio-org/cql2pgjson-java.git","svn_url":"https://github.com/folio-org/cql2pgjson-java","homepage":"http://www.indexdata.com/cql-java","size":311,"stargazers_count":1,"watchers_count":1,"language":"Java","has_issues":false,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":1,"watchers":1,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls/68"},"html":{"href":"https://github.com/folio-org/cql2pgjson-java/pull/68"},"issue":{"href":"https://api.github.com/repos/folio-org/cql2pgjson-java/issues/68"},"comments":{"href":"https://api.github.com/repos/folio-org/cql2pgjson-java/issues/68/comments"},"review_comments":{"href":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls/68/comments"},"review_comment":{"href":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/folio-org/cql2pgjson-java/pulls/68/commits"},"statuses":{"href":"https://api.github.com/repos/folio-org/cql2pgjson-java/statuses/43025785b46d38ecaf33080f082fee33d872dffd"}},"author_association":"NONE"}}
{"actor":{"display_login":"id-jenkins"}}