{"action":"created","comment":{"url":"https://api.github.com/repos/CartoDB/cartodb/pulls/comments/65141447","id":65141447,"diff_hunk":"@@ -79,30 +84,189 @@ def fix_oid(table_name)\n       end\n \n       def cartodbfy(table_name)\n+        schema_name = user.database_schema\n+        qualified_table_name = \"\\\"#{schema_name}\\\".#{table_name}\"\n+\n+        type = fix_the_geom_type!(schema_name, table_name)\n+        import_cleanup(schema_name, table_name)\n+\n+        user.transaction_with_timeout(statement_timeout: STATEMENT_TIMEOUT) do |user_conn|\n+          user_conn.run(%Q{\n+            SELECT cartodb.CDB_CartodbfyTable('#{schema_name}'::TEXT,'#{qualified_table_name}'::REGCLASS);\n+          })\n+        end\n+\n+        update_table_pg_stats(qualified_table_name)\n+        return type\n+      rescue => exception\n+        CartoDB::Logger.error(message: 'Error in sync cartodbfy',\n+                              exception: exception,\n+                              user: user,\n+                              table: table_name)\n+        drop(result.table_name) if exists?(result.table_name)\n+        raise exception\n+      end\n+\n+      def update_table_pg_stats(qualified_table_name)\n+        user.transaction_with_timeout(statement_timeout: STATEMENT_TIMEOUT) do |user_conn|\n+          user_conn.run(%Q{\n+            ANALYZE #{qualified_table_name};\n+          })\n+        end\n+      end\n+\n+      def setup_table(table_name, geo_type)\n         table = user.tables.where(name: table_name).first.service\n \n         table.force_schema = true\n \n         table.import_to_cartodb(table_name)\n         table.schema(reload: true)\n-\n-        table.send :set_the_geom_column!\n-        table.import_cleanup\n-\n-        table.send :cartodbfy\n-        table.schema(reload: true)\n         table.reload\n \n-        table.send :update_table_pg_stats\n+        # We send the detected geometry type to avoid manipulating geoms twice\n+        # set_the_geom_column! should just edit the metadata with the specified type\n+        table.send :set_the_geom_column!, geo_type\n         table.save\n       rescue => exception\n-        CartoDB::Logger.error(message: 'Error in sync cartodbfy',\n+        CartoDB::Logger.error(message: 'Error in setup cartodbfy',\n                               exception: exception,\n                               user: user,\n                               table: table_name)\n       ensure\n         fix_oid(table_name)\n-        update_cdb_tablemetadata(table_name)\n+      end\n+\n+      # From Table#get_the_geom_type!, adapted to unregistered tables\n+      # returns type to run Table#get_the_geom_type! afterwards again, which\n+      # saves the type in table metadata\n+      def fix_the_geom_type!(schema_name, table_name)\n+        qualified_table_name = \"\\\"#{schema_name}\\\".#{table_name}\"\n+\n+        type = nil\n+        the_geom_data = user.in_database[%Q{\n+          SELECT a.attname, t.typname\n+          FROM pg_attribute a, pg_type t\n+          WHERE attrelid = '#{qualified_table_name}'::regclass\n+          AND attname = '#{THE_GEOM}'\n+          AND a.atttypid = t.oid\n+          AND a.attstattarget < 0\n+          LIMIT 1\n+        }].first\n+        return nil unless the_geom_data\n+\n+        if the_geom_data[:typname] != 'geometry'\n+          user.in_database.rename_column(qualified_table_name, THE_GEOM, :the_geom_str)\n+          return nil\n+        end\n+\n+        geom_type = user.in_database[%Q{\n+          SELECT GeometryType(#{THE_GEOM})\n+          FROM #{qualified_table_name}\n+          WHERE #{THE_GEOM} IS NOT null\n+          LIMIT 1\n+        }].first\n+\n+        type = geom_type[:geometrytype].to_s.downcase if geom_type\n+\n+        # if the geometry is MULTIPOINT we convert it to POINT\n+        if type == 'multipoint'\n+          user.db_service.in_database_direct_connection(statement_timeout: STATEMENT_TIMEOUT) do |user_database|\n+            user_database.run(\"SELECT public.AddGeometryColumn('#{schema_name}', '#{table_name}','the_geom_simple',4326, 'GEOMETRY', 2);\")\n+            user_database.run(%Q{UPDATE #{qualified_table_name} SET the_geom_simple = ST_GeometryN(the_geom,1);})\n+            user_database.run(\"SELECT DropGeometryColumn('#{schema_name}', '#{table_name}','the_geom');\")\n+            user_database.run(%Q{ALTER TABLE #{qualified_table_name} RENAME COLUMN the_geom_simple TO the_geom;})\n+          end\n+          type = 'point'\n+        end\n+\n+        # if the geometry is LINESTRING or POLYGON we convert it to MULTILINESTRING or MULTIPOLYGON\n+        if %w(linestring polygon).include?(type)\n+          user.db_service.in_database_direct_connection(statement_timeout: STATEMENT_TIMEOUT) do |user_database|\n+            user_database.run(\"SELECT public.AddGeometryColumn('#{schema_name}', '#{table_name}','the_geom_simple',4326, 'GEOMETRY', 2);\")\n+            user_database.run(%Q{UPDATE #{qualified_table_name} SET the_geom_simple = ST_Multi(the_geom);})\n+            user_database.run(\"SELECT DropGeometryColumn('#{schema_name}', '#{table_name}','the_geom');\")\n+            user_database.run(%Q{ALTER TABLE #{qualified_table_name} RENAME COLUMN the_geom_simple TO the_geom;})\n+\n+            type = user_database[%Q{","path":"app/models/synchronization/adapter.rb","position":170,"original_position":170,"commit_id":"9607bc0a990aa717a565430451bd7e0200c2ba75","original_commit_id":"9607bc0a990aa717a565430451bd7e0200c2ba75","user":{"login":"houndci-bot","id":6697940,"avatar_url":"https://avatars.githubusercontent.com/u/6697940?v=3","gravatar_id":"","url":"https://api.github.com/users/houndci-bot","html_url":"https://github.com/houndci-bot","followers_url":"https://api.github.com/users/houndci-bot/followers","following_url":"https://api.github.com/users/houndci-bot/following{/other_user}","gists_url":"https://api.github.com/users/houndci-bot/gists{/gist_id}","starred_url":"https://api.github.com/users/houndci-bot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/houndci-bot/subscriptions","organizations_url":"https://api.github.com/users/houndci-bot/orgs","repos_url":"https://api.github.com/users/houndci-bot/repos","events_url":"https://api.github.com/users/houndci-bot/events{/privacy}","received_events_url":"https://api.github.com/users/houndci-bot/received_events","type":"User","site_admin":false},"body":"Use `%` instead of `%Q`.<br>Use `%Q` only for strings that contain both single quotes and double quotes, or for dynamic strings that contain double quotes.","created_at":"2016-05-31T08:33:00Z","updated_at":"2016-05-31T08:33:00Z","html_url":"https://github.com/CartoDB/cartodb/pull/7543#discussion_r65141447","pull_request_url":"https://api.github.com/repos/CartoDB/cartodb/pulls/7543","_links":{"self":{"href":"https://api.github.com/repos/CartoDB/cartodb/pulls/comments/65141447"},"html":{"href":"https://github.com/CartoDB/cartodb/pull/7543#discussion_r65141447"},"pull_request":{"href":"https://api.github.com/repos/CartoDB/cartodb/pulls/7543"}}},"pull_request":{"url":"https://api.github.com/repos/CartoDB/cartodb/pulls/7543","id":71687112,"html_url":"https://github.com/CartoDB/cartodb/pull/7543","diff_url":"https://github.com/CartoDB/cartodb/pull/7543.diff","patch_url":"https://github.com/CartoDB/cartodb/pull/7543.patch","issue_url":"https://api.github.com/repos/CartoDB/cartodb/issues/7543","number":7543,"state":"open","locked":false,"title":"7171 CartoDBfy tables before switching in Sync Tables","user":{"login":"iriberri","id":1730320,"avatar_url":"https://avatars.githubusercontent.com/u/1730320?v=3","gravatar_id":"","url":"https://api.github.com/users/iriberri","html_url":"https://github.com/iriberri","followers_url":"https://api.github.com/users/iriberri/followers","following_url":"https://api.github.com/users/iriberri/following{/other_user}","gists_url":"https://api.github.com/users/iriberri/gists{/gist_id}","starred_url":"https://api.github.com/users/iriberri/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iriberri/subscriptions","organizations_url":"https://api.github.com/users/iriberri/orgs","repos_url":"https://api.github.com/users/iriberri/repos","events_url":"https://api.github.com/users/iriberri/events{/privacy}","received_events_url":"https://api.github.com/users/iriberri/received_events","type":"User","site_admin":false},"body":"Fixes #7171 \r\n\r\n## The problem\r\nCurrently, the synchronization workflow is as follows:\r\n  1. The new table is imported, it is never registered\r\n  2. The old and the new tables are switched. The old table is dropped.\r\n  3. CartoDBfication, import cleanups (cartodb_id) and geom checks (multi/simple geoms) are performed\r\n\r\nAnd this provokes several problems:\r\n  * When the switch is performed, the new table is not CartoDBfied (no cartodb_id, no the_geom) so any maps that contain this table as a layer will crash. See #7171 for a specific example.\r\n  * If there's an error in the CartoDBfication or the rest of the checks, the synchronization will leave a broken table. The old table has been dropped so there's no possible rollback. The maps will be broken.\r\n\r\nWhen working in the issue, I noticed that the current flow is working due to the fact that when the switch between tables is performed, the new table gets automatically registered (it reuses the register of the old table) so the operations in the Table model that require the Table object can be performed on them.\r\n\r\nAs a side-effect, as the new table was not CartoDBfied it would not be captured when the ghost tables were triggered.\r\n\r\n## The solution\r\nWe had to move the CartoDBfy process (and the rest of the checks) before the switch is performed to ensure that when it happens, the new table will be completely compatible with the maps and the Editor.\r\n\r\nBy \"moving\" this processes before the switch, we no longer have a registered table to work with. This is the reason why we duplicated code from Table (`cartodbfy`, `set_the_geom_column!` and `import_cleanup`) and adapted it to work with unregistered tables. Basically in this approach I am getting the column information via PostgreSQL queries, instead of checking the schema of the Table.\r\n\r\nThis code duplication is intended to be only part of a first iteration. Some parts of these methods can be directly removed with a correct configuration of Ogr2Ogr or the original methods can moved outside of Table.rb to create some kind of utility that can be used for both registered and unregistered tables.\r\n\r\nTo be able to CartoDBfy the table before switching, we had to move the table to the user schema. Some internal code of the CartoDBfication performs queries on CDB_UserQuotaSize and other functions that are expected to live in the schema in which the table lives, and `cdb_importer`, which is the default schema in which new tables are created does not contain these.\r\n\r\nWe also had to work with Ghost Tables. As the table is CartoDBfied and lives in the user schema, it would be visible for the Ghost Tables task. We're adding a commit to ignore tables in the User DB that are named as our `importer` tables.\r\n\r\nNow the process is as follows:\r\n\r\n  1. The new table is imported\r\n  2. It is moved to the user schema\r\n  3. It is CartoDBfied + import_cleanup + geom fixes(cartodb_id, the_geom)\r\n  4. It is switched by the old table of the user\r\n\r\nIn this scenario, if something goes wrong while manipulating the table (incorrect CartoDB ID, or multiple geometry types issues, which were reported by Jaak) an exception will be raised and the sync will stop before any switch is made.\r\n\r\n## Testing\r\n\r\nOutput of some tests: https://gist.github.com/iriberri/42a1a44a47f9ee5e428901dcd4a125d5\r\n\r\n\r\nOther similar branches I created just for test purposes (see gist above):\r\n* `7171-cdbfy_in_syncs_b`\r\n* `cdbfy_master_with_sleep`\r\n\r\n### Timing checks\r\nI got some timings for the query edited in the `ghost_tables_manager` for my own production user with 2564 tables in the User DB.\r\n\r\n* Original query, no name checks:\r\n  * Time: 240.853 ms\r\n* Adapted query 1: `t.tablename !~ 'importer_\\\\w{32}'`\r\n  * Time: 364.519 ms\r\n* Adapted query 2 (the one currently commited): `t.tablename !~ '^importer_'`\r\n  * Time: 277.863 ms\r\n\r\n====\r\n\r\nPending: \r\n* [x] test thoroughly for cartodbfycation exceptions and special geom types (multipoint, simple linestrings) to check postgres queries flow\r\n* [x] get some numbers on ghost tables query times","created_at":"2016-05-27T09:46:19Z","updated_at":"2016-05-31T08:33:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5148b9b56444b1bec71a06d7d33cb6f779f75c29","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/CartoDB/cartodb/pulls/7543/commits","review_comments_url":"https://api.github.com/repos/CartoDB/cartodb/pulls/7543/comments","review_comment_url":"https://api.github.com/repos/CartoDB/cartodb/pulls/comments{/number}","comments_url":"https://api.github.com/repos/CartoDB/cartodb/issues/7543/comments","statuses_url":"https://api.github.com/repos/CartoDB/cartodb/statuses/9607bc0a990aa717a565430451bd7e0200c2ba75","head":{"label":"CartoDB:7171-cdbfy_in_syncs","ref":"7171-cdbfy_in_syncs","sha":"9607bc0a990aa717a565430451bd7e0200c2ba75","user":{"login":"CartoDB","id":1799254,"avatar_url":"https://avatars.githubusercontent.com/u/1799254?v=3","gravatar_id":"","url":"https://api.github.com/users/CartoDB","html_url":"https://github.com/CartoDB","followers_url":"https://api.github.com/users/CartoDB/followers","following_url":"https://api.github.com/users/CartoDB/following{/other_user}","gists_url":"https://api.github.com/users/CartoDB/gists{/gist_id}","starred_url":"https://api.github.com/users/CartoDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CartoDB/subscriptions","organizations_url":"https://api.github.com/users/CartoDB/orgs","repos_url":"https://api.github.com/users/CartoDB/repos","events_url":"https://api.github.com/users/CartoDB/events{/privacy}","received_events_url":"https://api.github.com/users/CartoDB/received_events","type":"Organization","site_admin":false},"repo":{"id":4909355,"name":"cartodb","full_name":"CartoDB/cartodb","owner":{"login":"CartoDB","id":1799254,"avatar_url":"https://avatars.githubusercontent.com/u/1799254?v=3","gravatar_id":"","url":"https://api.github.com/users/CartoDB","html_url":"https://github.com/CartoDB","followers_url":"https://api.github.com/users/CartoDB/followers","following_url":"https://api.github.com/users/CartoDB/following{/other_user}","gists_url":"https://api.github.com/users/CartoDB/gists{/gist_id}","starred_url":"https://api.github.com/users/CartoDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CartoDB/subscriptions","organizations_url":"https://api.github.com/users/CartoDB/orgs","repos_url":"https://api.github.com/users/CartoDB/repos","events_url":"https://api.github.com/users/CartoDB/events{/privacy}","received_events_url":"https://api.github.com/users/CartoDB/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CartoDB/cartodb","description":"Location Intelligence & Data Visualization tool","fork":false,"url":"https://api.github.com/repos/CartoDB/cartodb","forks_url":"https://api.github.com/repos/CartoDB/cartodb/forks","keys_url":"https://api.github.com/repos/CartoDB/cartodb/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CartoDB/cartodb/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CartoDB/cartodb/teams","hooks_url":"https://api.github.com/repos/CartoDB/cartodb/hooks","issue_events_url":"https://api.github.com/repos/CartoDB/cartodb/issues/events{/number}","events_url":"https://api.github.com/repos/CartoDB/cartodb/events","assignees_url":"https://api.github.com/repos/CartoDB/cartodb/assignees{/user}","branches_url":"https://api.github.com/repos/CartoDB/cartodb/branches{/branch}","tags_url":"https://api.github.com/repos/CartoDB/cartodb/tags","blobs_url":"https://api.github.com/repos/CartoDB/cartodb/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CartoDB/cartodb/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CartoDB/cartodb/git/refs{/sha}","trees_url":"https://api.github.com/repos/CartoDB/cartodb/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CartoDB/cartodb/statuses/{sha}","languages_url":"https://api.github.com/repos/CartoDB/cartodb/languages","stargazers_url":"https://api.github.com/repos/CartoDB/cartodb/stargazers","contributors_url":"https://api.github.com/repos/CartoDB/cartodb/contributors","subscribers_url":"https://api.github.com/repos/CartoDB/cartodb/subscribers","subscription_url":"https://api.github.com/repos/CartoDB/cartodb/subscription","commits_url":"https://api.github.com/repos/CartoDB/cartodb/commits{/sha}","git_commits_url":"https://api.github.com/repos/CartoDB/cartodb/git/commits{/sha}","comments_url":"https://api.github.com/repos/CartoDB/cartodb/comments{/number}","issue_comment_url":"https://api.github.com/repos/CartoDB/cartodb/issues/comments{/number}","contents_url":"https://api.github.com/repos/CartoDB/cartodb/contents/{+path}","compare_url":"https://api.github.com/repos/CartoDB/cartodb/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CartoDB/cartodb/merges","archive_url":"https://api.github.com/repos/CartoDB/cartodb/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CartoDB/cartodb/downloads","issues_url":"https://api.github.com/repos/CartoDB/cartodb/issues{/number}","pulls_url":"https://api.github.com/repos/CartoDB/cartodb/pulls{/number}","milestones_url":"https://api.github.com/repos/CartoDB/cartodb/milestones{/number}","notifications_url":"https://api.github.com/repos/CartoDB/cartodb/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CartoDB/cartodb/labels{/name}","releases_url":"https://api.github.com/repos/CartoDB/cartodb/releases{/id}","deployments_url":"https://api.github.com/repos/CartoDB/cartodb/deployments","created_at":"2012-07-05T15:23:45Z","updated_at":"2016-05-28T17:06:28Z","pushed_at":"2016-05-31T08:32:51Z","git_url":"git://github.com/CartoDB/cartodb.git","ssh_url":"git@github.com:CartoDB/cartodb.git","clone_url":"https://github.com/CartoDB/cartodb.git","svn_url":"https://github.com/CartoDB/cartodb","homepage":"http://cartodb.com","size":387432,"stargazers_count":1142,"watchers_count":1142,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":289,"mirror_url":null,"open_issues_count":928,"forks":289,"open_issues":928,"watchers":1142,"default_branch":"master"}},"base":{"label":"CartoDB:master","ref":"master","sha":"1086b0bb81c023593fb5cc4a52afa339763de619","user":{"login":"CartoDB","id":1799254,"avatar_url":"https://avatars.githubusercontent.com/u/1799254?v=3","gravatar_id":"","url":"https://api.github.com/users/CartoDB","html_url":"https://github.com/CartoDB","followers_url":"https://api.github.com/users/CartoDB/followers","following_url":"https://api.github.com/users/CartoDB/following{/other_user}","gists_url":"https://api.github.com/users/CartoDB/gists{/gist_id}","starred_url":"https://api.github.com/users/CartoDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CartoDB/subscriptions","organizations_url":"https://api.github.com/users/CartoDB/orgs","repos_url":"https://api.github.com/users/CartoDB/repos","events_url":"https://api.github.com/users/CartoDB/events{/privacy}","received_events_url":"https://api.github.com/users/CartoDB/received_events","type":"Organization","site_admin":false},"repo":{"id":4909355,"name":"cartodb","full_name":"CartoDB/cartodb","owner":{"login":"CartoDB","id":1799254,"avatar_url":"https://avatars.githubusercontent.com/u/1799254?v=3","gravatar_id":"","url":"https://api.github.com/users/CartoDB","html_url":"https://github.com/CartoDB","followers_url":"https://api.github.com/users/CartoDB/followers","following_url":"https://api.github.com/users/CartoDB/following{/other_user}","gists_url":"https://api.github.com/users/CartoDB/gists{/gist_id}","starred_url":"https://api.github.com/users/CartoDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CartoDB/subscriptions","organizations_url":"https://api.github.com/users/CartoDB/orgs","repos_url":"https://api.github.com/users/CartoDB/repos","events_url":"https://api.github.com/users/CartoDB/events{/privacy}","received_events_url":"https://api.github.com/users/CartoDB/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CartoDB/cartodb","description":"Location Intelligence & Data Visualization tool","fork":false,"url":"https://api.github.com/repos/CartoDB/cartodb","forks_url":"https://api.github.com/repos/CartoDB/cartodb/forks","keys_url":"https://api.github.com/repos/CartoDB/cartodb/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CartoDB/cartodb/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CartoDB/cartodb/teams","hooks_url":"https://api.github.com/repos/CartoDB/cartodb/hooks","issue_events_url":"https://api.github.com/repos/CartoDB/cartodb/issues/events{/number}","events_url":"https://api.github.com/repos/CartoDB/cartodb/events","assignees_url":"https://api.github.com/repos/CartoDB/cartodb/assignees{/user}","branches_url":"https://api.github.com/repos/CartoDB/cartodb/branches{/branch}","tags_url":"https://api.github.com/repos/CartoDB/cartodb/tags","blobs_url":"https://api.github.com/repos/CartoDB/cartodb/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CartoDB/cartodb/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CartoDB/cartodb/git/refs{/sha}","trees_url":"https://api.github.com/repos/CartoDB/cartodb/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CartoDB/cartodb/statuses/{sha}","languages_url":"https://api.github.com/repos/CartoDB/cartodb/languages","stargazers_url":"https://api.github.com/repos/CartoDB/cartodb/stargazers","contributors_url":"https://api.github.com/repos/CartoDB/cartodb/contributors","subscribers_url":"https://api.github.com/repos/CartoDB/cartodb/subscribers","subscription_url":"https://api.github.com/repos/CartoDB/cartodb/subscription","commits_url":"https://api.github.com/repos/CartoDB/cartodb/commits{/sha}","git_commits_url":"https://api.github.com/repos/CartoDB/cartodb/git/commits{/sha}","comments_url":"https://api.github.com/repos/CartoDB/cartodb/comments{/number}","issue_comment_url":"https://api.github.com/repos/CartoDB/cartodb/issues/comments{/number}","contents_url":"https://api.github.com/repos/CartoDB/cartodb/contents/{+path}","compare_url":"https://api.github.com/repos/CartoDB/cartodb/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CartoDB/cartodb/merges","archive_url":"https://api.github.com/repos/CartoDB/cartodb/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CartoDB/cartodb/downloads","issues_url":"https://api.github.com/repos/CartoDB/cartodb/issues{/number}","pulls_url":"https://api.github.com/repos/CartoDB/cartodb/pulls{/number}","milestones_url":"https://api.github.com/repos/CartoDB/cartodb/milestones{/number}","notifications_url":"https://api.github.com/repos/CartoDB/cartodb/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CartoDB/cartodb/labels{/name}","releases_url":"https://api.github.com/repos/CartoDB/cartodb/releases{/id}","deployments_url":"https://api.github.com/repos/CartoDB/cartodb/deployments","created_at":"2012-07-05T15:23:45Z","updated_at":"2016-05-28T17:06:28Z","pushed_at":"2016-05-31T08:32:51Z","git_url":"git://github.com/CartoDB/cartodb.git","ssh_url":"git@github.com:CartoDB/cartodb.git","clone_url":"https://github.com/CartoDB/cartodb.git","svn_url":"https://github.com/CartoDB/cartodb","homepage":"http://cartodb.com","size":387432,"stargazers_count":1142,"watchers_count":1142,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":289,"mirror_url":null,"open_issues_count":928,"forks":289,"open_issues":928,"watchers":1142,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/CartoDB/cartodb/pulls/7543"},"html":{"href":"https://github.com/CartoDB/cartodb/pull/7543"},"issue":{"href":"https://api.github.com/repos/CartoDB/cartodb/issues/7543"},"comments":{"href":"https://api.github.com/repos/CartoDB/cartodb/issues/7543/comments"},"review_comments":{"href":"https://api.github.com/repos/CartoDB/cartodb/pulls/7543/comments"},"review_comment":{"href":"https://api.github.com/repos/CartoDB/cartodb/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/CartoDB/cartodb/pulls/7543/commits"},"statuses":{"href":"https://api.github.com/repos/CartoDB/cartodb/statuses/9607bc0a990aa717a565430451bd7e0200c2ba75"}}}}
{"actor":{"display_login":"houndci-bot"}}