
    eTjY                        d Z ddlmZ ddlZddlZ ej
                  dej                        Zd ZddZ	d Z
ddZddd	Zddd
Zy)zUltron master DB logic for the shared jarvis-tools service (Railway).
Full Supabase SQL (read + write). Creds from env SUPABASE_URL +
SUPABASE_DB_PASSWORD. Seatbelt on drop/truncate/where-less delete.
    )annotationsNz\b(drop|truncate)\bc                     t         j                  j                  dd      } t         j                  j                  dd      }| r|sy t        j                  d|       }|sy d|j                  d       d|fS )NSUPABASE_URL SUPABASE_DB_PASSWORDz//([^.]+)\.zdb.   z.supabase.co)osenvirongetresearchgroup)urlpwms      F/Users/ahmed/devFolder/Ultron/claude-voice/memory-service/ultron_db.py_credsr      se    
**..
,C	.	3BB
		.#&AL)2--    c                     t               d uS )N)r    r   r   
configuredr      s    84r   c                 Z    dd l } t               \  }}| j                  d| d| ddd      S )Nr   zhost=z" port=5432 user=postgres password=z  dbname=postgres sslmode=require   T)connect_timeout
autocommit)psycopgr   connect)r   hostr   s      r   _connectr      sE    xHD"??
v7t <* 	+<>4  Q Qr   c                    | j                         }t        j                  |      ryt        j                  d|      r&t        j                  d|t        j
                        syy)NTz(?is)^\s*(delete|update)\bz	\bwhere\bF)strip_DANGERr   r   matchI)sqlss     r   _needs_confirmr'   $   sE    		A~~a	xx-q1		,2440r   c                   t        |       j                         } | syt        |       rt        |      j                         dk7  ryt	               5 }|j                  |       }|j                  r|j                  D cg c]  }|j                   }}|j                  d      }|s
	 d d d        ydj                  |      }dj                  d |D              }t        |      dk(  rd	nd
}	| ddt        |      z   d| |	 }
|
d d t        |
      dkD  rdnd
z   cd d d        S d|j                   dcd d d        S c c}w # 1 sw Y   y xY w)Nzultron_query failed: no SQL.yesztThat statement is irreversible (drop/truncate or a WHERE-less delete/update). Re-send with confirm='yes' to proceed.i  z(0 rows) | 
c              3  L   K   | ]  }d j                  d |D                yw)r*   c              3  :   K   | ]  }|dn
t        |        y w)Nr   )str).0vs     r   	<genexpr>z"query.<locals>.<genexpr>.<genexpr>>   s     B12A6s   N)join)r/   rs     r   r1   zquery.<locals>.<genexpr>=   s$      RLPq

BBBDs   "$u   
…(first 500 rows)r   -i  u    …[truncated]u   OK — z row(s) affected.)r.   r!   r'   lowerr   executedescriptionname	fetchmanyr2   lenrowcount)r%   confirmconncurdcolsrowsheadbodymoreouts              r   queryrF   .   s:   
c(..
C-cs7|113u<I	tll3??$'OO4OqAFFOD4==%D! 
 ::d#D99 RLPR RD.1$i3.>*BDF"S3t9_-RvdV<Cu:c#ho!22N 
 &78 
 5 
s+   ,D?;D:D?-A*D?!D?:D??Ec           	     l   t        |       j                         } t               5 }| s|j                  d      j	                         D cg c]  }|d   	 }}g }|D ]A  }	 |j                  d| d      j                         d   }|j                  d| d| d       C d	d
j                  |      z   cd d d        S |j                  d| f      j	                         }|sd| dcd d d        S |  dd
j                  d |D              z   cd d d        S c c}w # t        $ r d}Y w xY w# 1 sw Y   y xY w)NzWselect table_name from information_schema.tables where table_schema='public' order by 1r   zselect count(*) from ""?-  (z rows)zTables:
r+   zselect column_name, data_type from information_schema.columns where table_schema='public' and table_name=%s order by ordinal_positionzNo table named .z
 columns:
c              3  4   K   | ]  \  }}d | d| d  yw)rJ   rK   )Nr   )r/   cts      r   r1   zschema.<locals>.<genexpr>Z   s#     0QDDAq2aS1#QDs   )	r.   r!   r   r6   fetchallfetchone	Exceptionappendr2   )tabler=   r3   tabslinesrP   nr@   s           r   schemarY   E   s[   JE	t"&,,9#::B(*#E F #EQAaD #ED F E'=aS%BCLLNqQA r!Bqc01  5!11 
 ||(*/3 4<8: 	 $UIQ/% 
& $tyy0QD0Q'QQ' 
F ! A 
sM   $D*D	D*&D-D*;(D*-D*D*D'$D*&D''D**D3)returnbool)r%   r.   rZ   r[   )r   )r%   r.   r<   r.   rZ   r.   )rU   r.   rZ   r.   )__doc__
__future__r   r	   r   compiler$   r"   r   r   r   r'   rF   rY   r   r   r   <module>r_      sL    # 	 	
"**+RTT
2. Q9.Rr   