Skip to main content

oxirs_core/named_graph/
mod.rs

1//! Named Graph Management API (Jena Dataset-compatible)
2//!
3//! Provides a comprehensive API for managing named RDF graphs within a dataset.
4//! This module extends the basic `Dataset` with Jena-compatible operations,
5//! iterators, transactions, and a [`GraphStore`] trait for pluggable backends.
6//!
7//! # Overview
8//!
9//! An RDF Dataset consists of:
10//! - A **default graph** (unnamed, always present)
11//! - Zero or more **named graphs**, each identified by an IRI or blank node
12//!
13//! This module provides:
14//! - [`NamedGraphManager`] – high-level dataset manager with Jena-compatible API
15//! - [`GraphStore`] – trait for pluggable triple-store backends
16//! - [`NamedGraphIterator`] – typed iterator over `(name, graph)` pairs
17//! - [`GraphStatistics`] – statistics about a dataset's contents
18//! - [`GraphName`] re-export and helper constructors
19
20use crate::model::{Graph, GraphName, NamedNode, Quad, Triple};
21use crate::{OxirsError, Result};
22use std::collections::HashMap;
23
24// ── Re-exports ────────────────────────────────────────────────────────────────
25
26/// A named-graph key: either a [`NamedNode`] IRI or blank node name (string)
27pub use crate::model::GraphName as GraphNameKey;
28
29// ── NamedGraphManager ────────────────────────────────────────────────────────
30
31/// High-level manager for named RDF graphs within a single dataset
32///
33/// Provides a Jena-compatible API for creating, querying, and managing
34/// named graphs. Each graph is identified by a [`GraphName`] key.
35///
36/// # Example
37///
38/// ```rust
39/// use oxirs_core::named_graph::NamedGraphManager;
40/// use oxirs_core::model::{GraphName, NamedNode, Literal, Triple};
41///
42/// let mut mgr = NamedGraphManager::new();
43/// let graph_iri = NamedNode::new("http://example.org/graph1").expect("valid IRI");
44/// let key = GraphName::NamedNode(graph_iri.clone());
45///
46/// // Create a named graph (auto-created on first insert)
47/// mgr.add_named_graph(key.clone());
48///
49/// // Insert a triple into that graph
50/// let subj = NamedNode::new("http://example.org/s").expect("valid IRI");
51/// let pred = NamedNode::new("http://example.org/p").expect("valid IRI");
52/// let obj  = Literal::new("hello");
53/// let triple = Triple::new(subj, pred, obj);
54/// mgr.insert_triple(&key, triple).expect("operation should succeed");
55///
56/// assert_eq!(mgr.triple_count_in(&key), 1);
57/// ```
58#[derive(Debug, Clone)]
59pub struct NamedGraphManager {
60    default_graph: Graph,
61    named_graphs: HashMap<GraphName, Graph>,
62}
63
64impl NamedGraphManager {
65    /// Create a new empty dataset manager
66    pub fn new() -> Self {
67        NamedGraphManager {
68            default_graph: Graph::new(),
69            named_graphs: HashMap::new(),
70        }
71    }
72
73    /// Create a dataset manager with an initial capacity hint for named graphs
74    pub fn with_capacity(named_graph_capacity: usize) -> Self {
75        NamedGraphManager {
76            default_graph: Graph::new(),
77            named_graphs: HashMap::with_capacity(named_graph_capacity),
78        }
79    }
80
81    // ── Default graph ─────────────────────────────────────────────────────────
82
83    /// Returns a shared reference to the default (unnamed) graph
84    pub fn default_graph(&self) -> &Graph {
85        &self.default_graph
86    }
87
88    /// Returns an exclusive reference to the default (unnamed) graph
89    pub fn default_graph_mut(&mut self) -> &mut Graph {
90        &mut self.default_graph
91    }
92
93    // ── Named graph lifecycle ─────────────────────────────────────────────────
94
95    /// Create (or ensure the existence of) a named graph
96    ///
97    /// Returns `true` if the graph was newly created, `false` if it already existed.
98    /// Has no effect on the default graph key.
99    pub fn add_named_graph(&mut self, name: GraphName) -> bool {
100        if name.is_default_graph() {
101            return false;
102        }
103        if self.named_graphs.contains_key(&name) {
104            return false;
105        }
106        self.named_graphs.insert(name, Graph::new());
107        true
108    }
109
110    /// Remove a named graph from the dataset
111    ///
112    /// Returns the removed [`Graph`] if it existed, `None` otherwise.
113    /// Calling this with the default graph key clears the default graph and
114    /// returns the old contents.
115    pub fn remove_named_graph(&mut self, name: &GraphName) -> Option<Graph> {
116        if name.is_default_graph() {
117            let mut old = Graph::new();
118            std::mem::swap(&mut old, &mut self.default_graph);
119            Some(old)
120        } else {
121            self.named_graphs.remove(name)
122        }
123    }
124
125    /// Returns a shared reference to the named graph with the given key
126    ///
127    /// Returns `None` if no such graph exists. Use the default-graph key to
128    /// access the default graph.
129    pub fn get_named_graph(&self, name: &GraphName) -> Option<&Graph> {
130        if name.is_default_graph() {
131            Some(&self.default_graph)
132        } else {
133            self.named_graphs.get(name)
134        }
135    }
136
137    /// Returns an exclusive reference to the named graph with the given key,
138    /// creating an empty graph entry if it does not exist yet.
139    pub fn get_or_create_named_graph_mut(&mut self, name: &GraphName) -> &mut Graph {
140        if name.is_default_graph() {
141            &mut self.default_graph
142        } else {
143            self.named_graphs.entry(name.clone()).or_default()
144        }
145    }
146
147    /// Returns an exclusive reference to an existing named graph
148    ///
149    /// Returns `None` if the graph does not exist (unlike
150    /// `get_or_create_named_graph_mut`).
151    pub fn get_named_graph_mut(&mut self, name: &GraphName) -> Option<&mut Graph> {
152        if name.is_default_graph() {
153            Some(&mut self.default_graph)
154        } else {
155            self.named_graphs.get_mut(name)
156        }
157    }
158
159    /// Returns `true` if a named graph with the given key exists
160    pub fn contains_named_graph(&self, name: &GraphName) -> bool {
161        if name.is_default_graph() {
162            true // default graph always exists
163        } else {
164            self.named_graphs.contains_key(name)
165        }
166    }
167
168    /// Returns an iterator over the names of all named graphs (excluding default)
169    pub fn list_named_graphs(&self) -> impl Iterator<Item = &GraphName> {
170        self.named_graphs.keys()
171    }
172
173    /// Returns the number of named graphs (excluding the default graph)
174    pub fn graph_count(&self) -> usize {
175        self.named_graphs.len()
176    }
177
178    /// Returns the total number of graphs including the default graph
179    pub fn total_graph_count(&self) -> usize {
180        self.named_graphs.len() + 1
181    }
182
183    // ── Triple operations ─────────────────────────────────────────────────────
184
185    /// Insert a triple into the specified graph
186    ///
187    /// If the graph does not exist it is created automatically.
188    /// Returns `true` if the triple was newly inserted.
189    pub fn insert_triple(&mut self, graph: &GraphName, triple: Triple) -> Result<bool> {
190        let target = self.get_or_create_named_graph_mut(graph);
191        Ok(target.insert(triple))
192    }
193
194    /// Remove a triple from the specified graph
195    ///
196    /// Returns `true` if the triple was present and removed.
197    /// Returns an error if the graph does not exist.
198    pub fn remove_triple(&mut self, graph: &GraphName, triple: &Triple) -> Result<bool> {
199        let target = self
200            .get_named_graph_mut(graph)
201            .ok_or_else(|| OxirsError::Store(format!("Graph does not exist: {graph}")))?;
202        Ok(target.remove(triple))
203    }
204
205    /// Returns `true` if the specified graph contains the given triple
206    pub fn contains_triple(&self, graph: &GraphName, triple: &Triple) -> bool {
207        self.get_named_graph(graph)
208            .is_some_and(|g| g.contains(triple))
209    }
210
211    /// Returns an owned `Vec` of all triples in the specified graph
212    ///
213    /// Returns an empty vector if the graph does not exist.
214    pub fn triples_in_graph(&self, graph: &GraphName) -> Vec<Triple> {
215        match self.get_named_graph(graph) {
216            Some(g) => g.iter().cloned().collect(),
217            None => vec![],
218        }
219    }
220
221    /// Returns the number of triples in the specified graph
222    pub fn triple_count_in(&self, graph: &GraphName) -> usize {
223        self.get_named_graph(graph).map_or(0, Graph::len)
224    }
225
226    /// Returns the total number of triples across all graphs (named + default)
227    pub fn triple_count(&self) -> usize {
228        let named_count: usize = self.named_graphs.values().map(Graph::len).sum();
229        named_count + self.default_graph.len()
230    }
231
232    /// Remove all triples from the specified graph (graph itself remains)
233    ///
234    /// Returns the number of triples removed.
235    pub fn clear_graph(&mut self, graph: &GraphName) -> Result<usize> {
236        let target = self
237            .get_named_graph_mut(graph)
238            .ok_or_else(|| OxirsError::Store(format!("Graph does not exist: {graph}")))?;
239        let count = target.len();
240        target.clear();
241        Ok(count)
242    }
243
244    /// Remove all triples from the specified graph and delete the graph entry
245    ///
246    /// Returns `true` if the graph existed. For the default graph this clears
247    /// its contents but does not destroy the graph slot.
248    pub fn drop_graph(&mut self, graph: &GraphName) -> bool {
249        if graph.is_default_graph() {
250            let was_empty = self.default_graph.is_empty();
251            self.default_graph.clear();
252            !was_empty
253        } else {
254            self.named_graphs.remove(graph).is_some()
255        }
256    }
257
258    // ── Union / aggregation operations ────────────────────────────────────────
259
260    /// Build the union graph: all triples from all named graphs merged together
261    ///
262    /// The returned [`Graph`] is a fresh copy; modifications do not affect
263    /// the original graphs.
264    pub fn union_graph(&self) -> Graph {
265        let mut union = self.default_graph.clone();
266        for graph in self.named_graphs.values() {
267            for triple in graph.iter() {
268                union.insert(triple.clone());
269            }
270        }
271        union
272    }
273
274    /// Merge all named graphs (but NOT the default graph) into a union graph
275    ///
276    /// Useful when implementing the SPARQL `UNION DEFAULT GRAPH` feature.
277    pub fn union_of_named_graphs(&self) -> Graph {
278        let mut union = Graph::new();
279        for graph in self.named_graphs.values() {
280            for triple in graph.iter() {
281                union.insert(triple.clone());
282            }
283        }
284        union
285    }
286
287    // ── Quad operations ───────────────────────────────────────────────────────
288
289    /// Insert a [`Quad`] (routing it to the appropriate named graph)
290    pub fn insert_quad(&mut self, quad: Quad) -> Result<bool> {
291        let triple = quad.to_triple();
292        let graph_name = quad.graph_name().clone();
293        self.insert_triple(&graph_name, triple)
294    }
295
296    /// Returns an iterator over all quads in the dataset
297    pub fn iter_quads(&self) -> impl Iterator<Item = Quad> + '_ {
298        let default_quads = self
299            .default_graph
300            .iter()
301            .map(|t| Quad::from_triple(t.clone()));
302        let named_quads = self.named_graphs.iter().flat_map(|(name, graph)| {
303            let name = name.clone();
304            graph
305                .iter()
306                .map(move |t| Quad::from_triple_in_graph(t.clone(), name.clone()))
307        });
308        default_quads.chain(named_quads)
309    }
310
311    // ── Statistics ────────────────────────────────────────────────────────────
312
313    /// Compute statistics for this dataset
314    pub fn statistics(&self) -> GraphStatistics {
315        let named_triple_counts: HashMap<GraphName, usize> = self
316            .named_graphs
317            .iter()
318            .map(|(name, g)| (name.clone(), g.len()))
319            .collect();
320
321        let largest_graph = self
322            .named_graphs
323            .iter()
324            .max_by_key(|(_, g)| g.len())
325            .map(|(n, _)| n.clone());
326
327        GraphStatistics {
328            named_graph_count: self.named_graphs.len(),
329            default_graph_triple_count: self.default_graph.len(),
330            named_triple_counts,
331            total_triple_count: self.triple_count(),
332            largest_named_graph: largest_graph,
333        }
334    }
335
336    // ── Bulk operations ───────────────────────────────────────────────────────
337
338    /// Load all triples from an iterator into the given named graph
339    ///
340    /// Returns the number of triples inserted (deduplicated).
341    pub fn bulk_insert<I>(&mut self, graph: &GraphName, triples: I) -> usize
342    where
343        I: IntoIterator<Item = Triple>,
344    {
345        let target = self.get_or_create_named_graph_mut(graph);
346        let before = target.len();
347        target.extend(triples);
348        target.len() - before
349    }
350
351    /// Copy all triples from `source` graph into `destination` graph
352    ///
353    /// Returns the number of triples copied (may be fewer if destination
354    /// already contains some of them).
355    pub fn copy_graph(&mut self, source: &GraphName, destination: &GraphName) -> Result<usize> {
356        // Collect source triples first to avoid borrow conflict
357        let source_triples: Vec<Triple> = match self.get_named_graph(source) {
358            Some(g) => g.iter().cloned().collect(),
359            None => {
360                return Err(OxirsError::Store(format!(
361                    "Source graph does not exist: {source}"
362                )))
363            }
364        };
365        Ok(self.bulk_insert(destination, source_triples))
366    }
367
368    /// Move all triples from `source` graph into `destination` graph
369    ///
370    /// The source graph is emptied (but kept) after the operation.
371    /// Returns the number of triples moved.
372    pub fn move_graph(&mut self, source: &GraphName, destination: &GraphName) -> Result<usize> {
373        // Drain source
374        let source_triples: Vec<Triple> = {
375            let src = self.get_named_graph_mut(source).ok_or_else(|| {
376                OxirsError::Store(format!("Source graph does not exist: {source}"))
377            })?;
378            let triples: Vec<_> = src.iter().cloned().collect();
379            src.clear();
380            triples
381        };
382        Ok(self.bulk_insert(destination, source_triples))
383    }
384}
385
386impl Default for NamedGraphManager {
387    fn default() -> Self {
388        Self::new()
389    }
390}
391
392// ── GraphStatistics ───────────────────────────────────────────────────────────
393
394/// Statistics collected from a [`NamedGraphManager`]
395#[derive(Debug, Clone)]
396pub struct GraphStatistics {
397    /// Number of named graphs (excluding default)
398    pub named_graph_count: usize,
399    /// Number of triples in the default graph
400    pub default_graph_triple_count: usize,
401    /// Per-graph triple counts
402    pub named_triple_counts: HashMap<GraphName, usize>,
403    /// Total triples across all graphs
404    pub total_triple_count: usize,
405    /// The name of the named graph with the most triples
406    pub largest_named_graph: Option<GraphName>,
407}
408
409impl GraphStatistics {
410    /// Returns the average triple count across named graphs (0.0 if none)
411    pub fn average_named_graph_size(&self) -> f64 {
412        if self.named_graph_count == 0 {
413            return 0.0;
414        }
415        let total: usize = self.named_triple_counts.values().sum();
416        total as f64 / self.named_graph_count as f64
417    }
418
419    /// Returns `true` if the dataset is completely empty
420    pub fn is_empty(&self) -> bool {
421        self.total_triple_count == 0
422    }
423}
424
425// ── NamedGraphIterator ────────────────────────────────────────────────────────
426
427/// An owned iterator over `(GraphName, Graph)` pairs from a [`NamedGraphManager`]
428pub struct NamedGraphIterator {
429    inner: std::vec::IntoIter<(GraphName, Graph)>,
430}
431
432impl NamedGraphIterator {
433    /// Create an iterator from a [`NamedGraphManager`], consuming the named graphs
434    pub fn from_manager(manager: NamedGraphManager) -> Self {
435        let pairs: Vec<(GraphName, Graph)> = manager.named_graphs.into_iter().collect();
436        NamedGraphIterator {
437            inner: pairs.into_iter(),
438        }
439    }
440}
441
442impl Iterator for NamedGraphIterator {
443    type Item = (GraphName, Graph);
444
445    fn next(&mut self) -> Option<Self::Item> {
446        self.inner.next()
447    }
448
449    fn size_hint(&self) -> (usize, Option<usize>) {
450        self.inner.size_hint()
451    }
452}
453
454impl ExactSizeIterator for NamedGraphIterator {}
455
456// ── GraphStore trait ──────────────────────────────────────────────────────────
457
458/// Trait for pluggable named-graph triple-store backends
459///
460/// Implementors provide the six core operations needed to manage triples
461/// within named graphs. See [`NamedGraphManager`] for an in-memory implementation.
462pub trait GraphStore {
463    /// Add a triple to the given graph
464    ///
465    /// Returns `Ok(true)` if the triple was newly inserted.
466    fn add_triple(&mut self, graph: &GraphName, triple: Triple) -> Result<bool>;
467
468    /// Remove a triple from the given graph
469    ///
470    /// Returns `Ok(true)` if the triple was present.
471    fn remove_triple(&mut self, graph: &GraphName, triple: &Triple) -> Result<bool>;
472
473    /// Returns `true` if the graph contains the triple
474    fn contains_triple(&self, graph: &GraphName, triple: &Triple) -> Result<bool>;
475
476    /// Returns an owned list of all triples in the graph
477    fn triples_in_graph(&self, graph: &GraphName) -> Result<Vec<Triple>>;
478
479    /// Remove all triples from the graph (graph entry is kept)
480    ///
481    /// Returns the number of triples removed.
482    fn clear_graph(&mut self, graph: &GraphName) -> Result<usize>;
483
484    /// Delete the graph and all its triples
485    ///
486    /// Returns `Ok(true)` if the graph existed.
487    fn drop_graph(&mut self, graph: &GraphName) -> Result<bool>;
488}
489
490/// In-memory implementation of [`GraphStore`] backed by [`NamedGraphManager`]
491impl GraphStore for NamedGraphManager {
492    fn add_triple(&mut self, graph: &GraphName, triple: Triple) -> Result<bool> {
493        self.insert_triple(graph, triple)
494    }
495
496    fn remove_triple(&mut self, graph: &GraphName, triple: &Triple) -> Result<bool> {
497        self.remove_triple(graph, triple)
498    }
499
500    fn contains_triple(&self, graph: &GraphName, triple: &Triple) -> Result<bool> {
501        Ok(self.contains_triple(graph, triple))
502    }
503
504    fn triples_in_graph(&self, graph: &GraphName) -> Result<Vec<Triple>> {
505        Ok(self.triples_in_graph(graph))
506    }
507
508    fn clear_graph(&mut self, graph: &GraphName) -> Result<usize> {
509        self.clear_graph(graph)
510    }
511
512    fn drop_graph(&mut self, graph: &GraphName) -> Result<bool> {
513        Ok(self.drop_graph(graph))
514    }
515}
516
517// ── Helper constructors ───────────────────────────────────────────────────────
518
519/// Convenience function: create a [`GraphName`] key from an IRI string
520///
521/// Returns `Err` if the IRI is invalid.
522pub fn graph_name_from_iri(iri: &str) -> Result<GraphName> {
523    let node = NamedNode::new(iri).map_err(|e| OxirsError::Parse(e.to_string()))?;
524    Ok(GraphName::NamedNode(node))
525}
526
527/// Convenience function: create a default-graph [`GraphName`] key
528pub fn default_graph_name() -> GraphName {
529    GraphName::DefaultGraph
530}
531
532// ── Tests ─────────────────────────────────────────────────────────────────────
533
534#[cfg(test)]
535mod tests {
536    use super::*;
537    use crate::model::{Literal, NamedNode, Triple};
538
539    // ── Helper constructors ───────────────────────────────────────────────────
540
541    fn iri(s: &str) -> NamedNode {
542        NamedNode::new(s).expect("valid IRI")
543    }
544
545    fn graph_key(s: &str) -> GraphName {
546        GraphName::NamedNode(iri(s))
547    }
548
549    fn triple(s: &str, p: &str, o: &str) -> Triple {
550        Triple::new(iri(s), iri(p), Literal::new(o))
551    }
552
553    // ── NamedGraphManager::new / default ─────────────────────────────────────
554
555    #[test]
556    fn test_new_manager_is_empty() {
557        let mgr = NamedGraphManager::new();
558        assert_eq!(mgr.graph_count(), 0);
559        assert_eq!(mgr.triple_count(), 0);
560    }
561
562    #[test]
563    fn test_default_manager_is_empty() {
564        let mgr = NamedGraphManager::default();
565        assert_eq!(mgr.graph_count(), 0);
566    }
567
568    #[test]
569    fn test_with_capacity_starts_empty() {
570        let mgr = NamedGraphManager::with_capacity(32);
571        assert_eq!(mgr.graph_count(), 0);
572        assert!(mgr.triple_count() == 0);
573    }
574
575    #[test]
576    fn test_total_graph_count_includes_default() {
577        let mgr = NamedGraphManager::new();
578        assert_eq!(mgr.total_graph_count(), 1); // only default
579    }
580
581    // ── add_named_graph ───────────────────────────────────────────────────────
582
583    #[test]
584    fn test_add_named_graph_returns_true_on_creation() {
585        let mut mgr = NamedGraphManager::new();
586        let key = graph_key("http://example.org/g1");
587        assert!(mgr.add_named_graph(key));
588    }
589
590    #[test]
591    fn test_add_named_graph_returns_false_if_already_exists() {
592        let mut mgr = NamedGraphManager::new();
593        let key = graph_key("http://example.org/g1");
594        mgr.add_named_graph(key.clone());
595        assert!(!mgr.add_named_graph(key));
596    }
597
598    #[test]
599    fn test_add_named_graph_increments_count() {
600        let mut mgr = NamedGraphManager::new();
601        mgr.add_named_graph(graph_key("http://example.org/g1"));
602        assert_eq!(mgr.graph_count(), 1);
603    }
604
605    #[test]
606    fn test_add_default_graph_key_is_noop() {
607        let mut mgr = NamedGraphManager::new();
608        let result = mgr.add_named_graph(GraphName::DefaultGraph);
609        assert!(!result);
610        assert_eq!(mgr.graph_count(), 0);
611    }
612
613    #[test]
614    fn test_add_multiple_named_graphs() {
615        let mut mgr = NamedGraphManager::new();
616        for i in 0..5 {
617            mgr.add_named_graph(graph_key(&format!("http://example.org/g{i}")));
618        }
619        assert_eq!(mgr.graph_count(), 5);
620        assert_eq!(mgr.total_graph_count(), 6);
621    }
622
623    // ── contains_named_graph ──────────────────────────────────────────────────
624
625    #[test]
626    fn test_contains_named_graph_true_after_add() {
627        let mut mgr = NamedGraphManager::new();
628        let key = graph_key("http://example.org/g1");
629        mgr.add_named_graph(key.clone());
630        assert!(mgr.contains_named_graph(&key));
631    }
632
633    #[test]
634    fn test_contains_named_graph_false_before_add() {
635        let mgr = NamedGraphManager::new();
636        assert!(!mgr.contains_named_graph(&graph_key("http://example.org/missing")));
637    }
638
639    #[test]
640    fn test_contains_default_graph_always_true() {
641        let mgr = NamedGraphManager::new();
642        assert!(mgr.contains_named_graph(&GraphName::DefaultGraph));
643    }
644
645    // ── get_named_graph ───────────────────────────────────────────────────────
646
647    #[test]
648    fn test_get_named_graph_returns_some_after_add() {
649        let mut mgr = NamedGraphManager::new();
650        let key = graph_key("http://example.org/g1");
651        mgr.add_named_graph(key.clone());
652        assert!(mgr.get_named_graph(&key).is_some());
653    }
654
655    #[test]
656    fn test_get_named_graph_returns_none_if_absent() {
657        let mgr = NamedGraphManager::new();
658        assert!(mgr
659            .get_named_graph(&graph_key("http://example.org/absent"))
660            .is_none());
661    }
662
663    #[test]
664    fn test_get_default_graph_always_some() {
665        let mgr = NamedGraphManager::new();
666        assert!(mgr.get_named_graph(&GraphName::DefaultGraph).is_some());
667    }
668
669    // ── remove_named_graph ────────────────────────────────────────────────────
670
671    #[test]
672    fn test_remove_named_graph_returns_some_if_existed() {
673        let mut mgr = NamedGraphManager::new();
674        let key = graph_key("http://example.org/g1");
675        mgr.add_named_graph(key.clone());
676        assert!(mgr.remove_named_graph(&key).is_some());
677    }
678
679    #[test]
680    fn test_remove_named_graph_returns_none_if_absent() {
681        let mut mgr = NamedGraphManager::new();
682        assert!(mgr
683            .remove_named_graph(&graph_key("http://example.org/absent"))
684            .is_none());
685    }
686
687    #[test]
688    fn test_remove_named_graph_decrements_count() {
689        let mut mgr = NamedGraphManager::new();
690        let key = graph_key("http://example.org/g1");
691        mgr.add_named_graph(key.clone());
692        mgr.remove_named_graph(&key);
693        assert_eq!(mgr.graph_count(), 0);
694    }
695
696    #[test]
697    fn test_remove_default_graph_clears_contents() {
698        let mut mgr = NamedGraphManager::new();
699        let t = triple("http://example.org/s", "http://example.org/p", "hello");
700        mgr.insert_triple(&GraphName::DefaultGraph, t)
701            .expect("operation should succeed");
702        assert_eq!(mgr.default_graph().len(), 1);
703        let removed = mgr.remove_named_graph(&GraphName::DefaultGraph);
704        assert!(removed.is_some());
705        assert_eq!(mgr.default_graph().len(), 0);
706    }
707
708    // ── insert_triple / contains_triple ──────────────────────────────────────
709
710    #[test]
711    fn test_insert_triple_returns_true_on_new() {
712        let mut mgr = NamedGraphManager::new();
713        let key = graph_key("http://example.org/g1");
714        let t = triple("http://s.org/s", "http://p.org/p", "o");
715        assert!(mgr
716            .insert_triple(&key, t)
717            .expect("operation should succeed"));
718    }
719
720    #[test]
721    fn test_insert_triple_returns_false_on_duplicate() {
722        let mut mgr = NamedGraphManager::new();
723        let key = graph_key("http://example.org/g1");
724        let t = triple("http://s.org/s", "http://p.org/p", "o");
725        mgr.insert_triple(&key, t.clone())
726            .expect("triple insert should succeed");
727        assert!(!mgr
728            .insert_triple(&key, t)
729            .expect("operation should succeed"));
730    }
731
732    #[test]
733    fn test_insert_triple_auto_creates_graph() {
734        let mut mgr = NamedGraphManager::new();
735        let key = graph_key("http://example.org/g1");
736        let t = triple("http://s.org/s", "http://p.org/p", "o");
737        assert!(!mgr.contains_named_graph(&key));
738        mgr.insert_triple(&key, t)
739            .expect("operation should succeed");
740        assert!(mgr.contains_named_graph(&key));
741    }
742
743    #[test]
744    fn test_contains_triple_true_after_insert() {
745        let mut mgr = NamedGraphManager::new();
746        let key = graph_key("http://example.org/g1");
747        let t = triple("http://s.org/s", "http://p.org/p", "o");
748        mgr.insert_triple(&key, t.clone())
749            .expect("triple insert should succeed");
750        assert!(mgr.contains_triple(&key, &t));
751    }
752
753    #[test]
754    fn test_contains_triple_false_in_wrong_graph() {
755        let mut mgr = NamedGraphManager::new();
756        let key1 = graph_key("http://example.org/g1");
757        let key2 = graph_key("http://example.org/g2");
758        let t = triple("http://s.org/s", "http://p.org/p", "o");
759        mgr.insert_triple(&key1, t.clone())
760            .expect("triple insert should succeed");
761        assert!(!mgr.contains_triple(&key2, &t));
762    }
763
764    #[test]
765    fn test_triple_count_in_named_graph() {
766        let mut mgr = NamedGraphManager::new();
767        let key = graph_key("http://example.org/g1");
768        for i in 0..7 {
769            let t = triple(&format!("http://s.org/s{i}"), "http://p.org/p", "o");
770            mgr.insert_triple(&key, t)
771                .expect("operation should succeed");
772        }
773        assert_eq!(mgr.triple_count_in(&key), 7);
774    }
775
776    #[test]
777    fn test_triple_count_total_across_graphs() {
778        let mut mgr = NamedGraphManager::new();
779        for g in 0..3 {
780            let key = graph_key(&format!("http://example.org/g{g}"));
781            for i in 0..4 {
782                let t = triple(&format!("http://s.org/s{i}"), "http://p.org/p", "o");
783                mgr.insert_triple(&key, t)
784                    .expect("operation should succeed");
785            }
786        }
787        assert_eq!(mgr.triple_count(), 12);
788    }
789
790    // ── remove_triple ─────────────────────────────────────────────────────────
791
792    #[test]
793    fn test_remove_triple_returns_true_if_present() {
794        let mut mgr = NamedGraphManager::new();
795        let key = graph_key("http://example.org/g1");
796        let t = triple("http://s.org/s", "http://p.org/p", "o");
797        mgr.insert_triple(&key, t.clone())
798            .expect("triple insert should succeed");
799        assert!(mgr
800            .remove_triple(&key, &t)
801            .expect("operation should succeed"));
802    }
803
804    #[test]
805    fn test_remove_triple_returns_false_if_absent() {
806        let mut mgr = NamedGraphManager::new();
807        let key = graph_key("http://example.org/g1");
808        mgr.add_named_graph(key.clone());
809        let t = triple("http://s.org/s", "http://p.org/p", "o");
810        assert!(!mgr
811            .remove_triple(&key, &t)
812            .expect("operation should succeed"));
813    }
814
815    #[test]
816    fn test_remove_triple_from_nonexistent_graph_is_error() {
817        let mut mgr = NamedGraphManager::new();
818        let key = graph_key("http://example.org/absent");
819        let t = triple("http://s.org/s", "http://p.org/p", "o");
820        assert!(mgr.remove_triple(&key, &t).is_err());
821    }
822
823    #[test]
824    fn test_remove_triple_decrements_count() {
825        let mut mgr = NamedGraphManager::new();
826        let key = graph_key("http://example.org/g1");
827        let t = triple("http://s.org/s", "http://p.org/p", "o");
828        mgr.insert_triple(&key, t.clone())
829            .expect("triple insert should succeed");
830        mgr.remove_triple(&key, &t)
831            .expect("operation should succeed");
832        assert_eq!(mgr.triple_count_in(&key), 0);
833    }
834
835    // ── triples_in_graph ──────────────────────────────────────────────────────
836
837    #[test]
838    fn test_triples_in_graph_returns_all() {
839        let mut mgr = NamedGraphManager::new();
840        let key = graph_key("http://example.org/g1");
841        let t1 = triple("http://s.org/s1", "http://p.org/p", "o1");
842        let t2 = triple("http://s.org/s2", "http://p.org/p", "o2");
843        mgr.insert_triple(&key, t1.clone())
844            .expect("triple insert should succeed");
845        mgr.insert_triple(&key, t2.clone())
846            .expect("triple insert should succeed");
847        let triples = mgr.triples_in_graph(&key);
848        assert_eq!(triples.len(), 2);
849        assert!(triples.contains(&t1));
850        assert!(triples.contains(&t2));
851    }
852
853    #[test]
854    fn test_triples_in_nonexistent_graph_is_empty() {
855        let mgr = NamedGraphManager::new();
856        assert!(mgr
857            .triples_in_graph(&graph_key("http://example.org/absent"))
858            .is_empty());
859    }
860
861    // ── clear_graph ───────────────────────────────────────────────────────────
862
863    #[test]
864    fn test_clear_graph_removes_all_triples() {
865        let mut mgr = NamedGraphManager::new();
866        let key = graph_key("http://example.org/g1");
867        let t = triple("http://s.org/s", "http://p.org/p", "o");
868        mgr.insert_triple(&key, t)
869            .expect("operation should succeed");
870        let cleared = mgr.clear_graph(&key).expect("operation should succeed");
871        assert_eq!(cleared, 1);
872        assert_eq!(mgr.triple_count_in(&key), 0);
873    }
874
875    #[test]
876    fn test_clear_graph_keeps_graph_entry() {
877        let mut mgr = NamedGraphManager::new();
878        let key = graph_key("http://example.org/g1");
879        mgr.add_named_graph(key.clone());
880        mgr.clear_graph(&key).expect("operation should succeed");
881        assert!(mgr.contains_named_graph(&key));
882    }
883
884    #[test]
885    fn test_clear_nonexistent_graph_is_error() {
886        let mut mgr = NamedGraphManager::new();
887        let key = graph_key("http://example.org/absent");
888        assert!(mgr.clear_graph(&key).is_err());
889    }
890
891    // ── drop_graph ────────────────────────────────────────────────────────────
892
893    #[test]
894    fn test_drop_graph_removes_graph_entry() {
895        let mut mgr = NamedGraphManager::new();
896        let key = graph_key("http://example.org/g1");
897        mgr.add_named_graph(key.clone());
898        assert!(mgr.drop_graph(&key));
899        assert!(!mgr.contains_named_graph(&key));
900    }
901
902    #[test]
903    fn test_drop_graph_returns_false_if_absent() {
904        let mut mgr = NamedGraphManager::new();
905        assert!(!mgr.drop_graph(&graph_key("http://example.org/absent")));
906    }
907
908    #[test]
909    fn test_drop_default_graph_clears_triples() {
910        let mut mgr = NamedGraphManager::new();
911        let t = triple("http://s.org/s", "http://p.org/p", "o");
912        mgr.insert_triple(&GraphName::DefaultGraph, t)
913            .expect("operation should succeed");
914        let result = mgr.drop_graph(&GraphName::DefaultGraph);
915        assert!(result);
916        assert_eq!(mgr.default_graph().len(), 0);
917    }
918
919    // ── union_graph ───────────────────────────────────────────────────────────
920
921    #[test]
922    fn test_union_graph_merges_all_triples() {
923        let mut mgr = NamedGraphManager::new();
924        let k1 = graph_key("http://example.org/g1");
925        let k2 = graph_key("http://example.org/g2");
926        let t1 = triple("http://s.org/s1", "http://p.org/p", "o1");
927        let t2 = triple("http://s.org/s2", "http://p.org/p", "o2");
928        mgr.insert_triple(&k1, t1.clone())
929            .expect("triple insert should succeed");
930        mgr.insert_triple(&k2, t2.clone())
931            .expect("triple insert should succeed");
932        let union = mgr.union_graph();
933        assert!(union.contains(&t1));
934        assert!(union.contains(&t2));
935        assert_eq!(union.len(), 2);
936    }
937
938    #[test]
939    fn test_union_graph_includes_default_graph() {
940        let mut mgr = NamedGraphManager::new();
941        let t = triple("http://s.org/s", "http://p.org/p", "o");
942        mgr.insert_triple(&GraphName::DefaultGraph, t.clone())
943            .expect("operation should succeed");
944        let union = mgr.union_graph();
945        assert!(union.contains(&t));
946    }
947
948    #[test]
949    fn test_union_graph_deduplicates() {
950        let mut mgr = NamedGraphManager::new();
951        let k1 = graph_key("http://example.org/g1");
952        let k2 = graph_key("http://example.org/g2");
953        let t = triple("http://s.org/s", "http://p.org/p", "o");
954        mgr.insert_triple(&k1, t.clone())
955            .expect("triple insert should succeed");
956        mgr.insert_triple(&k2, t.clone())
957            .expect("triple insert should succeed");
958        let union = mgr.union_graph();
959        assert_eq!(union.len(), 1);
960    }
961
962    #[test]
963    fn test_union_of_named_graphs_excludes_default() {
964        let mut mgr = NamedGraphManager::new();
965        let k1 = graph_key("http://example.org/g1");
966        let t_named = triple("http://s.org/named", "http://p.org/p", "o");
967        let t_default = triple("http://s.org/default", "http://p.org/p", "o");
968        mgr.insert_triple(&k1, t_named.clone())
969            .expect("triple insert should succeed");
970        mgr.insert_triple(&GraphName::DefaultGraph, t_default.clone())
971            .expect("operation should succeed");
972        let union = mgr.union_of_named_graphs();
973        assert!(union.contains(&t_named));
974        assert!(!union.contains(&t_default));
975    }
976
977    // ── list_named_graphs ─────────────────────────────────────────────────────
978
979    #[test]
980    fn test_list_named_graphs_empty_when_none() {
981        let mgr = NamedGraphManager::new();
982        assert_eq!(mgr.list_named_graphs().count(), 0);
983    }
984
985    #[test]
986    fn test_list_named_graphs_returns_correct_count() {
987        let mut mgr = NamedGraphManager::new();
988        for i in 0..4 {
989            mgr.add_named_graph(graph_key(&format!("http://example.org/g{i}")));
990        }
991        assert_eq!(mgr.list_named_graphs().count(), 4);
992    }
993
994    #[test]
995    fn test_list_named_graphs_contains_added_keys() {
996        let mut mgr = NamedGraphManager::new();
997        let key = graph_key("http://example.org/myGraph");
998        mgr.add_named_graph(key.clone());
999        let names: Vec<_> = mgr.list_named_graphs().collect();
1000        assert!(names.contains(&&key));
1001    }
1002
1003    // ── bulk operations ───────────────────────────────────────────────────────
1004
1005    #[test]
1006    fn test_bulk_insert_returns_inserted_count() {
1007        let mut mgr = NamedGraphManager::new();
1008        let key = graph_key("http://example.org/g1");
1009        let triples: Vec<Triple> = (0..5)
1010            .map(|i| triple(&format!("http://s.org/s{i}"), "http://p.org/p", "o"))
1011            .collect();
1012        let count = mgr.bulk_insert(&key, triples);
1013        assert_eq!(count, 5);
1014    }
1015
1016    #[test]
1017    fn test_bulk_insert_deduplicates() {
1018        let mut mgr = NamedGraphManager::new();
1019        let key = graph_key("http://example.org/g1");
1020        let t = triple("http://s.org/s", "http://p.org/p", "o");
1021        mgr.bulk_insert(&key, vec![t.clone(), t]);
1022        assert_eq!(mgr.triple_count_in(&key), 1);
1023    }
1024
1025    #[test]
1026    fn test_copy_graph_copies_all_triples() {
1027        let mut mgr = NamedGraphManager::new();
1028        let src = graph_key("http://example.org/src");
1029        let dst = graph_key("http://example.org/dst");
1030        let t = triple("http://s.org/s", "http://p.org/p", "o");
1031        mgr.insert_triple(&src, t.clone())
1032            .expect("triple insert should succeed");
1033        mgr.copy_graph(&src, &dst)
1034            .expect("operation should succeed");
1035        assert!(mgr.contains_triple(&dst, &t));
1036        assert!(mgr.contains_triple(&src, &t)); // source not cleared
1037    }
1038
1039    #[test]
1040    fn test_copy_nonexistent_graph_is_error() {
1041        let mut mgr = NamedGraphManager::new();
1042        let src = graph_key("http://example.org/absent");
1043        let dst = graph_key("http://example.org/dst");
1044        assert!(mgr.copy_graph(&src, &dst).is_err());
1045    }
1046
1047    #[test]
1048    fn test_move_graph_empties_source() {
1049        let mut mgr = NamedGraphManager::new();
1050        let src = graph_key("http://example.org/src");
1051        let dst = graph_key("http://example.org/dst");
1052        let t = triple("http://s.org/s", "http://p.org/p", "o");
1053        mgr.insert_triple(&src, t.clone())
1054            .expect("triple insert should succeed");
1055        mgr.move_graph(&src, &dst)
1056            .expect("operation should succeed");
1057        assert_eq!(mgr.triple_count_in(&src), 0);
1058        assert!(mgr.contains_triple(&dst, &t));
1059    }
1060
1061    #[test]
1062    fn test_move_nonexistent_graph_is_error() {
1063        let mut mgr = NamedGraphManager::new();
1064        let src = graph_key("http://example.org/absent");
1065        let dst = graph_key("http://example.org/dst");
1066        assert!(mgr.move_graph(&src, &dst).is_err());
1067    }
1068
1069    // ── insert_quad ───────────────────────────────────────────────────────────
1070
1071    #[test]
1072    fn test_insert_quad_into_named_graph() {
1073        let mut mgr = NamedGraphManager::new();
1074        let graph_node = iri("http://example.org/g1");
1075        let quad = Quad::new(
1076            iri("http://s.org/s"),
1077            iri("http://p.org/p"),
1078            Literal::new("o"),
1079            graph_node,
1080        );
1081        mgr.insert_quad(quad).expect("operation should succeed");
1082        assert_eq!(mgr.triple_count(), 1);
1083    }
1084
1085    #[test]
1086    fn test_insert_quad_into_default_graph() {
1087        let mut mgr = NamedGraphManager::new();
1088        let quad = Quad::new_default_graph(
1089            iri("http://s.org/s"),
1090            iri("http://p.org/p"),
1091            Literal::new("o"),
1092        );
1093        mgr.insert_quad(quad).expect("operation should succeed");
1094        assert_eq!(mgr.default_graph().len(), 1);
1095    }
1096
1097    // ── iter_quads ────────────────────────────────────────────────────────────
1098
1099    #[test]
1100    fn test_iter_quads_covers_all_graphs() {
1101        let mut mgr = NamedGraphManager::new();
1102        let k1 = graph_key("http://example.org/g1");
1103        let k2 = graph_key("http://example.org/g2");
1104        mgr.insert_triple(&k1, triple("http://s.org/s1", "http://p.org/p", "o"))
1105            .expect("operation should succeed");
1106        mgr.insert_triple(&k2, triple("http://s.org/s2", "http://p.org/p", "o"))
1107            .expect("operation should succeed");
1108        mgr.insert_triple(
1109            &GraphName::DefaultGraph,
1110            triple("http://s.org/s3", "http://p.org/p", "o"),
1111        )
1112        .expect("operation should succeed");
1113        let count = mgr.iter_quads().count();
1114        assert_eq!(count, 3);
1115    }
1116
1117    // ── GraphStatistics ───────────────────────────────────────────────────────
1118
1119    #[test]
1120    fn test_statistics_empty_dataset() {
1121        let mgr = NamedGraphManager::new();
1122        let stats = mgr.statistics();
1123        assert_eq!(stats.named_graph_count, 0);
1124        assert_eq!(stats.total_triple_count, 0);
1125        assert!(stats.is_empty());
1126    }
1127
1128    #[test]
1129    fn test_statistics_named_graph_count() {
1130        let mut mgr = NamedGraphManager::new();
1131        for i in 0..3 {
1132            mgr.add_named_graph(graph_key(&format!("http://example.org/g{i}")));
1133        }
1134        assert_eq!(mgr.statistics().named_graph_count, 3);
1135    }
1136
1137    #[test]
1138    fn test_statistics_total_triple_count() {
1139        let mut mgr = NamedGraphManager::new();
1140        let key = graph_key("http://example.org/g1");
1141        for i in 0..6 {
1142            mgr.insert_triple(
1143                &key,
1144                triple(&format!("http://s.org/s{i}"), "http://p.org/p", "o"),
1145            )
1146            .expect("operation should succeed");
1147        }
1148        assert_eq!(mgr.statistics().total_triple_count, 6);
1149    }
1150
1151    #[test]
1152    fn test_statistics_largest_named_graph() {
1153        let mut mgr = NamedGraphManager::new();
1154        let big = graph_key("http://example.org/big");
1155        let small = graph_key("http://example.org/small");
1156        for i in 0..10 {
1157            mgr.insert_triple(
1158                &big,
1159                triple(&format!("http://s.org/s{i}"), "http://p.org/p", "o"),
1160            )
1161            .expect("operation should succeed");
1162        }
1163        mgr.insert_triple(&small, triple("http://s.org/s", "http://p.org/p", "o"))
1164            .expect("operation should succeed");
1165        let stats = mgr.statistics();
1166        assert_eq!(stats.largest_named_graph, Some(big));
1167    }
1168
1169    #[test]
1170    fn test_statistics_average_size_zero_when_no_named_graphs() {
1171        let mgr = NamedGraphManager::new();
1172        assert_eq!(mgr.statistics().average_named_graph_size(), 0.0);
1173    }
1174
1175    #[test]
1176    fn test_statistics_average_named_graph_size() {
1177        let mut mgr = NamedGraphManager::new();
1178        let k1 = graph_key("http://example.org/g1");
1179        let k2 = graph_key("http://example.org/g2");
1180        for i in 0..4 {
1181            mgr.insert_triple(
1182                &k1,
1183                triple(&format!("http://s.org/s{i}"), "http://p.org/p", "o"),
1184            )
1185            .expect("operation should succeed");
1186        }
1187        for i in 0..2 {
1188            mgr.insert_triple(
1189                &k2,
1190                triple(&format!("http://s.org/s{i}"), "http://p.org/p", "x"),
1191            )
1192            .expect("operation should succeed");
1193        }
1194        // avg = (4 + 2) / 2 = 3.0
1195        assert!((mgr.statistics().average_named_graph_size() - 3.0).abs() < 1e-10);
1196    }
1197
1198    // ── NamedGraphIterator ────────────────────────────────────────────────────
1199
1200    #[test]
1201    fn test_named_graph_iterator_yields_all_graphs() {
1202        let mut mgr = NamedGraphManager::new();
1203        for i in 0..4 {
1204            mgr.add_named_graph(graph_key(&format!("http://example.org/g{i}")));
1205        }
1206        let iter = NamedGraphIterator::from_manager(mgr);
1207        assert_eq!(iter.count(), 4);
1208    }
1209
1210    #[test]
1211    fn test_named_graph_iterator_size_hint() {
1212        let mut mgr = NamedGraphManager::new();
1213        for i in 0..3 {
1214            mgr.add_named_graph(graph_key(&format!("http://example.org/g{i}")));
1215        }
1216        let iter = NamedGraphIterator::from_manager(mgr);
1217        let (lower, upper) = iter.size_hint();
1218        assert_eq!(lower, 3);
1219        assert_eq!(upper, Some(3));
1220    }
1221
1222    // ── GraphStore trait ──────────────────────────────────────────────────────
1223
1224    #[test]
1225    fn test_graph_store_add_triple() {
1226        let mut store: Box<dyn GraphStore> = Box::new(NamedGraphManager::new());
1227        let key = graph_key("http://example.org/g1");
1228        let t = triple("http://s.org/s", "http://p.org/p", "o");
1229        assert!(store
1230            .add_triple(&key, t)
1231            .expect("store operation should succeed"));
1232    }
1233
1234    #[test]
1235    fn test_graph_store_contains_triple() {
1236        let mut store = NamedGraphManager::new();
1237        let key = graph_key("http://example.org/g1");
1238        let t = triple("http://s.org/s", "http://p.org/p", "o");
1239        GraphStore::add_triple(&mut store, &key, t.clone()).expect("add triple should succeed");
1240        assert!(GraphStore::contains_triple(&store, &key, &t)
1241            .expect("GraphStore operation should succeed"));
1242    }
1243
1244    #[test]
1245    fn test_graph_store_remove_triple() {
1246        let mut store = NamedGraphManager::new();
1247        let key = graph_key("http://example.org/g1");
1248        let t = triple("http://s.org/s", "http://p.org/p", "o");
1249        GraphStore::add_triple(&mut store, &key, t.clone()).expect("add triple should succeed");
1250        assert!(GraphStore::remove_triple(&mut store, &key, &t)
1251            .expect("GraphStore operation should succeed"));
1252    }
1253
1254    #[test]
1255    fn test_graph_store_triples_in_graph() {
1256        let mut store = NamedGraphManager::new();
1257        let key = graph_key("http://example.org/g1");
1258        let t = triple("http://s.org/s", "http://p.org/p", "o");
1259        GraphStore::add_triple(&mut store, &key, t.clone()).expect("add triple should succeed");
1260        let triples = GraphStore::triples_in_graph(&store, &key)
1261            .expect("GraphStore operation should succeed");
1262        assert_eq!(triples.len(), 1);
1263        assert!(triples.contains(&t));
1264    }
1265
1266    #[test]
1267    fn test_graph_store_clear_graph() {
1268        let mut store = NamedGraphManager::new();
1269        let key = graph_key("http://example.org/g1");
1270        let t = triple("http://s.org/s", "http://p.org/p", "o");
1271        GraphStore::add_triple(&mut store, &key, t).expect("GraphStore operation should succeed");
1272        let cleared =
1273            GraphStore::clear_graph(&mut store, &key).expect("GraphStore operation should succeed");
1274        assert_eq!(cleared, 1);
1275    }
1276
1277    #[test]
1278    fn test_graph_store_drop_graph() {
1279        let mut store = NamedGraphManager::new();
1280        let key = graph_key("http://example.org/g1");
1281        store.add_named_graph(key.clone());
1282        assert!(
1283            GraphStore::drop_graph(&mut store, &key).expect("GraphStore operation should succeed")
1284        );
1285    }
1286
1287    // ── Helper functions ──────────────────────────────────────────────────────
1288
1289    #[test]
1290    fn test_graph_name_from_iri_valid() {
1291        let key = graph_name_from_iri("http://example.org/g1");
1292        assert!(key.is_ok());
1293        assert!(matches!(
1294            key.expect("key should be valid"),
1295            GraphName::NamedNode(_)
1296        ));
1297    }
1298
1299    #[test]
1300    fn test_graph_name_from_iri_invalid() {
1301        let key = graph_name_from_iri("not a valid IRI!!!");
1302        assert!(key.is_err());
1303    }
1304
1305    #[test]
1306    fn test_default_graph_name_is_default() {
1307        let key = default_graph_name();
1308        assert!(key.is_default_graph());
1309    }
1310}