             profiler: false
         history: []
         focus_on_codemirror: true
-        last_query_has_profile: true
-        #saved_data: {}
-
+
+    # This class represents the results of a query.
+    #
+    # If there is a profile, `profile` is set
+    #
+    # After a 'sync' event, one of `error`, `value` or `cursor` is always set
+    #
+    # It triggers the following events:
+    #
+    #  * sync: The first response has been received
+    #
+    #  * add: Another row has been received from a cursor
+    #
+    #  * error: An error has been received from a cursor
+    #
+    #  * end: There are no more documents to fetch
+    #
+    #  * discard: The results have been discarded
+    class @QueryResult
+        _.extend @::, Backbone.Events
+
+        constructor: (options) ->
+            @has_profile = options.profile
+            @discard_results = options.discard_results ? false
+            if options.events?
+                for own event, handler of options.events
+                    @on event, handler
+
+        # Can be used as a callback to run
+        set: (error, result) =>
+            if error?
+                @error = error
+            else if not @discard_results
+                if @has_profile
+                    @profile = result.profile
+                    value = result.value
+                else
+                    value = result
+                if typeof value._next is 'function' # if it's a cursor
+                    @results = []
+                    @truncated = false
+                    @cursor = value
+                    @is_feed = @cursor.toString() == '[object Feed]'
+                    @missing = 0
+                    @ended = false
+                    @start_index = 0
+                else
+                    @start_index = 0
+                    @value = value
+                    @ended = true
+            @trigger 'sync', @
+
+        # Remove n elements from the result set of a cursor Waits for
+        # n+1 elements, or the end before returning
+        #
+        # Note: the callbacks are not ordered. In this code, `f` is
+        # never called: `qr.shift 2 f; cb = -> qr.shift 1 cb`
+        shift: (n, k) =>
+            cb = => 
+                if @results.length > n or @ended
+                    @off 'end', cb
+                    ret = @results[0...n]
+                    @results = @results[n...]
+                    @start_index += n
+                    k @, ret
+                else
+                    @once 'add', cb
+                    @more()
+            @once 'end', cb
+            cb()
+
+        # Discard the results
+        discard: =>
+            @trigger 'discard', @
+            @off()
+            @discard_results = true
+            delete @profile
+            delete @value
+            delete @results
+            delete @truncated
+            @cursor?.close()
+            delete @cursor
+
+        # Ask for more results from the cursor
+        more: (n) =>
+            prev_missing = @missing
+            @missing = prev_missing + (n ? 1)
+            if prev_missing <= 0
+                @fetch_next()
+
+        # Gets the next result from the cursor
+        fetch_next: =>
+            if not @ended
+                @cursor.next (error, row) =>
+                    if error?
+                        if error.message is 'No more rows in the cursor.'
+                            @ended = true
+                            @trigger 'end', @
+                        else
+                            @error = error
+                            @trigger 'error', @, error
+                            @discard_results = true
+                    else
+                        if @discard_results
+                            return
+                        @results.push row
+                        @trigger 'add', @, row
+                        @missing--
+                        if @missing >= 0
+                            @fetch_next()
 
     class @Container extends Backbone.View
         id: 'dataexplorer'


        # A portion is one query of the whole input.
        execute_portion: =>
            @state.cursor = null
            while @queries[@index]?
                full_query = @non_rethinkdb_query
                full_query += @queries[@index]

            
            # Execute the query
            try
                @state.query_result?.discard()
                # Separate queries
                @non_rethinkdb_query = '' # Store the statements that don't return a rethinkdb query (like "var a = 1;")
                @index = 0 # index of the query currently being executed
