o
    „¼|j=  ã                   @   sž   d Z ddlZddlZddlZej dd¡Zej dd¡Zej dd¡Zg d	¢Z	g d
¢Z
dgZdZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zddd„Zdd„ ZdS )u9  Shared helpers for the Asset Inventory page.

Hierarchy: Site â†’ Container (connex / truck / toolbox / â€¦) â†’ Category â†’ Item.
One versioned SQLite DB (connex.db). Categories are per-container and fully custom
(container_categories table); items/photos reference a category by name. Photo bytes
live on disk under PHOTO_DIR; the DB stores only the filename.

Journal mode is DELETE (not WAL): the DB is written directly by a www-data CGI, and the
project rule is that any DB touched by a www-data CGI must be DELETE journal to avoid
"readonly database" surprises.
é    NÚ	CONNEX_DBz/opt/ngon/data/connex.dbÚCONNEX_PHOTO_DIRz/opt/ngon/data/connex_photosÚMASTER_CONFIGz#/opt/ngon/config/master_config.json)ÚITÚGensÚPodsÚGaszMiner RepairzGood Minersz
Bad MinersÚTools)ÚConnexÚTruckÚToolboxÚTrailerÚShedzHearne Officeap  
CREATE TABLE IF NOT EXISTS meta (
    key   TEXT PRIMARY KEY,
    value TEXT
);
CREATE TABLE IF NOT EXISTS containers (
    id         INTEGER PRIMARY KEY AUTOINCREMENT,
    name       TEXT NOT NULL,
    site       TEXT NOT NULL,
    type       TEXT NOT NULL DEFAULT 'Connex',
    position   REAL DEFAULT 0,
    created_by TEXT,
    created_at TEXT
);
CREATE TABLE IF NOT EXISTS container_categories (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    container_id INTEGER NOT NULL REFERENCES containers(id) ON DELETE CASCADE,
    name         TEXT NOT NULL,
    position     REAL DEFAULT 0,
    UNIQUE(container_id, name)
);
CREATE TABLE IF NOT EXISTS items (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    container_id INTEGER NOT NULL REFERENCES containers(id) ON DELETE CASCADE,
    category     TEXT NOT NULL,
    description  TEXT NOT NULL,
    quantity     INTEGER NOT NULL DEFAULT 0,
    position     REAL DEFAULT 0,
    created_by   TEXT,
    created_at   TEXT
);
CREATE TABLE IF NOT EXISTS photos (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    container_id INTEGER NOT NULL REFERENCES containers(id) ON DELETE CASCADE,
    category     TEXT NOT NULL,
    filename     TEXT NOT NULL,
    orig_name    TEXT,
    caption      TEXT,
    uploaded_by  TEXT,
    uploaded_at  TEXT
);
CREATE TABLE IF NOT EXISTS site_order (
    site     TEXT PRIMARY KEY,
    position REAL DEFAULT 0
);
CREATE INDEX IF NOT EXISTS idx_items_container  ON items(container_id);
CREATE INDEX IF NOT EXISTS idx_photos_container ON photos(container_id);
CREATE INDEX IF NOT EXISTS idx_cats_container   ON container_categories(container_id);
c                 C   s   |   d|f¡ ¡ d uS )Nz9SELECT 1 FROM sqlite_master WHERE type='table' AND name=?)ÚexecuteÚfetchone)ÚconnÚname© r   ú&/var/www/html/ngon/connex/connex_db.pyÚ_table_existsT   s
   ÿÿr   c              	      sæ   t | dƒr
t | dƒrdS |  d¡ |  d¡ |  d¡ |  d¡ |  t¡ dd	„ ttƒD ƒ‰ |  d
¡ ¡ }i }|D ]\}}| |tƒ ¡ 	|¡ q9| 
¡ D ]$\}}t|‡ fdd„d�D ]}ˆ  |d¡d }|  d||t|ƒf¡ qZqLdS )uN  One-time migration from the original connex-only schema to the container model:
      connexes â†’ containers (+type='Connex'), items/photos connex_id â†’ container_id,
      and backfill container_categories from the distinct categories already in use.
    Runs only when the legacy `connexes` table exists and `containers` does not.ÚconnexesÚ
