/* * 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 org.jdbi.v3.postgres; import static org.assertj.core.api.Assertions.assertThat; import java.util.List; import java.util.Map; import org.jdbi.v3.core.Handle; import org.jdbi.v3.core.generic.GenericType; import org.jdbi.v3.sqlobject.SingleValue; import org.jdbi.v3.sqlobject.customizer.Bind; import org.jdbi.v3.sqlobject.customizer.BindMap; import org.jdbi.v3.sqlobject.statement.SqlQuery; import org.jdbi.v3.sqlobject.statement.SqlUpdate; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; public class TestHStore { private static final GenericType<Map<String, String>> STRING_MAP = new GenericType<Map<String, String>>() { }; @ClassRule public static PostgresDbRule postgresDbRule = new PostgresDbRule(); @Rule public ExpectedException expectedException = ExpectedException.none(); private Handle handle; private final Map<String, String> caps = ImmutableMap.of("yearly", "6000", "monthly", "1500", "daily", "100"); @BeforeClass public static void staticSetUp() { postgresDbRule.getSharedHandle().execute("create extension hstore"); } @Before public void setUp() throws Exception { handle = postgresDbRule.getSharedHandle(); handle.useTransaction(h -> { h.execute("drop table if exists campaigns"); h.execute("create table campaigns(id int not null, caps hstore)"); h.execute("insert into campaigns(id, caps) values (1, 'yearly=>10000, monthly=>5000, daily=>200'::hstore)"); h.execute("insert into campaigns(id, caps) values (2, 'yearly=>1000, monthly=>200, daily=>20'::hstore)"); }); } @Test public void testReadsViaFluentAPI() { List<Map<String, String>> caps = handle.createQuery("select caps from campaigns order by id") .mapTo(STRING_MAP) .list(); assertThat(caps).isEqualTo(ImmutableList.of( ImmutableMap.of("yearly", "10000", "monthly", "5000", "daily", "200"), ImmutableMap.of("yearly", "1000", "monthly", "200", "daily", "20") )); } @Test public void testHandlesEmptyMap() { handle.execute("insert into campaigns(id, caps) values (?,?)", 4, ImmutableMap.of()); Map<String, String> newCaps = handle.createQuery("select caps from campaigns where id=?") .bind(0, 4) .mapTo(STRING_MAP) .findOnly(); assertThat(newCaps).isEmpty(); } @Test public void testHandlesNulls() { handle.execute("insert into campaigns(id, caps) values (?,?)", 4, null); Map<String, String> newCaps = handle.createQuery("select caps from campaigns where id=?") .bind(0, 4) .mapTo(STRING_MAP) .findOnly(); assertThat(newCaps).isNull(); } @Test public void testRaisesExceptionWhenReadsWithWrongType() { expectedException.expect(UnsupportedOperationException.class); expectedException.expectMessage("No mapper registered for type java.util.Map<java.lang.String, java.lang.Object>"); handle.createQuery("select caps from campaigns order by id") .mapTo(new GenericType<Map<String, Object>>() {}) .list(); } @Test public void testWritesViaFluentApi() { handle.execute("insert into campaigns(id, caps) values (?,?)", 3, caps); Map<String, String> newCaps = handle.createQuery("select caps from campaigns where id=?") .bind(0, 3) .mapTo(STRING_MAP) .findOnly(); assertThat(newCaps).isEqualTo(caps); } @Test public void testSqlObjectApi() { CampaignDao campaignDao = handle.attach(CampaignDao.class); campaignDao.insertCampaign(3, caps); assertThat(campaignDao.getCampaignsCaps(3)).isEqualTo(caps); } @Test public void testWritesWithBindMap() { CampaignDao campaignDao = handle.attach(CampaignDao.class); campaignDao.insertCampaignFromMap(ImmutableMap.of("id", 3, "caps", caps)); assertThat(campaignDao.getCampaignsCaps(3)).isEqualTo(caps); } public interface CampaignDao { @SqlQuery("select caps from campaigns where id=:id") @SingleValue Map<String, String> getCampaignsCaps(@Bind("id") long campaignsId); @SqlUpdate("insert into campaigns(id, caps) values (:id, :caps)") void insertCampaign(@Bind("id") long campaignsId, Map<String, String> caps); @SqlUpdate("insert into campaigns(id, caps) values (:id, :caps)") int insertCampaignFromMap(@BindMap Map<String, Object> bindings); } }