1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//! Blocking cursor

use parking_lot::RwLock;

use crate::{Cursor, Result, Rows, oci::*, stmt::cols::Columns};

impl<'a> Cursor<'a> {
    /**
    Returns rows selected by this cursor

    # Example

    ```
    use sibyl::Cursor;

    # let oracle = sibyl::env()?;
    # let dbname = std::env::var("DBNAME")?;
    # let dbuser = std::env::var("DBUSER")?;
    # let dbpass = std::env::var("DBPASS")?;
    # let session = oracle.connect(&dbname, &dbuser, &dbpass)?;
    let stmt = session.prepare("
        SELECT last_name
             , CURSOR(
                    SELECT department_name
                      FROM hr.departments
                     WHERE department_id IN (
                                SELECT department_id
                                  FROM hr.employees
                                 WHERE last_name = e.last_name)
                  ORDER BY department_name
               ) AS departments
          FROM (
                SELECT DISTINCT last_name
                  FROM hr.employees
                 WHERE last_name = :last_name
               ) e
    ")?;
    let rows = stmt.query("King")?;

    let row = rows.next()?.unwrap();
    let last_name : &str = row.get_not_null(0)?;
    assert_eq!(last_name, "King");

    let departments : Cursor = row.get_not_null(1)?;
    let mut dept_rows = departments.rows()?;
    let dept_row = dept_rows.next()?.unwrap();

    let department_name : &str = dept_row.get_not_null(0)?;
    assert_eq!(department_name, "Executive");

    let dept_row = dept_rows.next()?.unwrap();
    let department_name : &str = dept_row.get_not_null(0)?;
    assert_eq!(department_name, "Sales");

    assert!(dept_rows.next()?.is_none());
    assert!(rows.next()?.is_none());
    # Ok::<(),Box<dyn std::error::Error>>(())
    ```
    */
    pub fn rows(&self) -> Result<Rows> {
        if self.cols.get().is_none() {
            let cols = Columns::new(Ptr::from(self.as_ref()), Ptr::from(self.as_ref()), Ptr::from(self.as_ref()), self.max_long)?;
            self.cols.get_or_init(|| RwLock::new(cols));
        };
        Ok( Rows::from_cursor(OCI_SUCCESS, self) )
    }
}