Skip to content

Commit 0e84849

Browse files
committed
Adds set_catalog and current_catalog to session
1 parent 51fdbe4 commit 0e84849

File tree

6 files changed

+113
-24
lines changed

6 files changed

+113
-24
lines changed

daft/session.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ def create_catalog(self, name: str) -> Catalog:
6868
"""Create a new catalog scoped to this session."""
6969
return self._session.create_catalog(name)
7070

71-
def create_namespace(self, name: str) -> Namespace:
72-
"""Create a new namespace scope to this session's current catalog."""
73-
return self._session.create_namespace(name)
71+
# def create_namespace(self, name: str) -> Namespace:
72+
# """Create a new namespace scope to this session's current catalog."""
73+
# return self._session.create_namespace(name)
7474

7575
def create_table(self, name: str, source: TableSource = None) -> Table:
7676
"""Creates a new table scoped to this session's current catalog and namespace."""
@@ -90,9 +90,9 @@ def current_catalog(self) -> Catalog:
9090
"""Returns the session's current catalog."""
9191
return self._session.current_catalog()
9292

93-
def current_namespace(self) -> Namespace:
94-
"""Returns the session's current namespace."""
95-
return self._session.current_namespace()
93+
# def current_namespace(self) -> Namespace:
94+
# """Returns the session's current namespace."""
95+
# return self._session.current_namespace()
9696

9797
###
9898
# get_*

src/daft-catalog/src/catalog.rs

+5
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ impl Catalogs {
5050
.map(|k| k.to_string())
5151
.collect()
5252
}
53+
54+
/// Returns true iff there are no catalogs in this collection.
55+
pub fn is_empty(&self) -> bool {
56+
self.0.is_empty()
57+
}
5358
}
5459

5560
/// A catalog provides object metadata such as namespaces, tables, and functions.

src/daft-catalog/src/python.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use std::sync::Arc;
22

33
use pyo3::{exceptions::PyIndexError, prelude::*};
44

5-
use crate::{Catalog, Identifier};
5+
use crate::{Catalog, Identifier, Table};
6+
use crate::error::{Error,Result};
67

78
/// PyCatalog implements the Catalog ABC for some Catalog trait impl (rust->py).
89
#[pyclass]
@@ -36,7 +37,7 @@ impl Catalog for PyCatalogImpl {
3637
todo!()
3738
}
3839

39-
fn get_table(&self, _name: &Identifier) -> crate::error::Result<Option<Box<dyn crate::Table>>> {
40+
fn get_table(&self, _name: &Identifier) -> Result<Option<Box<dyn Table>>> {
4041
todo!()
4142
}
4243

src/daft-session/src/python.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@ impl PySession {
2929
}
3030

3131
pub fn attach(&self, catalog: PyObject, alias: String) -> PyResult<()> {
32-
self.0.attach(Arc::new(PyCatalogImpl::from(catalog)), alias)?;
33-
Ok(())
32+
Ok(self.0.attach(Arc::new(PyCatalogImpl::from(catalog)), alias)?)
3433
}
3534

3635
pub fn detach(&self, catalog: &str) -> PyResult<()> {
37-
self.0.detach(catalog)?;
38-
Ok(())
36+
Ok(self.0.detach(catalog)?)
3937
}
4038

4139
pub fn create_catalog(&self, name: &str) -> PyResult<PyCatalog> {
@@ -56,7 +54,6 @@ impl PySession {
5654
let catalog = catalog.to_py(py);
5755
Ok(catalog)
5856
})
59-
6057
}
6158