containersNz)ALTER TABLE connexes RENAME TO containerszEALTER TABLE containers ADD COLUMN type TEXT NOT NULL DEFAULT 'Connex'z:ALTER TABLE items  RENAME COLUMN connex_id TO container_idz:ALTER TABLE photos RENAME COLUMN connex_id TO container_idc                 S   s   i | ]\}}||“qS r   r   )Ú.0Úir   r   r   r   Ú
<dictcomp>h   s    z0_migrate_connex_to_container.<locals>.<dictcomp>zXSELECT container_id, category FROM items UNION SELECT container_id, category FROM photosc                    s   ˆ   | d¡|  ¡ fS )Niç  )ÚgetÚlower)Úc©Úorderr   r   Ú<lambda>p   s    z._migrate_connex_to_container.<locals>.<lambda>)Úkeyi„  é   zWINSERT OR IGNORE INTO container_categories(container_id, name, position) VALUES (?,?,?))r   r   ÚexecutescriptÚ_SCHEMAÚ	enumerateÚSUGGESTED_CATEGORIESÚfetchallÚ
setdefaultÚsetÚaddÚitemsÚsortedr   Úfloat)r   ÚpairsÚseenÚcontainer_idÚcategoryÚcatsÚcatÚposr   r   r   Ú_migrate_connex_to_containerY   s2   




ÿþþþÿr5   c                  C   sN   t  t¡} t j| _|  d¡ |  d¡ t| ƒ |  t¡ |  d¡ |  	¡  | S )zOOpen connex.db, migrate/ensure schema + version row, return a Row-factory conn.zPRAGMA journal_mode=DELETEzPRAGMA foreign_keys=ONz>INSERT OR IGNORE INTO meta(key, value) VALUES ('version', '0'))
Úsqlite3ÚconnectÚDBÚRowÚrow_factoryr   r5   r#   r$   Úcommit©r   r   r   r   Úget_dbw   s   




r=   c                 C   s"   |   d¡ ¡ }|rt|d ƒS dS )Nz*SELECT value FROM meta WHERE key='version'r   )r   r   Úint)r   Úrowr   r   r   Úget_version„   s   r@   c                 C   s   |   d¡ t| ƒS )NzTUPDATE meta SET value = CAST(CAST(value AS INTEGER) + 1 AS TEXT) WHERE key='version')r   r@   r<   r   r   r   Úbump_version‰   s   
rA   Ú r   c                 C   s,   |   d|› d|› �|¡ ¡ }t|d ƒd S )Nz'SELECT COALESCE(MAX(position), 0) FROM ú r   g      ð?)r   r   r-   )r   ÚtableÚ	where_sqlÚ
where_argsr?   r   r   r   Únext_positionŽ   s   ÿþrG   c                  C   sv   t tƒ} z*ttƒ�}t |¡}W d  ƒ n1 sw   Y  |  | d¡p&i  ¡ ¡ W t
| ƒS  t	y:   Y t
| ƒS w )z›Sorted site names for the container 'site' picker: master_config sites plus any
    one-off EXTRA_SITES (e.g. Hearne Office) that aren't real mining sites.NÚsites)r)   ÚEXTRA_SITESÚopenr   ÚjsonÚloadÚupdater   ÚkeysÚ	Exceptionr,   )ÚnamesÚfÚcfgr   r   r   Ú
site_names•   s   
ÿþþrS   )rB   r   )Ú__doc__rK   Úosr6   Úenvironr   r8   Ú	PHOTO_DIRr   r&   ÚSUGGESTED_CONTAINER_TYPESrI   r$   r   r5   r=   r@   rA   rG   rS   r   r   r   r   Ú<module>   s$   3
