Skip to content

Commit

Permalink
https://github.com/manifold-systems/manifold/issues/605
Browse files Browse the repository at this point in the history
- support duckdb as proposed

#606
- add batch support as proposed
  • Loading branch information
rsmckinney committed Jun 29, 2024
1 parent cedce98 commit ce33b2b
Show file tree
Hide file tree
Showing 29 changed files with 3,077 additions and 128 deletions.
12 changes: 11 additions & 1 deletion manifold-deps-parent/manifold-sql-inproc-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@
<version>3.40.1.0</version>
</dependency>


<dependency>
<groupId>org.duckdb</groupId>
<artifactId>duckdb_jdbc</artifactId>
<version>1.0.0</version>
</dependency>

<!-- for testing H2's GEOMETRY type -->
<dependency>
<groupId>org.locationtech.jts</groupId>
Expand Down Expand Up @@ -90,6 +95,11 @@
<artifactId>sqlite-jdbc</artifactId>
<version>3.40.1.0</version>
</path>
<path>
<groupId>org.duckdb</groupId>
<artifactId>duckdb_jdbc</artifactId>
<version>1.0.0</version>
</path>
<path>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2023 - Manifold Systems LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package manifold.sql.schema.duckdb;

import manifold.ext.rt.api.auto;
import manifold.sql.rt.api.TxScope;
import manifold.sql.schema.simple.duckdb.DuckdbSakila;
import manifold.sql.schema.simple.duckdb.DuckdbSakila.*;
import manifold.sql.schema.duckdb.base.DuckdbDdlServerTest;
import org.junit.Test;

import java.sql.SQLException;

import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import static org.junit.Assert.*;