6259
pub fn get_namespace(&self, name: &str) -> Namespace {
@@ -67,27 +64,28 @@ impl PySession {
6764
todo!()
6865
}
6966

67+
#[pyo3(signature = (pattern=None))]
7068
pub fn list_catalogs(&self, pattern: Option<&str>) -> PyResult<Vec<String>> {
71-
let catalogs = self.0.list_catalogs(pattern)?;
72-
Ok(catalogs)
69+
Ok(self.0.list_catalogs(pattern)?)
7370
}
7471

72+
#[pyo3(signature = (pattern=None))]
7573
pub fn list_namespaces(&self, pattern: Option<&str>) -> PyResult<()> {
7674
todo!()
7775
}
7876

77+
#[pyo3(signature = (pattern=None))]
7978
pub fn list_tables(&self, pattern: Option<&str>) -> PyResult<()> {
8079
todo!()
8180
}
8281

83-
pub fn set_catalog(&self, name: &str) {
84-
todo!()
82+
pub fn set_catalog(&self, name: &str) -> PyResult<()> {
83+
Ok(self.0.set_catalog(name)?)
8584
}
8685

87-
pub fn set_namespace(&self, name: &str) {
86+
pub fn set_namespace(&self, name: String) {
8887
todo!()
8988
}
90-
9189
}
9290

9391
pub fn register_modules(parent: &Bound<PyModule>) -> PyResult<()> {

src/daft-session/src/session.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ impl Session {
9292

9393
/// Returns the session's current catalog.
9494
pub fn current_catalog(&self) -> Result<Arc<dyn Catalog>> {
95-
todo!()
95+
self.get_catalog(&self.state().options.curr_catalog)
9696
}
9797

9898
/// Returns the session's current schema.
@@ -120,19 +120,35 @@ impl Session {
120120
obj_not_found_err!("Table", name)
121121
}
122122

123-
/// Returns true iff the session has for the given identifier
123+
/// Returns true iff the session has access to a matching catalog.
124+
pub fn has_catalog(&self, name: &str) -> bool {
125+
self.state().catalogs.exists(name)
126+
}
127+
128+
/// Returns true iff the session has access to a matching table.
124129
pub fn has_table(&self, name: &Identifier) -> bool {
125130
if name.has_namespace() {
126131
return false;
127132
}
128133
return self.state().tables.contains_key(&name.name);
129134
}
130135

136+
/// Lists all catalogs matching the pattern.
131137
pub fn list_catalogs(&self, pattern: Option<&str>) -> Result<Vec<String>> {
132138
Ok(self.state().catalogs.list(pattern))
133139
}
140+
141+
/// Sets the current_catalog
142+
pub fn set_catalog(&self, name: &str) -> Result<()> {
143+
if !self.has_catalog(name) {
144+
obj_not_found_err!("Catalog", &name.into())
145+
}
146+
self.state_mut().options.curr_catalog = name.to_string();
147+
Ok(())
148+
}
134149
}
135150

151+
136152
impl Default for Session {
137153
fn default() -> Self {
138154
Self::empty()

tests/test_session.py

+72-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,78 @@
11
import daft
2+
from daft.session import Session
23

3-
###
4-
# SESSION SETUP
5-
###
4+
import pytest
65

6+
"""
7+
SESSION SETUP
8+
"""
79

810
def test_current_session_exists():
911
assert daft.current_session() is not None
12+
13+
"""
14+
ATTACH & DETACH
15+
"""
16+
17+
def test_attach():
18+
sess = Session.empty()
19+
#
20+
# create some 'existing' catalogs
21+
cat1 = daft.load_catalog("cat1")
22+
cat2 = daft.load_catalog("cat2")
23+
#
24+
# attach them..
25+
sess.attach(cat1)
26+
sess.attach(cat2)
27+
#
28+
# list_catalogs
29+
assert 2 == len(sess.list_catalogs())
30+
#
31+
# get_catalog
32+
assert sess.get_catalog("cat1") == cat1
33+
assert sess.get_catalog("cat2") == cat2
34+
#
35+
# error!
36+
with pytest.raises(Exception, match="already exists"):
37+
sess.attach(cat1)
38+
39+
def test_detach():
40+
sess = Session.empty()
41+
#
42+
# setup.
43+
cat1 = daft.load_catalog("cat1")
44+
cat2 = daft.load_catalog("cat2")
45+
sess.attach(cat1)
46+
sess.attach(cat2)
47+
#
48+
#
49+
assert 2 == len(sess.list_catalogs())
50+
#
51+
# detach existing
52+
sess.detach("cat1")
53+
assert 1 == len(sess.list_catalogs())
54+
#
55+
# error!
56+
with pytest.raises(Exception, match="not found"):
57+
sess.detach("cat1")
58+
59+
"""
60+
CATALOG ACTIONS
61+
"""
62+
63+
@pytest.mark.skip
64+
def test_catalog_actions():
65+
sess = Session.empty()
66+
#
67+
# setup.
68+
cat1 = daft.load_catalog("cat1")
69+
cat2 = daft.load_catalog("cat2")
70+
sess.attach(cat1)
71+
sess.attach(cat2)
72+
#
73+
# current_catalog should default to first in.
74+
assert cat1 == sess.current_catalog()
75+
#
76+
# set_catalog and current_catalog
77+
sess.set_catalog("cat2")
78+
assert cat2 == sess.current_catalog()

0 commit comments

Comments
 (0)