Demo for query storing

Change-Id: I947bcac841992c3f6cfd01ab337c265b0d01cb70
diff --git a/node_modules/tar-stream/extract.js b/node_modules/tar-stream/extract.js
new file mode 100644
index 0000000..19a4255
--- /dev/null
+++ b/node_modules/tar-stream/extract.js
@@ -0,0 +1,258 @@
+var util = require('util')
+var bl = require('bl')
+var xtend = require('xtend')
+var headers = require('./headers')
+
+var Writable = require('readable-stream').Writable
+var PassThrough = require('readable-stream').PassThrough
+
+var noop = function () {}
+
+var overflow = function (size) {
+  size &= 511
+  return size && 512 - size
+}
+
+var emptyStream = function (self, offset) {
+  var s = new Source(self, offset)
+  s.end()
+  return s
+}
+
+var mixinPax = function (header, pax) {
+  if (pax.path) header.name = pax.path
+  if (pax.linkpath) header.linkname = pax.linkpath
+  if (pax.size) header.size = parseInt(pax.size, 10)
+  header.pax = pax
+  return header
+}
+
+var Source = function (self, offset) {
+  this._parent = self
+  this.offset = offset
+  PassThrough.call(this)
+}
+
+util.inherits(Source, PassThrough)
+
+Source.prototype.destroy = function (err) {
+  this._parent.destroy(err)
+}
+
+var Extract = function (opts) {
+  if (!(this instanceof Extract)) return new Extract(opts)
+  Writable.call(this, opts)
+
+  opts = opts || {}
+
+  this._offset = 0
+  this._buffer = bl()
+  this._missing = 0
+  this._partial = false
+  this._onparse = noop
+  this._header = null
+  this._stream = null
+  this._overflow = null
+  this._cb = null
+  this._locked = false
+  this._destroyed = false
+  this._pax = null
+  this._paxGlobal = null
+  this._gnuLongPath = null
+  this._gnuLongLinkPath = null
+
+  var self = this
+  var b = self._buffer
+
+  var oncontinue = function () {
+    self._continue()
+  }
+
+  var onunlock = function (err) {
+    self._locked = false
+    if (err) return self.destroy(err)
+    if (!self._stream) oncontinue()
+  }
+
+  var onstreamend = function () {
+    self._stream = null
+    var drain = overflow(self._header.size)
+    if (drain) self._parse(drain, ondrain)
+    else self._parse(512, onheader)
+    if (!self._locked) oncontinue()
+  }
+
+  var ondrain = function () {
+    self._buffer.consume(overflow(self._header.size))
+    self._parse(512, onheader)
+    oncontinue()
+  }
+
+  var onpaxglobalheader = function () {
+    var size = self._header.size
+    self._paxGlobal = headers.decodePax(b.slice(0, size))
+    b.consume(size)
+    onstreamend()
+  }
+
+  var onpaxheader = function () {
+    var size = self._header.size
+    self._pax = headers.decodePax(b.slice(0, size))
+    if (self._paxGlobal) self._pax = xtend(self._paxGlobal, self._pax)
+    b.consume(size)
+    onstreamend()
+  }
+
+  var ongnulongpath = function () {
+    var size = self._header.size
+    this._gnuLongPath = headers.decodeLongPath(b.slice(0, size), opts.filenameEncoding)
+    b.consume(size)
+    onstreamend()
+  }
+
+  var ongnulonglinkpath = function () {
+    var size = self._header.size
+    this._gnuLongLinkPath = headers.decodeLongPath(b.slice(0, size), opts.filenameEncoding)
+    b.consume(size)
+    onstreamend()
+  }
+
+  var onheader = function () {
+    var offset = self._offset
+    var header
+    try {
+      header = self._header = headers.decode(b.slice(0, 512), opts.filenameEncoding)
+    } catch (err) {
+      self.emit('error', err)
+    }
+    b.consume(512)
+
+    if (!header) {
+      self._parse(512, onheader)
+      oncontinue()
+      return
+    }
+    if (header.type === 'gnu-long-path') {
+      self._parse(header.size, ongnulongpath)
+      oncontinue()
+      return
+    }
+    if (header.type === 'gnu-long-link-path') {
+      self._parse(header.size, ongnulonglinkpath)
+      oncontinue()
+      return
+    }
+    if (header.type === 'pax-global-header') {
+      self._parse(header.size, onpaxglobalheader)
+      oncontinue()
+      return
+    }
+    if (header.type === 'pax-header') {
+      self._parse(header.size, onpaxheader)
+      oncontinue()
+      return
+    }
+
+    if (self._gnuLongPath) {
+      header.name = self._gnuLongPath
+      self._gnuLongPath = null
+    }
+
+    if (self._gnuLongLinkPath) {
+      header.linkname = self._gnuLongLinkPath
+      self._gnuLongLinkPath = null
+    }
+
+    if (self._pax) {
+      self._header = header = mixinPax(header, self._pax)
+      self._pax = null
+    }
+
+    self._locked = true
+
+    if (!header.size || header.type === 'directory') {
+      self._parse(512, onheader)
+      self.emit('entry', header, emptyStream(self, offset), onunlock)
+      return
+    }
+
+    self._stream = new Source(self, offset)
+
+    self.emit('entry', header, self._stream, onunlock)
+    self._parse(header.size, onstreamend)
+    oncontinue()
+  }
+
+  this._onheader = onheader
+  this._parse(512, onheader)
+}
+
+util.inherits(Extract, Writable)
+
+Extract.prototype.destroy = function (err) {
+  if (this._destroyed) return
+  this._destroyed = true
+
+  if (err) this.emit('error', err)
+  this.emit('close')
+  if (this._stream) this._stream.emit('close')
+}
+
+Extract.prototype._parse = function (size, onparse) {
+  if (this._destroyed) return
+  this._offset += size
+  this._missing = size
+  if (onparse === this._onheader) this._partial = false
+  this._onparse = onparse
+}
+
+Extract.prototype._continue = function () {
+  if (this._destroyed) return
+  var cb = this._cb
+  this._cb = noop
+  if (this._overflow) this._write(this._overflow, undefined, cb)
+  else cb()
+}
+
+Extract.prototype._write = function (data, enc, cb) {
+  if (this._destroyed) return
+
+  var s = this._stream
+  var b = this._buffer
+  var missing = this._missing
+  if (data.length) this._partial = true
+
+  // we do not reach end-of-chunk now. just forward it
+
+  if (data.length < missing) {
+    this._missing -= data.length
+    this._overflow = null
+    if (s) return s.write(data, cb)
+    b.append(data)
+    return cb()
+  }
+
+  // end-of-chunk. the parser should call cb.
+
+  this._cb = cb
+  this._missing = 0
+
+  var overflow = null
+  if (data.length > missing) {
+    overflow = data.slice(missing)
+    data = data.slice(0, missing)
+  }
+
+  if (s) s.end(data)
+  else b.append(data)
+
+  this._overflow = overflow
+  this._onparse()
+}
+
+Extract.prototype._final = function (cb) {
+  if (this._partial) return this.destroy(new Error('Unexpected end of data'))
+  cb()
+}
+
+module.exports = Extract