public class CrudTest extends DuckdbDdlServerTest
{
@Test
public void testCreate() throws SQLException
{
TxScope txScope = DuckdbSakila.newScope();

for( Country cu: "[.sql:DuckdbSakila/] select * from country".fetch() )
{
System.out.println(cu);
}
Country hi = Country.create( txScope, "mycountry" );
txScope.commit();
// test that country_id was assigned after the insert
assertTrue( hi.getCountryId() > 0 );

auto row = "[.sql:DuckdbSakila/] SELECT country_id FROM Country where country = 'mycountry'"
.fetchOne( txScope );
assertEquals( row.getCountryId(), hi.getCountryId() );
}

@Test
public void testRead() throws SQLException
{
TxScope txScope = DuckdbSakila.newScope();
Country hi = Country.create( txScope, "mycountry" );
txScope.commit();

Country readHi = Country.fetch( txScope, hi.getCountryId() );
assertEquals( readHi.getCountryId(), hi.getCountryId() );
}

@Test
public void testUpdate() throws SQLException
{
TxScope txScope = DuckdbSakila.newScope();
Country hi = Country.create( txScope, "mycountry" );
txScope.commit();
// test that country_id was assigned after the insert
assertTrue( hi.getCountryId() > 0 );

hi.setCountry( "mycountry2" );
txScope.commit();

Country readHi = Country.fetch( txScope, hi.getCountryId() );
assertEquals( "mycountry2", hi.getCountry() );
}

@Test
public void testDelete() throws SQLException
{
TxScope txScope = DuckdbSakila.newScope();
Country hi = Country.create( txScope, "mycountry" );
txScope.commit();
// test that country_id was assigned after the insert
assertTrue( hi.getCountryId() > 0 );

int countryId = hi.getCountryId();

hi.delete();
txScope.commit();
Country readHi = Country.fetch( txScope, countryId );
assertNull( readHi );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2023 - Manifold Systems LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package manifold.sql.schema.duckdb;

import manifold.sql.schema.duckdb.base.DuckdbDdlServerTest;
import manifold.sql.schema.simple.duckdb.DuckdbSakila;
import manifold.sql.schema.simple.duckdb.DuckdbSakila.City;
import manifold.sql.schema.simple.duckdb.DuckdbSakila.Country;
import org.junit.Test;

import java.sql.SQLException;

import static org.junit.Assert.*;

public class FkDependencyTest extends DuckdbDdlServerTest
{
@Test
public void testOneDependency() throws SQLException
{
Country country = Country.builder( "westamerica" ).build();
City city = City.builder( "flippinton", country ).build();

// pk is initially null
assertNull( country.getCountryId() );
assertNull( city.getCityId() );

DuckdbSakila.commit();

// country's pk was written into country after the commit
assertTrue( country.getCountryId() > 0 );
// city's pk was written into city after the commit
assertTrue( city.getCityId() > 0 );
// country's pk was written into city's fk after the commit
assertEquals( country.getCountryId(), city.getCountryId() );

// check that the rows are in the db
Country readCountry = Country.fetch( country.getCountryId() );
assertNotNull( readCountry );
// also sanity check from direct sql
Country countryFromSql = "[.sql:DuckdbSakila/] select * from country where country_id = :country_id".fetchOne( country.getCountryId() );
assertEquals( country.getCountryId(), countryFromSql.getCountryId() );

assertEquals( country.getCountryId(), readCountry.getCountryId() );
City readCity = City.fetch( city.getCityId() );
assertNotNull( readCity );
assertEquals( city.getCityId(), readCity.getCityId() );
assertEquals( country.getCountryId(), readCity.getCountryId() );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2023 - Manifold Systems LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package manifold.sql.schema.duckdb;

import manifold.sql.schema.duckdb.base.DuckdbDdlServerTest;
import manifold.sql.schema.simple.duckdb.DuckdbSakila;
import manifold.sql.schema.simple.duckdb.DuckdbSakila.Category;
import manifold.sql.schema.simple.duckdb.DuckdbSakila.Film;
import manifold.sql.schema.simple.duckdb.DuckdbSakila.FilmCategory;
import manifold.sql.schema.simple.duckdb.DuckdbSakila.Language;
import org.junit.Test;

import java.sql.SQLException;
import java.util.List;

import static org.junit.Assert.assertEquals;

public class ManyToManyTest extends DuckdbDdlServerTest
{
@Test
public void testManyToMany() throws SQLException
{
Language myLanguage = Language.create("My Language");
Film myFilm = Film.create("My Film", myLanguage );
Film myOtherFilm = Film.create("My Other Film", myLanguage );
Category myCat = Category.create( "My Category" );
Category myOtherCat = Category.create( "My Other Category" );
FilmCategory myFilmCategory = FilmCategory.create( myFilm, myCat );
FilmCategory myFilmOtherCategory = FilmCategory.create( myFilm, myOtherCat );
FilmCategory myOtherFilmCategory = FilmCategory.create( myOtherFilm, myCat );

DuckdbSakila.commit();

List<Category> categories = myFilm.fetchCategoryRefs();
assertEquals( 2, categories.size() );
Category c = categories.get( 0 );
assertEquals( "My Category", c.getName() );
c = categories.get( 1 );
assertEquals( "My Other Category", c.getName() );

categories = myOtherFilm.fetchCategoryRefs();
assertEquals( 1, categories.size() );
c = categories.get( 0 );
assertEquals( "My Category", c.getName() );

List<Film> films = myCat.fetchFilmRefs();
assertEquals( 2, films.size() );
Film f = films.get( 0 );
assertEquals( "My Film", f.getTitle() );
f = films.get( 1 );
assertEquals( "My Other Film", f.getTitle() );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2023 - Manifold Systems LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package manifold.sql.schema.duckdb;

import manifold.sql.schema.duckdb.base.DuckdbDdlServerTest;
import manifold.sql.schema.simple.duckdb.DuckdbSakila;
import manifold.sql.schema.simple.duckdb.DuckdbSakila.City;
import manifold.sql.schema.simple.duckdb.DuckdbSakila.Country;
import org.junit.Test;

import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class OneToManyTest extends DuckdbDdlServerTest
{
@Test
public void testOneToMany() throws SQLException
{
Country myCountry = Country.create( "My Country" );
City myCity = City.create( "My City", myCountry );
City otherCity = City.create( "Other City", myCountry );

DuckdbSakila.commit();

List<City> cities = myCountry.fetchCityRefs();
assertEquals( 2, cities.size() );

List<String> cityNames = cities.stream().map( City::getCity ).collect( Collectors.toList() );
assertTrue( cityNames.contains( myCity.getCity() ) );
assertTrue( cityNames.contains( otherCity.getCity() ) );
}
}
Loading

0 comments on commit ce33b2b

Please sign in to comment.