lib: introduce neo4j connector
[nit.git] / lib / neo4j / curl_json.nit
diff --git a/lib/neo4j/curl_json.nit b/lib/neo4j/curl_json.nit
new file mode 100644 (file)
index 0000000..77d3650
--- /dev/null
@@ -0,0 +1,182 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# cURL requests compatible with the JSON REST APIs.
+module curl_json
+
+import jsonable
+intrude import curl
+
+# An abstract request that defines most of the standard options for Neo4j REST API
+abstract class JsonCurlRequest
+       super CurlRequest
+       super CCurlCallbacks
+       super CurlCallbacksRegisterIntern
+
+       # REST API service URL
+       var url: String
+
+       init (url: String, curl: nullable Curl) do
+               self.url = url
+               self.curl = curl
+
+               init_headers
+       end
+
+       # OAuth token
+       var auth: nullable String writable
+
+       # User agent (is used by github to contact devs in case of problems)
+       # Eg. "Awesome-Octocat-App"
+       var user_agent: nullable String writable
+
+       # HTTP headers to send
+       var headers: nullable HeaderMap writable = null
+
+
+       # init HTTP headers for Neo4j REST API
+       protected fun init_headers do
+               headers = new HeaderMap
+               headers["Accept"] = "application/json; charset=UTF-8"
+               headers["Transfer-Encoding"] = "chunked"
+               if auth != null then
+                       headers["Authorization"] = "token {auth.to_s}"
+               end
+               if user_agent != null then
+                       headers["User-Agent"] = user_agent.to_s
+               end
+       end
+
+       redef fun execute do
+               init_headers
+               if not self.curl.is_ok then
+                       return answer_failure(0, "Curl instance is not correctly initialized")
+               end
+
+               var success_response = new CurlResponseSuccess
+               var callback_receiver: CurlCallbacks = success_response
+               if self.delegate != null then callback_receiver = self.delegate.as(not null)
+
+               var err
+
+               err = self.curl.prim_curl.easy_setopt(new CURLOption.follow_location, 1)
+               if not err.is_ok then return answer_failure(err.to_i, err.to_s)
+
+               err = self.curl.prim_curl.easy_setopt(new CURLOption.http_version, 1)
+               if not err.is_ok then return answer_failure(err.to_i, err.to_s)
+
+
+               err = self.curl.prim_curl.easy_setopt(new CURLOption.url, url)
+               if not err.is_ok then return answer_failure(err.to_i, err.to_s)
+
+               err = self.curl.prim_curl.register_callback(callback_receiver, new CURLCallbackType.header)
+               if not err.is_ok then return answer_failure(err.to_i, err.to_s)
+
+               err = self.curl.prim_curl.register_callback(callback_receiver, new CURLCallbackType.body)
+               if not err.is_ok then return answer_failure(err.to_i, err.to_s)
+
+               # HTTP Header
+               if self.headers != null then
+                       var headers_joined = self.headers.join_pairs(": ")
+                       err = self.curl.prim_curl.easy_setopt(
+                               new CURLOption.httpheader, headers_joined.to_curlslist)
+                       if not err.is_ok then return answer_failure(err.to_i, err.to_s)
+               end
+
+               var err_hook = execute_hook
+           if err_hook != null then return err_hook
+
+               var err_resp = perform
+               if err_resp != null then return err_resp
+
+               var st_code = self.curl.prim_curl.easy_getinfo_long(new CURLInfoLong.response_code)
+               if not st_code == null then success_response.status_code = st_code.response
+
+               return success_response
+       end
+
+       # Hook to implement in concrete requests
+       protected fun execute_hook: nullable CurlResponse do return null
+end
+
+# HTTP GET command
+class JsonGET
+       super JsonCurlRequest
+
+       redef fun execute_hook do
+               var err = self.curl.prim_curl.easy_setopt(new CURLOption.get, true)
+               if not err.is_ok then return answer_failure(err.to_i, err.to_s)
+               return null
+       end
+end
+
+# HTTP POST command that sends JSON data
+class JsonPOST
+       super JsonCurlRequest
+
+       var data: nullable Jsonable writable = null
+
+       redef fun init_headers do
+               super
+               headers["Content-Type"] = "application/json"
+       end
+
+       redef fun execute_hook do
+               var err = self.curl.prim_curl.easy_setopt(new CURLOption.post, true)
+               if not err.is_ok then return answer_failure(err.to_i, err.to_s)
+
+               if self.data != null then
+                       var postdatas = self.data.to_json
+                       err = self.curl.prim_curl.easy_setopt(new CURLOption.postfields, postdatas)
+                       if not err.is_ok then return answer_failure(err.to_i, err.to_s)
+               end
+               return null
+       end
+end
+
+# HTTP DELETE command
+class JsonDELETE
+       super JsonCurlRequest
+
+       redef fun execute_hook do
+               var err = self.curl.prim_curl.easy_setopt(new CURLOption.custom_request, "DELETE")
+               if not err.is_ok then return answer_failure(err.to_i, err.to_s)
+               return null
+       end
+end
+
+# HTTP PUT command that sends JSON data
+class JsonPUT
+       super JsonCurlRequest
+
+       var data: nullable Jsonable writable = null
+
+       redef fun init_headers do
+               super
+               headers["Content-Type"] = "application/json"
+       end
+
+       redef fun execute_hook do
+               var err = self.curl.prim_curl.easy_setopt(new CURLOption.custom_request, "PUT")
+               if not err.is_ok then return answer_failure(err.to_i, err.to_s)
+
+               if self.data != null then
+                       var postdatas = self.data.to_json
+                       err = self.curl.prim_curl.easy_setopt(new CURLOption.postfields, postdatas)
+                       if not err.is_ok then return answer_failure(err.to_i, err.to_s)
+               end
+               return null
+       end
+end
+