   #   end)
   #   {:ok, s}
   # end
-  #
-  # ## connect
-  #
-  # defp connect(host, port, sock_opts, %{timeout: timeout} = s) do
-  #   buffer? = Keyword.has_key?(sock_opts, :buffer)
-  #   case :gen_tcp.connect(host, port, sock_opts ++ @sock_opts, timeout) do
-  #     {:ok, sock} when buffer? ->
-  #       {:ok, %{s | sock: {:gen_tcp, sock}}}
-  #     {:ok, sock} ->
-  #       # A suitable :buffer is only set if :recbuf is included in
-  #       # :socket_options.
-  #       {:ok, [sndbuf: sndbuf, recbuf: recbuf, buffer: buffer]} =
-  #         :inet.getopts(sock, [:sndbuf, :recbuf, :buffer])
-  #       buffer = buffer
-  #         |> max(sndbuf)
-  #         |> max(recbuf)
-  #       :ok = :inet.setopts(sock, [buffer: buffer])
-  #       {:ok, %{s | sock: {:gen_tcp, sock}}}
-  #     {:error, reason} ->
-  #       {:error, Sqlite.DbConnection.Error.exception(tag: :tcp, action: "connect", reason: reason)}
-  #   end
-  # end
-  #
-  # ## ssl
-  #
-  # defp ssl(s, status) do
-  #   case msg_send(s, msg_ssl_request(), "") do
-  #     :ok              -> ssl_recv(s, status)
-  #     {:error, _} = err -> err
-  #   end
-  # end
-  #
-  # defp ssl_recv(%{sock: {:gen_tcp, sock}, timeout: timeout} = s, status) do
-  #   case :gen_tcp.recv(sock, 1, timeout) do
-  #     {:ok, <<?S>>} ->
-  #       ssl_connect(s, status)
-  #     {:ok, <<?N>>} ->
-  #       disconnect(s, %Sqlite.DbConnection.Error{message: "ssl not available"}, "")
-  #     {:error, reason} ->
-  #       err = Sqlite.DbConnection.Error.exception(tag: :tcp, action: "recv", reason: reason)
-  #       disconnect(s, err, "")
-  #   end
-  # end
-  #
-  # defp ssl_connect(%{sock: {:gen_tcp, sock}, timeout: timeout} = s, status) do
-  #   case :ssl.connect(sock, status.opts[:ssl_opts] || [], timeout) do
-  #     {:ok, ssl_sock} ->
-  #       startup(%{s | sock: {:ssl, ssl_sock}}, status)
-  #     {:error, reason} ->
-  #       err = Sqlite.DbConnection.Error.exception(tag: :ssl, action: "connect", reason: reason)
-  #       disconnect(s, err, "")
-  #   end
-  # end
-  #
-  # ## startup
-  #
-  # defp startup(s, %{opts: opts} = status) do
-  #   params = opts[:parameters] || []
-  #   user = Keyword.fetch!(opts, :username)
-  #   database = Keyword.fetch!(opts, :database)
-  #   msg = msg_startup(params: [user: user, database: database] ++ params)
-  #   case msg_send(s, msg, "") do
-  #     :ok                       -> auth_recv(s, status, <<>>)
-  #     {:disconnect, _, _} = dis -> dis
-  #   end
-  # end
-  #
-  # ## auth
-  #
-  # defp auth_recv(%{timeout: timeout} = s, status, buffer) do
-  #   case msg_recv(s, timeout, buffer) do
-  #     {:ok, msg_auth(type: :ok), buffer} ->
-  #       init_recv(s, status, buffer)
-  #     {:ok, msg_auth(type: :cleartext), buffer} ->
-  #       auth_cleartext(s, status, buffer)
-  #     {:ok, msg_auth(type: :md5, data: salt), buffer} ->
-  #       auth_md5(s, status, salt, buffer)
-  #     {:ok, msg_error(fields: fields), buffer} ->
-  #       disconnect(s, Sqlite.DbConnection.Error.exception(postgres: fields), buffer)
-  #     {:disconnect, _, _} = dis ->
-  #       dis
-  #   end
-  # end
-  #
-  # defp auth_cleartext(s, %{opts: opts} = status, buffer) do
-  #   pass = Keyword.fetch!(opts, :password)
-  #   auth_send(s, msg_password(pass: pass), status, buffer)
-  # end
-  #
-  # defp auth_md5(s, %{opts: opts} = status, salt, buffer) do
-  #   user = Keyword.fetch!(opts, :username)
-  #   pass = Keyword.fetch!(opts, :password)
-  #
-  #   digest = :crypto.hash(:md5, [pass, user])
-  #   |> Base.encode16(case: :lower)
-  #   digest = :crypto.hash(:md5, [digest, salt])
-  #   |> Base.encode16(case: :lower)
-  #   auth_send(s, msg_password(pass: ["md5", digest]), status, buffer)
-  # end
-  #
-  # defp auth_send(s, msg, status, buffer) do
-  #   case msg_send(s, msg, buffer) do
-  #     :ok                       -> auth_recv(s, status, buffer)
-  #     {:disconnect, _, _} = dis -> dis
-  #   end
-  # end
-  #
-  # ## init
-  #
-  # defp init_recv(%{timeout: timeout} = s, status, buffer) do
-  #   case msg_recv(s, timeout, buffer) do
-  #     {:ok, msg_backend_key(pid: pid, key: key), buffer} ->
-  #       init_recv(%{s | backend_key: {pid, key}}, status, buffer)
-  #     {:ok, msg_ready(), buffer} ->
-  #       bootstrap(s, status, buffer)
-  #     {:ok, msg_error(fields: fields), buffer} ->
-  #       disconnect(s, Sqlite.DbConnection.Error.exception(postgres: fields), buffer)
-  #     {:ok, msg, buffer} ->
-  #       init_recv(handle_msg(s, status, msg), status, buffer)
-  #     {:disconnect, _, _} = dis ->
-  #       dis
-  #   end
-  # end
-  #
-  # ## bootstrap
-  #
-  # defp bootstrap(s, %{types_key: nil}, buffer) do
-  #   activate(s, buffer)
-  # end
-  # defp bootstrap(s, %{types_key: types_key} = status, buffer) do
-  #   case Sqlite.DbConnection.TypeServer.fetch(types_key) do
-  #     {:ok, table} ->
-  #       reserve_send(%{s | types: table}, status, buffer)
-  #     {:lock, ref, table} ->
-  #       status = %{status | types_ref: ref, types_table: table}
-  #       bootstrap_send(%{s | types: ref}, status, buffer)
-  #   end
-  # end
-  #
-  # defp bootstrap_send(%{parameters: parameters} = s, status, buffer) do
-  #   %{extensions: extensions} = status
-  #
-  #   extension_keys = Enum.map(extensions, &elem(&1, 0))
-  #   extension_opts = Types.prepare_extensions(extensions, parameters)
-  #   matchers = Types.extension_matchers(extension_keys, extension_opts)
-  #   version = parameters["server_version"] |> Sqlite.DbConnection.Utils.parse_version
-  #   statement = Types.bootstrap_query(matchers, version)
-  #   msg = msg_query(statement: statement)
-  #   case msg_send(s, msg, buffer) do
-  #     :ok ->
-  #       status = %{status | extension_info: {extension_keys, extension_opts}}
-  #       bootstrap_recv(s, status, buffer)
-  #     {:disconnect, _, _} = dis ->
-  #       dis
-  #   end
-  # end
-  #
-  # defp bootstrap_recv(%{timeout: timeout} = s, status, buffer) do
-  #   case msg_recv(s, timeout, buffer) do
-  #     {:ok, msg_row_desc(), buffer} ->
-  #       bootstrap_recv(s, status, [], buffer)
-  #     {:ok, msg_error(fields: fields), buffer} ->
-  #       disconnect(s, Sqlite.DbConnection.Error.exception(postgres: fields), buffer)
-  #     {:ok, msg, buffer} ->
-  #       bootstrap_recv(handle_msg(s, status, msg), status, buffer)
-  #     {:disconnect, _, _} = dis ->
-  #       dis
-  #   end
-  # end
-  #
-  # defp bootstrap_recv(%{timeout: timeout} = s, status, rows, buffer) do
-  #   case msg_recv(s, timeout, buffer) do
-  #     {:ok, msg_data_row(values: values), buffer} ->
-  #       bootstrap_recv(s, status, [values | rows], buffer)
-  #     {:ok, msg_command_complete(), buffer} ->
-  #       bootstrap_types(s, status, rows, buffer)
-  #     {:ok, msg_error(fields: fields), buffer} ->
-  #       disconnect(s, Sqlite.DbConnection.Error.exception(postgres: fields), buffer)
-  #     {:ok, msg, buffer} ->
-  #       bootstrap_recv(handle_msg(s, status, msg), status, rows, buffer)
-  #     {:disconnect, _, _} = dis ->
-  #       dis
-  #   end
-  # end
-  #
-  # defp bootstrap_types(s, %{types_table: table} = status, rows, buffer) do
-  #   %{types_ref: ref, extension_info: {extension_keys, extension_opts}} = status
-  #   types = Types.build_types(rows)
-  #   Types.associate_extensions_with_types(table, extension_keys, extension_opts, types)
-  #   Sqlite.DbConnection.TypeServer.unlock(ref)
-  #   bootstrap_sync_recv(%{s | types: table}, status, buffer)
-  # end
-  #
-  # defp bootstrap_sync_recv(%{timeout: timeout} = s, status, buffer) do
-  #   case msg_recv(s, timeout, buffer) do
-  #     {:ok, msg_ready(), buffer} ->
-  #       reserve_send(s, status, buffer)
-  #     {:ok, msg, buffer} ->
-  #       bootstrap_sync_recv(handle_msg(s, status, msg), status, buffer)
-  #     {:disconnect, _, _} = dis ->
-  #       dis
-  #   end
-  # end
-  #
-  # defp reserve_send(s, status, buffer) do
-  #   case msg_send(s, reserve_msgs() ++ [msg_sync()], buffer) do
-  #     :ok ->
-  #       reserve_recv(s, status, buffer)
-  #     {:disconnect, _, _} = dis ->
-  #       dis
-  #   end
-  # end
-  #
-  # defp reserve_msgs() do
-  #   for statement <- @reserved_queries do
-  #     name = @reserved_prefix <> statement
-  #     msg_parse(name: name, statement: statement, type_oids: [])
-  #   end
-  # end
-  #
-  # defp reserve_recv(%{timeout: timeout} = s, status, buffer) do
-  #   case msg_recv(s, timeout, buffer) do
-  #     {:ok, msg_parse_complete(), buffer} ->
-  #       reserve_recv(s, status, buffer)
-  #     {:ok, msg_ready(status: :idle), buffer} ->
-  #       activate(s, buffer)
-  #     {:ok, msg_ready(status: postgres), buffer} ->
-  #       sync_error(s, postgres, buffer)
-  #     {:ok, msg_error(fields: fields), buffer} ->
-  #       disconnect(s, Sqlite.DbConnection.Error.exception(postgres: fields), buffer)
-  #     {:ok, msg, buffer} ->
-  #       reserve_recv(handle_msg(s, status, msg), status, buffer)
-  #     {:disconnect, _, _} = dis ->
-  #       dis
-  #   end
-  # end
-  #
-  # ## simple
-  #
-  # defp simple_send(s, status, statement, buffer) do
-  #   msg = msg_query(statement: statement)
-  #   case msg_send(s, msg, buffer) do
-  #     :ok                       -> simple_recv(s, status, buffer)
-  #     {:disconnect, _, _} = dis -> dis
-  #   end
-  # end
-  #
-  # defp simple_recv(%{timeout: timeout} = s, status, buffer) do
-  #   ## simple queries here are only done by Sqlite.DbConnection.Notifications processes
-  #   case msg_recv(s, timeout, buffer) do
-  #     {:ok, msg_command_complete(tag: tag), buffer} ->
-  #       complete(s, status, %Query{}, [], tag, buffer)
-  #     {:ok, msg_error(fields: fields), buffer} ->
-  #       sync_recv(s, status, Sqlite.DbConnection.Error.exception(postgres: fields), buffer)
-  #     {:ok, msg, buffer} ->
-  #       simple_recv(handle_msg(s, status, msg), status, buffer)
-  #     {:disconnect, _, _} = dis ->
-  #       dis
-  #   end
-  # end
 
   ## prepare
 

        sqlite_error(err, s)
    end
  end

  # defp handle_prepare(query, prepare, opts, %{buffer: buffer} = s) do
  #   status = %{notify: notify(opts), prepare: prepare, sync: :sync}
  #   prepare_send(%{s | buffer: nil}, status, query, buffer)
  # end
  #
  # defp prepare_send(s, %{prepare: prepare} = status, query, buffer) do
  #   %Query{name: name, statement: statement} = query
  #   msgs =
  #    case prepare do
  #      :parse_describe ->
  #         [msg_describe(type: :statement, name: name), msg_flush()]
  #      :parse ->
  #         [msg_flush()]
  #     end
  #   msgs = [msg_parse(name: name, statement: statement, type_oids: []) | msgs]
  #   case msg_send(s, msgs, buffer) do
  #     :ok ->
  #       parse_recv(s, status, query, buffer)
  #     {:disconnect, _, _} = dis ->
  #       dis
  #   end
  # end
  #
  # defp parse_recv(s, %{prepare: prepare} = status, query, buffer) do
  #   case msg_recv(s, :infinity, buffer) do
  #     {:ok, msg_parse_complete(), buffer} when prepare == :parse_describe ->
  #       describe_recv(s, status, %Query{query | types: s.types}, buffer)
  #     {:ok, msg_parse_complete(), buffer} when prepare == :parse ->
  #       ok(s, query, buffer)
  #     {:ok, msg_error(fields: fields), buffer} ->
  #       exception = Sqlite.DbConnection.Error.exception(postgres: fields)
  #       close_sync(s, status, query, exception, buffer)
  #     {:ok, msg, buffer} ->
  #       parse_recv(handle_msg(s, status, msg), status, query, buffer)
  #     {:disconnect, _, _} = dis ->
  #       dis
  #   end
  # end
  #
  # defp describe_recv(s, status, query, buffer) do
  #   case msg_recv(s, :infinity, buffer) do
  #     {:ok, msg_no_data(), buffer} ->
  #       ok(s, query, buffer)
  #     {:ok, msg_parameter_desc(type_oids: param_oids), buffer} ->
  #       describe_recv(s, status, %Query{query | encoders: param_oids}, buffer)
  #     {:ok, msg_row_desc(fields: fields), buffer} ->
  #       {col_oids, col_names} = columns(fields)
  #       query = %Query{query | columns: col_names, decoders: col_oids}
  #       ok(s, query, buffer)
  #     {:ok, msg_error(fields: fields), buffer} ->
  #       exception = Sqlite.DbConnection.Error.exception(postgres: fields)
  #       close_sync(s, status, query, exception, buffer)
  #     {:ok, msg, buffer} ->
  #       describe_recv(handle_msg(s, status, msg), status, query, buffer)
  #     {:disconnect, _, _} = dis ->
  #       dis
  #   end
  # end
  #
  # defp close_sync(s, status, %Query{name: name}, result, buffer) do
  #   msgs = [
  #     msg_close(type: :statement, name: name),
  #     msg_sync() ]
  #   case msg_send(s, msgs, buffer) do
  #     :ok                       -> sync_recv(s, status, result, buffer)
  #     {:disconnect, _, _} = dis -> dis
  #   end
  # end

  ## execute


  defp command_from_words(words) when is_list(words), do:
    String.to_atom(List.first(words))

  defp reserved_error(query, s) do
    err = ArgumentError.exception("query #{inspect query} uses reserved name")
    {:error, err, s}
  end
end
