create backend
This commit is contained in:
107
lib/mound_hunters/repo.ex
Normal file
107
lib/mound_hunters/repo.ex
Normal file
@@ -0,0 +1,107 @@
|
||||
defmodule MoundHunters.Repo do
|
||||
@moduledoc """
|
||||
Mnesia database helpers for tiles and geometries.
|
||||
"""
|
||||
|
||||
require Logger
|
||||
|
||||
# Tile statuses
|
||||
@type tile_status :: :processing | :ready | :error
|
||||
|
||||
@doc """
|
||||
Get a tile by ID from Mnesia.
|
||||
"""
|
||||
def get_tile(tile_id) do
|
||||
case :mnesia.transaction(fn ->
|
||||
:mnesia.read(:tiles, tile_id)
|
||||
end) do
|
||||
{:atomic, [tile]} -> {:ok, tile_to_map(tile)}
|
||||
{:atomic, []} -> {:error, :not_found}
|
||||
{:aborted, reason} -> {:error, reason}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Insert or update a tile record.
|
||||
"""
|
||||
def upsert_tile(attrs) do
|
||||
tile_id = Map.fetch!(attrs, :id)
|
||||
now = System.system_time(:second)
|
||||
|
||||
tile_record =
|
||||
{:tiles, tile_id, Map.get(attrs, :min_lat), Map.get(attrs, :max_lat),
|
||||
Map.get(attrs, :min_lng), Map.get(attrs, :max_lng), Map.get(attrs, :status),
|
||||
Map.get(attrs, :error_message), Map.get(attrs, :created_at, now), now}
|
||||
|
||||
case :mnesia.transaction(fn ->
|
||||
:mnesia.write(tile_record)
|
||||
end) do
|
||||
{:atomic, :ok} -> {:ok, tile_to_map(tile_record)}
|
||||
{:aborted, reason} -> {:error, reason}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Get a shared geometry by ID.
|
||||
"""
|
||||
def get_geometry(geometry_id) do
|
||||
case :mnesia.transaction(fn ->
|
||||
:mnesia.read(:geometries, geometry_id)
|
||||
end) do
|
||||
{:atomic, [geometry]} -> {:ok, geometry_to_map(geometry)}
|
||||
{:atomic, []} -> {:error, :not_found}
|
||||
{:aborted, reason} -> {:error, reason}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Create a new shared geometry.
|
||||
"""
|
||||
def create_geometry(geojson) do
|
||||
geometry_id = generate_id()
|
||||
now = System.system_time(:second)
|
||||
|
||||
geometry_record = {:geometries, geometry_id, geojson, now}
|
||||
|
||||
case :mnesia.transaction(fn ->
|
||||
:mnesia.write(geometry_record)
|
||||
end) do
|
||||
{:atomic, :ok} -> {:ok, %{id: geometry_id}}
|
||||
{:aborted, reason} -> {:error, reason}
|
||||
end
|
||||
end
|
||||
|
||||
# Convert Mnesia tile record to map
|
||||
defp tile_to_map(
|
||||
{:tiles, id, min_lat, max_lat, min_lng, max_lng, status, error_message, created_at,
|
||||
updated_at}
|
||||
) do
|
||||
%{
|
||||
id: id,
|
||||
min_lat: min_lat,
|
||||
max_lat: max_lat,
|
||||
min_lng: min_lng,
|
||||
max_lng: max_lng,
|
||||
status: status,
|
||||
error_message: error_message,
|
||||
created_at: created_at,
|
||||
updated_at: updated_at
|
||||
}
|
||||
end
|
||||
|
||||
# Convert Mnesia geometry record to map
|
||||
defp geometry_to_map({:geometries, id, geojson, created_at}) do
|
||||
%{
|
||||
id: id,
|
||||
geojson: geojson,
|
||||
created_at: created_at
|
||||
}
|
||||
end
|
||||
|
||||
# Generate random 8-character alphanumeric ID
|
||||
defp generate_id do
|
||||
:crypto.strong_rand_bytes(6)
|
||||
|> Base.url_encode64(padding: false)
|
||||
|> binary_part(0, 8)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user