GitHub PullRequestReviewCommentEvent at 2014-11-13 18:27:30
Repository: elysium
Actor: elvisinaka
Payload: {"action":"created","comment":{"url":"https://api.github.com/repos/inaka/elysium/pulls/comments/20311464","id":20311464,"diff_hunk":"@@ -0,0 +1,325 @@\n+%%% Copyright 2014 Aleksey Yeschenko\n+%%%\n+%%% Licensed under the Apache License, Version 2.0 (the \"License\");\n+%%% you may not use this file except in compliance with the License.\n+%%% You may obtain a copy of the License at\n+%%%\n+%%%     http://www.apache.org/licenses/LICENSE-2.0\n+%%%\n+%%% Unless required by applicable law or agreed to in writing, software\n+%%% distributed under the License is distributed on an \"AS IS\" BASIS,\n+%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+%%% See the License for the specific language governing permissions and\n+%%% limitations under the License.\n+\n+%%% Forked as a modified copy of seestar_session to remove multiplexed\n+%%% session channels and to allow gen_server and gen_tcp timeouts.\n+\n+-module(elysium_channel).\n+\n+-behaviour(gen_server).\n+\n+-include_lib(\"seestar/src/seestar_messages.hrl\").\n+-include_lib(\"seestar/include/builtin_types.hrl\").\n+-include_lib(\"seestar/include/buffer.hrl\").\n+\n+%% API exports.\n+-export([start_link/2, start_link/3, start_link/4, stop/1]).\n+-export([perform/3, perform_async/3]).\n+-export([prepare/2, execute/5, execute_async/5]).\n+\n+%% gen_server exports.\n+-export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2,\n+         code_change/3]).\n+\n+-type credentials() :: [{string() | binary(), string() | binary()}].\n+-type events() :: [topology_change | status_change | schema_change].\n+-type client_option() :: {keyspace, string() | binary()}\n+                       | {credentials, credentials()}\n+                       | {events, events()}\n+                       | {send_timeout, non_neg_integer()}.\n+\n+-type connect_option() :: gen_tcp:connect_option() | {connect_timeout, timeout()}.\n+\n+-type 'query'() :: binary() | string().\n+-type query_id() :: binary().\n+\n+-define(b2l(Term), case is_binary(Term) of true -> binary_to_list(Term); false -> Term end).\n+-define(l2b(Term), case is_list(Term) of true -> list_to_binary(Term); false -> Term end).\n+\n+-record(req,\n+        {op   :: seestar_frame:opcode(),\n+         body :: binary(),\n+         from :: {pid(), reference()},\n+         sync = true :: boolean()\n+        }).\n+\n+-record(st,\n+        {host   :: inet:hostname(),\n+         sock   :: inet:socket(),\n+         buffer :: seestar_buffer:buffer(),\n+         from   :: {pid(), reference()},\n+         sync   :: boolean()\n+        }).\n+\n+%% -------------------------------------------------------------------------\n+%% API\n+%% -------------------------------------------------------------------------\n+\n+%% @equiv start_link(Host, Post, [])\n+-spec start_link(inet:hostname(), inet:port_number()) ->\n+    any().\n+start_link(Host, Port) ->\n+    start_link(Host, Port, []).\n+\n+%% @equiv start_link(Host, Post, ClientOptions, [])\n+-spec start_link(inet:hostname(), inet:port_number(), [client_option()]) ->\n+    any().\n+start_link(Host, Port, ClientOptions) ->\n+    start_link(Host, Port, ClientOptions, []).\n+\n+-spec start_link(inet:hostname(), inet:port_number(), [client_option()], [connect_option()]) ->\n+    any().\n+start_link(Host, Port, ClientOptions, ConnectOptions) ->\n+     case gen_server:start_link(?MODULE, [Host, Port, ConnectOptions], []) of\n+        {ok, Pid} ->\n+            case setup(Pid, ClientOptions) of\n+                ok    -> {ok, Pid};\n+                Error -> stop(Pid), Error\n+            end;\n+        Error ->\n+            Error\n+    end.\n+\n+setup(Pid, Options) ->\n+    case authenticate(Pid, Options) of\n+        false ->\n+            {error, invalid_credentials};\n+        true ->\n+            case set_keyspace(Pid, Options) of\n+                false ->\n+                    {error, invalid_keyspace};\n+                true ->\n+                    case subscribe(Pid, Options) of\n+                        false -> {error, invalid_events};\n+                        true  -> ok\n+                    end\n+            end\n+    end.\n+\n+authenticate(Pid, Options) ->\n+    Credentials = proplists:get_value(credentials, Options),\n+    case request(Pid, #startup{}, true) of\n+        #ready{} ->\n+            true;\n+        #authenticate{} when Credentials =:= undefined ->\n+            false;\n+        #authenticate{} ->\n+            KVPairs = [ {?l2b(K), ?l2b(V)} || {K, V} <- Credentials ],\n+            case request(Pid, #credentials{credentials = KVPairs}, true) of\n+                #ready{} -> true;\n+                #error{} -> false\n+            end\n+    end.\n+\n+set_keyspace(Pid, Options) ->\n+    case proplists:get_value(keyspace, Options) of\n+        undefined ->\n+            true;\n+        Keyspace ->\n+            case perform(Pid, \"USE \" ++ ?b2l(Keyspace), one) of\n+                {ok, _Result}    -> true;\n+                {error, _Reason} -> false\n+            end\n+    end.\n+\n+subscribe(Pid, Options) ->\n+    case proplists:get_value(events, Options, []) of\n+        [] ->\n+            true;\n+        Events ->\n+            case request(Pid, #register{event_types = Events}, true) of\n+                #ready{} -> true;\n+                #error{} -> false\n+            end\n+    end.\n+\n+%% @doc Stop the client.\n+%% Closes the socket and terminates the process normally.\n+-spec stop(pid()) -> ok.\n+stop(Client) ->\n+    gen_server:cast(Client, stop).\n+\n+%% @doc Synchoronously perform a CQL query using the specified consistency level.\n+%% Returns a result of an appropriate type (void, rows, set_keyspace, schema_change).\n+%% Use {@link seestar_result} module functions to work with the result.\n+-spec perform(pid(), 'query'(), seestar:consistency()) ->\n+    {ok, Result :: seestar_result:result()} | {error, Error :: seestar_error:error()} | busy.\n+perform(Client, Query, Consistency) ->\n+    case request(Client, #'query'{'query' = ?l2b(Query), consistency = Consistency}, true) of\n+        #result{result = Result} ->\n+            {ok, Result};\n+        #error{} = Error ->\n+            {error, Error};\n+        busy ->\n+            busy\n+    end.\n+\n+%% TODO doc\n+%% @doc Asynchronously perform a CQL query using the specified consistency level.\n+-spec perform_async(pid(), 'query'(), seestar:consistency()) -> ok | busy.\n+perform_async(Client, Query, Consistency) ->\n+    Req = #'query'{'query' = ?l2b(Query), consistency = Consistency},\n+    request(Client, Req, false).\n+\n+%% @doc Prepare a query for later execution. The response will contain the prepared\n+%% query id and column metadata for all the variables (if any).\n+%% @see execute/3.\n+%% @see execute/4.\n+-spec prepare(pid(), 'query'()) ->\n+    {ok, Result :: seestar_result:prepared_result()} | {error, Error :: seestar_error:error()} | busy.\n+prepare(Client, Query) ->\n+    case request(Client, #prepare{'query' = ?l2b(Query)}, true) of\n+        #result{result = Result} ->\n+            {ok, Result};\n+        #error{} = Error ->\n+            {error, Error};\n+        busy ->\n+            busy\n+    end.\n+\n+%% @doc Synchronously execute a prepared query using the specified consistency level.\n+%% Use {@link seestar_result} module functions to work with the result.\n+%% @see prepare/2.\n+%% @see perform/3.\n+-spec execute(pid(), query_id(),\n+              [seestar_cqltypes:type()], [seestar_cqltypes:value()], seestar:consistency()) ->\n+        {ok, Result :: seestar_result:result()} | {error, Error :: seestar_error:error()} | busy.","path":"src/elysium_channel.erl","position":197,"original_position":197,"commit_id":"37cca477d0beb04f75c5062b03155b11ac33fbdd","original_commit_id":"37cca477d0beb04f75c5062b03155b11ac33fbdd","user":{"login":"elvisinaka","id":8136322,"avatar_url":"https://avatars.githubusercontent.com/u/8136322?v=3","gravatar_id":"","url":"https://api.github.com/users/elvisinaka","html_url":"https://github.com/elvisinaka","followers_url":"https://api.github.com/users/elvisinaka/followers","following_url":"https://api.github.com/users/elvisinaka/following{/other_user}","gists_url":"https://api.github.com/users/elvisinaka/gists{/gist_id}","starred_url":"https://api.github.com/users/elvisinaka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elvisinaka/subscriptions","organizations_url":"https://api.github.com/users/elvisinaka/orgs","repos_url":"https://api.github.com/users/elvisinaka/repos","events_url":"https://api.github.com/users/elvisinaka/events{/privacy}","received_events_url":"https://api.github.com/users/elvisinaka/received_events","type":"User","site_admin":false},"body":"Line 197 is too long: \"        {ok, Result :: seestar_result:result()} | {error, Error :: seestar_error:error()} | busy.\".","created_at":"2014-11-13T18:27:30Z","updated_at":"2014-11-13T18:27:30Z","html_url":"https://github.com/inaka/elysium/pull/1#discussion_r20311464","pull_request_url":"https://api.github.com/repos/inaka/elysium/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/inaka/elysium/pulls/comments/20311464"},"html":{"href":"https://github.com/inaka/elysium/pull/1#discussion_r20311464"},"pull_request":{"href":"https://api.github.com/repos/inaka/elysium/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/inaka/elysium/pulls/1","id":24389247,"html_url":"https://github.com/inaka/elysium/pull/1","diff_url":"https://github.com/inaka/elysium/pull/1.diff","patch_url":"https://github.com/inaka/elysium/pull/1.patch","issue_url":"https://api.github.com/repos/inaka/elysium/issues/1","number":1,"state":"open","locked":false,"title":"Up to date","user":{"login":"HernanRivasAcosta","id":5691671,"avatar_url":"https://avatars.githubusercontent.com/u/5691671?v=3","gravatar_id":"","url":"https://api.github.com/users/HernanRivasAcosta","html_url":"https://github.com/HernanRivasAcosta","followers_url":"https://api.github.com/users/HernanRivasAcosta/followers","following_url":"https://api.github.com/users/HernanRivasAcosta/following{/other_user}","gists_url":"https://api.github.com/users/HernanRivasAcosta/gists{/gist_id}","starred_url":"https://api.github.com/users/HernanRivasAcosta/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HernanRivasAcosta/subscriptions","organizations_url":"https://api.github.com/users/HernanRivasAcosta/orgs","repos_url":"https://api.github.com/users/HernanRivasAcosta/repos","events_url":"https://api.github.com/users/HernanRivasAcosta/events{/privacy}","received_events_url":"https://api.github.com/users/HernanRivasAcosta/received_events","type":"User","site_admin":false},"body":"","created_at":"2014-11-13T18:26:57Z","updated_at":"2014-11-13T18:27:30Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a72986d87e4cefc1039607628657465b2ad79a70","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/inaka/elysium/pulls/1/commits","review_comments_url":"https://api.github.com/repos/inaka/elysium/pulls/1/comments","review_comment_url":"https://api.github.com/repos/inaka/elysium/pulls/comments/{number}","comments_url":"https://api.github.com/repos/inaka/elysium/issues/1/comments","statuses_url":"https://api.github.com/repos/inaka/elysium/statuses/37cca477d0beb04f75c5062b03155b11ac33fbdd","head":{"label":"tigertext:master","ref":"master","sha":"37cca477d0beb04f75c5062b03155b11ac33fbdd","user":{"login":"tigertext","id":173280,"avatar_url":"https://avatars.githubusercontent.com/u/173280?v=3","gravatar_id":"","url":"https://api.github.com/users/tigertext","html_url":"https://github.com/tigertext","followers_url":"https://api.github.com/users/tigertext/followers","following_url":"https://api.github.com/users/tigertext/following{/other_user}","gists_url":"https://api.github.com/users/tigertext/gists{/gist_id}","starred_url":"https://api.github.com/users/tigertext/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tigertext/subscriptions","organizations_url":"https://api.github.com/users/tigertext/orgs","repos_url":"https://api.github.com/users/tigertext/repos","events_url":"https://api.github.com/users/tigertext/events{/privacy}","received_events_url":"https://api.github.com/users/tigertext/received_events","type":"Organization","site_admin":false},"repo":{"id":24917017,"name":"elysium","full_name":"tigertext/elysium","owner":{"login":"tigertext","id":173280,"avatar_url":"https://avatars.githubusercontent.com/u/173280?v=3","gravatar_id":"","url":"https://api.github.com/users/tigertext","html_url":"https://github.com/tigertext","followers_url":"https://api.github.com/users/tigertext/followers","following_url":"https://api.github.com/users/tigertext/following{/other_user}","gists_url":"https://api.github.com/users/tigertext/gists{/gist_id}","starred_url":"https://api.github.com/users/tigertext/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tigertext/subscriptions","organizations_url":"https://api.github.com/users/tigertext/orgs","repos_url":"https://api.github.com/users/tigertext/repos","events_url":"https://api.github.com/users/tigertext/events{/privacy}","received_events_url":"https://api.github.com/users/tigertext/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/tigertext/elysium","description":"The blessed and happy erlang afterlife for Cassandra","fork":true,"url":"https://api.github.com/repos/tigertext/elysium","forks_url":"https://api.github.com/repos/tigertext/elysium/forks","keys_url":"https://api.github.com/repos/tigertext/elysium/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tigertext/elysium/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tigertext/elysium/teams","hooks_url":"https://api.github.com/repos/tigertext/elysium/hooks","issue_events_url":"https://api.github.com/repos/tigertext/elysium/issues/events{/number}","events_url":"https://api.github.com/repos/tigertext/elysium/events","assignees_url":"https://api.github.com/repos/tigertext/elysium/assignees{/user}","branches_url":"https://api.github.com/repos/tigertext/elysium/branches{/branch}","tags_url":"https://api.github.com/repos/tigertext/elysium/tags","blobs_url":"https://api.github.com/repos/tigertext/elysium/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tigertext/elysium/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tigertext/elysium/git/refs{/sha}","trees_url":"https://api.github.com/repos/tigertext/elysium/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tigertext/elysium/statuses/{sha}","languages_url":"https://api.github.com/repos/tigertext/elysium/languages","stargazers_url":"https://api.github.com/repos/tigertext/elysium/stargazers","contributors_url":"https://api.github.com/repos/tigertext/elysium/contributors","subscribers_url":"https://api.github.com/repos/tigertext/elysium/subscribers","subscription_url":"https://api.github.com/repos/tigertext/elysium/subscription","commits_url":"https://api.github.com/repos/tigertext/elysium/commits{/sha}","git_commits_url":"https://api.github.com/repos/tigertext/elysium/git/commits{/sha}","comments_url":"https://api.github.com/repos/tigertext/elysium/comments{/number}","issue_comment_url":"https://api.github.com/repos/tigertext/elysium/issues/comments/{number}","contents_url":"https://api.github.com/repos/tigertext/elysium/contents/{+path}","compare_url":"https://api.github.com/repos/tigertext/elysium/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tigertext/elysium/merges","archive_url":"https://api.github.com/repos/tigertext/elysium/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tigertext/elysium/downloads","issues_url":"https://api.github.com/repos/tigertext/elysium/issues{/number}","pulls_url":"https://api.github.com/repos/tigertext/elysium/pulls{/number}","milestones_url":"https://api.github.com/repos/tigertext/elysium/milestones{/number}","notifications_url":"https://api.github.com/repos/tigertext/elysium/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tigertext/elysium/labels{/name}","releases_url":"https://api.github.com/repos/tigertext/elysium/releases{/id}","created_at":"2014-10-08T00:02:02Z","updated_at":"2014-10-15T21:47:30Z","pushed_at":"2014-11-13T06:07:18Z","git_url":"git://github.com/tigertext/elysium.git","ssh_url":"git@github.com:tigertext/elysium.git","clone_url":"https://github.com/tigertext/elysium.git","svn_url":"https://github.com/tigertext/elysium","homepage":null,"size":675,"stargazers_count":0,"watchers_count":0,"language":"Erlang","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":0,"forks":2,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"inaka:master","ref":"master","sha":"cdd4be536f0a749ee4b48d6e5d9036ab33c39e28","user":{"login":"inaka","id":867053,"avatar_url":"https://avatars.githubusercontent.com/u/867053?v=3","gravatar_id":"","url":"https://api.github.com/users/inaka","html_url":"https://github.com/inaka","followers_url":"https://api.github.com/users/inaka/followers","following_url":"https://api.github.com/users/inaka/following{/other_user}","gists_url":"https://api.github.com/users/inaka/gists{/gist_id}","starred_url":"https://api.github.com/users/inaka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/inaka/subscriptions","organizations_url":"https://api.github.com/users/inaka/orgs","repos_url":"https://api.github.com/users/inaka/repos","events_url":"https://api.github.com/users/inaka/events{/privacy}","received_events_url":"https://api.github.com/users/inaka/received_events","type":"Organization","site_admin":false},"repo":{"id":25830237,"name":"elysium","full_name":"inaka/elysium","owner":{"login":"inaka","id":867053,"avatar_url":"https://avatars.githubusercontent.com/u/867053?v=3","gravatar_id":"","url":"https://api.github.com/users/inaka","html_url":"https://github.com/inaka","followers_url":"https://api.github.com/users/inaka/followers","following_url":"https://api.github.com/users/inaka/following{/other_user}","gists_url":"https://api.github.com/users/inaka/gists{/gist_id}","starred_url":"https://api.github.com/users/inaka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/inaka/subscriptions","organizations_url":"https://api.github.com/users/inaka/orgs","repos_url":"https://api.github.com/users/inaka/repos","events_url":"https://api.github.com/users/inaka/events{/privacy}","received_events_url":"https://api.github.com/users/inaka/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/inaka/elysium","description":"The blessed and happy erlang afterlife for Cassandra","fork":true,"url":"https://api.github.com/repos/inaka/elysium","forks_url":"https://api.github.com/repos/inaka/elysium/forks","keys_url":"https://api.github.com/repos/inaka/elysium/keys{/key_id}","collaborators_url":"https://api.github.com/repos/inaka/elysium/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/inaka/elysium/teams","hooks_url":"https://api.github.com/repos/inaka/elysium/hooks","issue_events_url":"https://api.github.com/repos/inaka/elysium/issues/events{/number}","events_url":"https://api.github.com/repos/inaka/elysium/events","assignees_url":"https://api.github.com/repos/inaka/elysium/assignees{/user}","branches_url":"https://api.github.com/repos/inaka/elysium/branches{/branch}","tags_url":"https://api.github.com/repos/inaka/elysium/tags","blobs_url":"https://api.github.com/repos/inaka/elysium/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/inaka/elysium/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/inaka/elysium/git/refs{/sha}","trees_url":"https://api.github.com/repos/inaka/elysium/git/trees{/sha}","statuses_url":"https://api.github.com/repos/inaka/elysium/statuses/{sha}","languages_url":"https://api.github.com/repos/inaka/elysium/languages","stargazers_url":"https://api.github.com/repos/inaka/elysium/stargazers","contributors_url":"https://api.github.com/repos/inaka/elysium/contributors","subscribers_url":"https://api.github.com/repos/inaka/elysium/subscribers","subscription_url":"https://api.github.com/repos/inaka/elysium/subscription","commits_url":"https://api.github.com/repos/inaka/elysium/commits{/sha}","git_commits_url":"https://api.github.com/repos/inaka/elysium/git/commits{/sha}","comments_url":"https://api.github.com/repos/inaka/elysium/comments{/number}","issue_comment_url":"https://api.github.com/repos/inaka/elysium/issues/comments/{number}","contents_url":"https://api.github.com/repos/inaka/elysium/contents/{+path}","compare_url":"https://api.github.com/repos/inaka/elysium/compare/{base}...{head}","merges_url":"https://api.github.com/repos/inaka/elysium/merges","archive_url":"https://api.github.com/repos/inaka/elysium/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/inaka/elysium/downloads","issues_url":"https://api.github.com/repos/inaka/elysium/issues{/number}","pulls_url":"https://api.github.com/repos/inaka/elysium/pulls{/number}","milestones_url":"https://api.github.com/repos/inaka/elysium/milestones{/number}","notifications_url":"https://api.github.com/repos/inaka/elysium/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/inaka/elysium/labels{/name}","releases_url":"https://api.github.com/repos/inaka/elysium/releases{/id}","created_at":"2014-10-27T17:16:14Z","updated_at":"2014-10-15T21:47:30Z","pushed_at":"2014-10-27T17:16:47Z","git_url":"git://github.com/inaka/elysium.git","ssh_url":"git@github.com:inaka/elysium.git","clone_url":"https://github.com/inaka/elysium.git","svn_url":"https://github.com/inaka/elysium","homepage":null,"size":169,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/inaka/elysium/pulls/1"},"html":{"href":"https://github.com/inaka/elysium/pull/1"},"issue":{"href":"https://api.github.com/repos/inaka/elysium/issues/1"},"comments":{"href":"https://api.github.com/repos/inaka/elysium/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/inaka/elysium/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/inaka/elysium/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/inaka/elysium/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/inaka/elysium/statuses/37cca477d0beb04f75c5062b03155b11ac33fbdd"}}}}