# `GeoGenius.Store`
[🔗](https://github.com/agoodway/geo_genius/blob/main/lib/geo_genius/store.ex#L1)

The contract every catalog read goes through.

A store issues one call to a shipped SQL function per read and maps the rows.
It adds no filtering, ordering, or limiting of its own: those belong to the
SQL API, where they are already specified and tested.

# `numeric`

```elixir
@type numeric() :: number() | Decimal.t()
```

A coordinate or a radius in metres.

These bind as `double precision`, and a host holds one in whatever shape it
read: a float, an integer for a whole-degree coordinate, or the `%Decimal{}`
Ecto loads from a `numeric` column. All three are accepted.

# `seeds`

```elixir
@type seeds() :: [String.t()]
```

The plural reads' seeds: many area keys, or many code values.

Each returned `GeoGenius.SeededMatch` carries the seed it came from, and a
seed that matched nothing contributes no row.

# `ancestors_of`

```elixir
@callback ancestors_of(GeoGenius.Context.t(), String.t(), keyword()) :: [
  GeoGenius.AreaMatch.t()
]
```

# `ancestors_of_many`

```elixir
@callback ancestors_of_many(GeoGenius.Context.t(), seeds(), keyword()) :: [
  GeoGenius.SeededMatch.t()
]
```

# `areas_by_code`

```elixir
@callback areas_by_code(GeoGenius.Context.t(), String.t(), String.t(), keyword()) :: [
  GeoGenius.AreaMatch.t()
]
```

# `areas_by_code_many`

```elixir
@callback areas_by_code_many(GeoGenius.Context.t(), String.t(), seeds(), keyword()) :: [
  GeoGenius.SeededMatch.t()
]
```

# `areas_for_geometry`

```elixir
@callback areas_for_geometry(GeoGenius.Context.t(), Geo.geometry(), keyword()) :: [
  GeoGenius.AreaMatch.t()
]
```

# `areas_for_point`

```elixir
@callback areas_for_point(GeoGenius.Context.t(), numeric(), numeric(), keyword()) :: [
  GeoGenius.AreaMatch.t()
]
```

# `areas_near`

```elixir
@callback areas_near(GeoGenius.Context.t(), numeric(), numeric(), numeric(), keyword()) ::
  [
    GeoGenius.AreaMatch.t()
  ]
```

# `children_of`

```elixir
@callback children_of(GeoGenius.Context.t(), String.t(), keyword()) :: [
  GeoGenius.AreaMatch.t()
]
```

# `children_of_many`

```elixir
@callback children_of_many(GeoGenius.Context.t(), seeds(), keyword()) :: [
  GeoGenius.SeededMatch.t()
]
```

# `related_areas`

```elixir
@callback related_areas(GeoGenius.Context.t(), String.t(), keyword()) :: [
  GeoGenius.AreaMatch.t()
]
```

# `related_areas_many`

```elixir
@callback related_areas_many(GeoGenius.Context.t(), seeds(), keyword()) :: [
  GeoGenius.SeededMatch.t()
]
```

# `release_at`

```elixir
@callback release_at(GeoGenius.Context.t(), DateTime.t(), keyword()) ::
  Ecto.UUID.t() | nil
```

# `resolve`

```elixir
@callback resolve(GeoGenius.Context.t(), map(), keyword()) :: [GeoGenius.AreaMatch.t()]
```

# `search_areas`

```elixir
@callback search_areas(GeoGenius.Context.t(), String.t(), keyword()) :: [
  GeoGenius.AreaMatch.t()
]
```

# `configured`

```elixir
@spec configured(keyword()) :: module()
```

The store this host configured, or the shipped default.

# `module_for_backend`

```elixir
@spec module_for_backend(String.t()) :: {:ok, module()} | {:error, :unknown_backend}
```

Resolves a backend name to its module.

---

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