# `Grizzly.ZIPGateway.Database`
[🔗](https://github.com/smartrent/grizzly/blob/v9.1.4/lib/grizzly/zipgateway/database.ex#L1)

Functions for inspecting and debugging Z/IP Gateway's SQLite database.

# `endpoint`

```elixir
@type endpoint() :: %{
  id: non_neg_integer(),
  node_id: Grizzly.zwave_node_id(),
  generic_device_class:
    Grizzly.ZWave.DeviceClasses.generic_device_class() | nil,
  specific_device_class:
    Grizzly.ZWave.DeviceClasses.specific_device_class() | nil,
  command_classes: Grizzly.ZWave.CommandClasses.command_class_list()
}
```

# `listening_mode`

```elixir
@type listening_mode() ::
  :always_listening | :frequently_listening | :wakeup | :unknown
```

# `mode_flag`

```elixir
@type mode_flag() ::
  {:mode, node_mode() | :unknown}
  | {:deleted | :failed | :low_battery, boolean()}
```

# `node_mode`

```elixir
@type node_mode() ::
  :not_probed
  | :nonlistening
  | :always_listening
  | :flirs
  | :wakeup
  | :wakeup_firmware_upgrade
```

# `node_state`

```elixir
@type node_state() ::
  :created
  | :probe_node_info
  | :probe_product_id
  | :enumerate_endpoints
  | :find_endpoints
  | :check_wakeup_cc_version
  | :get_wakeup_capabilities
  | :set_wakeup_interval
  | :assign_return_route
  | :probe_wakeup_interval
  | :probe_endpoints
  | :mdns_probe
  | :mdns_endpoint_probe
  | :done
  | :probe_fail
  | :failing
```

# `probe_state`

```elixir
@type probe_state() :: :ok | :never_started | :probe_started | :probe_failed
```

# `properties_flag`

```elixir
@type properties_flag() ::
  {:portable, boolean()} | {:just_added, String.t()} | {:added_by, String.t()}
```

# `query_result`

```elixir
@type query_result(result) :: {:ok, result} | {:error, Exqlite.Sqlite3.reason()}
```

# `security_flag`

```elixir
@type security_flag() ::
  {:s0
   | :s2_unauthenticated
   | :s2_authenticated
   | :s2_access_control
   | :known_bad, boolean()}
```

# `version_capability`

```elixir
@type version_capability() ::
  :version_get | :version_command_class_get | :version_zwave_software_get
```

# `zwave_node`

```elixir
@type zwave_node() :: %{
  id: Grizzly.zwave_node_id(),
  dsk: Grizzly.ZWave.DSK.t() | nil,
  last_awake: pos_integer(),
  last_update: pos_integer(),
  manufacturer_id: 0..65535,
  product_type: 0..65535,
  product_id: 0..65535,
  mode: [mode_flag()],
  security_flags: [security_flag()],
  properties_flags: [properties_flag()],
  probe_state: probe_state(),
  state: node_state(),
  version_capabilities: [{version_capability(), boolean()}],
  basic_device_class: Grizzly.ZWave.DeviceClasses.basic_device_class() | nil,
  wake_up_interval: non_neg_integer() | nil
}
```

# `all_endpoints`

```elixir
@spec all_endpoints(Exqlite.Sqlite3.db()) :: query_result([endpoint()])
```

Returns a list of all endpoints.

# `all_nodes`

```elixir
@spec all_nodes(Exqlite.Sqlite3.db()) :: query_result([zwave_node()])
```

Returns a list of all nodes.

# `clear_s2_sessions`

```elixir
@spec clear_s2_sessions(reference()) :: :ok | {:error, atom() | binary()}
```

Deletes all entries in the s2_span table, effectively forcing S2 resynchronization
for all nodes. This is useful if you're running a Zniffer capture and need to
capture the S2 nonce exchange in order to decrypt frames.

To ensure you capture the nonce exchange, be sure to stop Z/IP Gateway before
calling this function, then start the capture before restarting Z/IP Gateway.

# `decode_mode_flags`

```elixir
@spec decode_mode_flags(integer()) :: [mode_flag()]
```

Decodes the bitmask stored in the `nodes.mode` field into a keyword list.

# `decode_node_state`

```elixir
@spec decode_node_state(integer()) :: node_state() | :unknown
```

Decodes the bitmask stored in the `nodes.state` field into an atom.

# `decode_probe_state`

```elixir
@spec decode_probe_state(integer()) :: probe_state() | :unknown
```

Decodes the bitmask stored in the `nodes.probe_flags` field into an atom.

# `decode_properties_flags`

```elixir
@spec decode_properties_flags(integer()) :: [properties_flag()]
```

Decodes the bitmask stored in the `nodes.properties_flags` field into a keyword list.

# `decode_security_flags`

```elixir
@spec decode_security_flags(integer()) :: [security_flag()]
```

Decodes the bitmask stored in the `nodes.security_flags` field into a keyword list.

# `decode_version_capabilities`

```elixir
@spec decode_version_capabilities(integer()) :: [{version_capability(), boolean()}]
```

Decodes a node's Version CC capabilities bitmask stored in the
`nodes.node_version_cap_and_zwave_sw` field into a keyword list.

# `delete_node`

```elixir
@spec delete_node(Exqlite.Sqlite3.db(), integer()) ::
  :ok | {:error, Exqlite.Sqlite3.reason()}
```

Deletes a node (and its endpoints) from the database. The DSK field will be permanently
lost, but that's probably not a major issue.

# `execute`

```elixir
@spec execute(Exqlite.Sqlite3.db(), binary(), list()) ::
  :ok | {:error, Exqlite.Sqlite3.reason()}
```

Execute a query that doesn't return any rows. It is an error to use a select
statement with this function.

# `find_nodes_with_no_endpoints`

```elixir
@spec find_nodes_with_no_endpoints(Exqlite.Sqlite3.db()) :: query_result([map()])
```

Returns a list of nodes that have don't have any entries in the endpoints table.

# `get_endpoint`

```elixir
@spec get_endpoint(Exqlite.Sqlite3.db(), pos_integer(), non_neg_integer()) ::
  query_result(map() | nil)
```

Looks up a endpoint by node id and endpoint id and returns a map or nil if not found.
Returns endpoint 0 (the root device) if no endpoint_id is specified.

# `get_node`

```elixir
@spec get_node(Exqlite.Sqlite3.db(), integer()) :: query_result(zwave_node() | nil)
```

Looks up a node by its ID and returns a map or nil if not found.

# `get_node_endpoints`

```elixir
@spec get_node_endpoints(Exqlite.Sqlite3.db(), integer()) :: query_result([map()])
```

Returns a list of the given node's endpoints.

# `listening_mode`

```elixir
@spec listening_mode(Grizzly.node_id()) :: {:ok, listening_mode()} | nil
```

Retrieve the listening mode of a node.

# `select_all`

```elixir
@spec select_all(Exqlite.Sqlite3.db(), binary(), list()) :: query_result([map()])
```

Prepares and executes the given query. Returns a list of maps, where map keys
are column names and values are the corresponding row values.

# `select_one`

```elixir
@spec select_one(Exqlite.Sqlite3.db(), binary(), list()) :: query_result(map() | nil)
```

Same as `select_all/3`, but returns only the first row or nil.

# `with_database`

```elixir
@spec with_database((Exqlite.Sqlite3.db() -&gt; any())) :: any()
```

Same as `with_database/2`, but uses the database file pointed to by `Grizzly.options/0`.

# `with_database`

```elixir
@spec with_database(Path.t() | reference(), (Exqlite.Sqlite3.db() -&gt; any())) :: any()
```

Opens a SQLite database and passes the connection handle to the given function,
then closes the database on completion.

If the first argument is a reference to an already-open SQLite database, the
first and last steps will be skipped. This is mostly useful for testing.

If the given database file does not exist, an error will be returned. Otherwise,
the return value will be the result of the given function.

Z/IP Gateway should be stopped prior to making any modifications to the database,
otherwise it will ignore and most likely overwrite your changes. This function
will return an error if Z/IP Gateway is running and the first argument. If you
want to bypass this check, open the database and pass the connection handle.

# `with_statement`

```elixir
@spec with_statement(Exqlite.Sqlite3.db(), binary(), (Exqlite.Sqlite3.statement() -&gt;
                                                  result)) :: result
when result: var
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
