@@ -7,6 +7,59 @@ use crate::traits::ObservationStore;
77use async_trait:: async_trait;
88use opencode_mem_core:: { Observation , SearchResult } ;
99
10+ impl PgStorage {
11+ async fn update_observation_fields (
12+ & self ,
13+ tx : & mut sqlx:: Transaction < ' _ , sqlx:: Postgres > ,
14+ id : & str ,
15+ merged : & opencode_mem_core:: MergeResult ,
16+ ) -> Result < ( ) , StorageError > {
17+ sqlx:: query (
18+ "UPDATE observations SET facts = $1, keywords = $2, files_read = $3,
19+ files_modified = $4, narrative = $5, created_at = $6, concepts = $7,
20+ noise_level = $8, subtitle = $9, noise_reason = $10,
21+ prompt_number = $11, discovery_tokens = $12, title = $14, observation_type = $15
22+ WHERE id = $13" ,
23+ )
24+ . bind ( serde_json:: to_value ( & merged. facts ) ?)
25+ . bind ( serde_json:: to_value ( & merged. keywords ) ?)
26+ . bind ( serde_json:: to_value ( & merged. files_read ) ?)
27+ . bind ( serde_json:: to_value ( & merged. files_modified ) ?)
28+ . bind ( & merged. narrative )
29+ . bind ( merged. created_at )
30+ . bind ( serde_json:: to_value ( & merged. concepts ) ?)
31+ . bind ( merged. noise_level . as_str ( ) )
32+ . bind ( & merged. subtitle )
33+ . bind ( & merged. noise_reason )
34+ . bind (
35+ merged
36+ . prompt_number
37+ . map ( |v| v. as_pg_i32 ( ) )
38+ . transpose ( )
39+ . map_err ( |e| StorageError :: DataCorruption {
40+ context : "prompt_number exceeds i32::MAX" . into ( ) ,
41+ source : Box :: < dyn std:: error:: Error + Send + Sync > :: from ( e. to_string ( ) ) ,
42+ } ) ?,
43+ )
44+ . bind (
45+ merged
46+ . discovery_tokens
47+ . map ( |v| v. as_pg_i32 ( ) )
48+ . transpose ( )
49+ . map_err ( |e| StorageError :: DataCorruption {
50+ context : "discovery_tokens exceeds i32::MAX" . into ( ) ,
51+ source : Box :: < dyn std:: error:: Error + Send + Sync > :: from ( e. to_string ( ) ) ,
52+ } ) ?,
53+ )
54+ . bind ( id)
55+ . bind ( & merged. title )
56+ . bind ( merged. observation_type . as_str ( ) )
57+ . execute ( & mut * * tx)
58+ . await ?;
59+ Ok ( ( ) )
60+ }
61+ }
62+
1063#[ async_trait]
1164impl ObservationStore for PgStorage {
1265 async fn save_observation ( & self , obs : & Observation ) -> Result < bool , StorageError > {
@@ -224,48 +277,8 @@ impl ObservationStore for PgStorage {
224277
225278 let merged = opencode_mem_core:: compute_merge ( & existing, newer, force_newer) ;
226279
227- sqlx:: query (
228- "UPDATE observations SET facts = $1, keywords = $2, files_read = $3,
229- files_modified = $4, narrative = $5, created_at = $6, concepts = $7,
230- noise_level = $8, subtitle = $9, noise_reason = $10,
231- prompt_number = $11, discovery_tokens = $12, title = $14, observation_type = $15
232- WHERE id = $13" ,
233- )
234- . bind ( serde_json:: to_value ( & merged. facts ) ?)
235- . bind ( serde_json:: to_value ( & merged. keywords ) ?)
236- . bind ( serde_json:: to_value ( & merged. files_read ) ?)
237- . bind ( serde_json:: to_value ( & merged. files_modified ) ?)
238- . bind ( & merged. narrative )
239- . bind ( merged. created_at )
240- . bind ( serde_json:: to_value ( & merged. concepts ) ?)
241- . bind ( merged. noise_level . as_str ( ) )
242- . bind ( & merged. subtitle )
243- . bind ( & merged. noise_reason )
244- . bind (
245- merged
246- . prompt_number
247- . map ( |v| v. as_pg_i32 ( ) )
248- . transpose ( )
249- . map_err ( |e| StorageError :: DataCorruption {
250- context : "prompt_number exceeds i32::MAX" . into ( ) ,
251- source : Box :: < dyn std:: error:: Error + Send + Sync > :: from ( e. to_string ( ) ) ,
252- } ) ?,
253- )
254- . bind (
255- merged
256- . discovery_tokens
257- . map ( |v| v. as_pg_i32 ( ) )
258- . transpose ( )
259- . map_err ( |e| StorageError :: DataCorruption {
260- context : "discovery_tokens exceeds i32::MAX" . into ( ) ,
261- source : Box :: < dyn std:: error:: Error + Send + Sync > :: from ( e. to_string ( ) ) ,
262- } ) ?,
263- )
264- . bind ( existing_id)
265- . bind ( & merged. title )
266- . bind ( merged. observation_type . as_str ( ) )
267- . execute ( & mut * tx)
268- . await ?;
280+ self . update_observation_fields ( & mut tx, existing_id, & merged)
281+ . await ?;
269282
270283 tx. commit ( ) . await ?;
271284 Ok ( ( ) )
@@ -321,48 +334,8 @@ impl ObservationStore for PgStorage {
321334 let merged = opencode_mem_core:: compute_merge ( & keeper, & duplicate, false ) ;
322335
323336 // 3. Update keeper with merged data
324- sqlx:: query (
325- "UPDATE observations SET facts = $1, keywords = $2, files_read = $3,
326- files_modified = $4, narrative = $5, created_at = $6, concepts = $7,
327- noise_level = $8, subtitle = $9, noise_reason = $10,
328- prompt_number = $11, discovery_tokens = $12, title = $14, observation_type = $15
329- WHERE id = $13" ,
330- )
331- . bind ( serde_json:: to_value ( & merged. facts ) ?)
332- . bind ( serde_json:: to_value ( & merged. keywords ) ?)
333- . bind ( serde_json:: to_value ( & merged. files_read ) ?)
334- . bind ( serde_json:: to_value ( & merged. files_modified ) ?)
335- . bind ( & merged. narrative )
336- . bind ( merged. created_at )
337- . bind ( serde_json:: to_value ( & merged. concepts ) ?)
338- . bind ( merged. noise_level . as_str ( ) )
339- . bind ( & merged. subtitle )
340- . bind ( & merged. noise_reason )
341- . bind (
342- merged
343- . prompt_number
344- . map ( |v| v. as_pg_i32 ( ) )
345- . transpose ( )
346- . map_err ( |e| StorageError :: DataCorruption {
347- context : "prompt_number exceeds i32::MAX" . into ( ) ,
348- source : Box :: < dyn std:: error:: Error + Send + Sync > :: from ( e. to_string ( ) ) ,
349- } ) ?,
350- )
351- . bind (
352- merged
353- . discovery_tokens
354- . map ( |v| v. as_pg_i32 ( ) )
355- . transpose ( )
356- . map_err ( |e| StorageError :: DataCorruption {
357- context : "discovery_tokens exceeds i32::MAX" . into ( ) ,
358- source : Box :: < dyn std:: error:: Error + Send + Sync > :: from ( e. to_string ( ) ) ,
359- } ) ?,
360- )
361- . bind ( keeper_id)
362- . bind ( & merged. title )
363- . bind ( merged. observation_type . as_str ( ) )
364- . execute ( & mut * tx)
365- . await ?;
337+ self . update_observation_fields ( & mut tx, keeper_id, & merged)
338+ . await ?;
366339
367340 // 4. Repoint knowledge entries (replace duplicate_id with keeper_id in jsonb array)
368341 // Correct PostgreSQL logic: remove duplicate_id, add keeper_id, then DISTINCT to avoid duplicates.
0 commit comments