diff --git a/pom.xml b/pom.xml
index ab04b06..7ba4cf9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -73,6 +73,7 @@
${java.version}
${java.version}
${project.build.sourceEncoding}
+ full
512M
@@ -172,7 +173,9 @@
每一个测试创建一个新进程,为每个测试创建新的JVM是单独测试的最彻底方式,但也是最慢的,不适合hudson上持续回归。 once:在一个进程中进行所有测试。once为默认设置,在Hudson上持续回归时建议使用默认设置。
always:在一个进程中并行的运行脚本,Junit4.7以上版本才可以使用,surefire的版本要在2.6以上提供这个功能,其中 threadCount:执行时,指定可分配的线程数量。只和参数parallel配合使用有效。默认:5。 -->
once
- ${argLine} -Xmx1024m -Dfile.encoding=UTF-8
+
+ ${argLine} -Xmx1024m -Dfile.encoding=UTF-8 -Dje.freeDisk=0
${basedir}/target/test-classes
diff --git a/src/main/java/com/sleepycat/berkeley/spring/boot/BerkeleyAutoConfiguration.java b/src/main/java/com/sleepycat/berkeley/spring/boot/BerkeleyAutoConfiguration.java
index cef54cf..ac6563c 100644
--- a/src/main/java/com/sleepycat/berkeley/spring/boot/BerkeleyAutoConfiguration.java
+++ b/src/main/java/com/sleepycat/berkeley/spring/boot/BerkeleyAutoConfiguration.java
@@ -96,6 +96,7 @@ public Database catalogDatabase(Environment myDbEnvironment){
System.out.println(catalogDatabase.getDatabaseName());
+ this.catalogDatabase = catalogDatabase;
return catalogDatabase;
}
@@ -126,6 +127,7 @@ public Database berkeleyDatabase(Environment myDbEnvironment){
System.out.println(myDatabase.getDatabaseName());
+ this.myDatabase = myDatabase;
return myDatabase;
}
diff --git a/src/main/java/com/sleepycat/berkeley/spring/boot/BerkeleyTemplate.java b/src/main/java/com/sleepycat/berkeley/spring/boot/BerkeleyTemplate.java
index a85b252..e8b804d 100644
--- a/src/main/java/com/sleepycat/berkeley/spring/boot/BerkeleyTemplate.java
+++ b/src/main/java/com/sleepycat/berkeley/spring/boot/BerkeleyTemplate.java
@@ -161,10 +161,12 @@ public void otherMethod(){
List list = myDbEnvironment.getDatabaseNames();//取得当前环境下数据库名称列表
System.out.println(list);
- env.renameDatabase(null, databaseName, "newName");//给数据库改名
- env.removeDatabase(null, databaseName);//删除当前环境数据库
-
- long deleteNum = env.truncateDatabase(null, databaseName, true);//清空数据库中所有记录,并返回数量
+ // JE cannot truncate a database while its handle is open. Keep the
+ // template usable by reopening the same database after truncation.
+ com.sleepycat.je.DatabaseConfig config = myDatabase.getConfig();
+ myDatabase.close();
+ long deleteNum = env.truncateDatabase(null, databaseName, true);
+ myDatabase = env.openDatabase(null, databaseName, config);
System.out.println(deleteNum);
diff --git a/src/main/java/com/sleepycat/berkeley/spring/boot/Cursor.java b/src/main/java/com/sleepycat/berkeley/spring/boot/Cursor.java
index 0055fd5..15898ca 100644
--- a/src/main/java/com/sleepycat/berkeley/spring/boot/Cursor.java
+++ b/src/main/java/com/sleepycat/berkeley/spring/boot/Cursor.java
@@ -52,7 +52,8 @@ public void getAllByCursor() throws UnsupportedEncodingException{
}
//向前遍历
- while(myCursor.getPrev(databaseKey, databaseValue, LockMode.DEFAULT) == OperationStatus.SUCCESS){
+ myCursor.getFirst(databaseKey, databaseValue, LockMode.DEFAULT);
+ while(myCursor.getNext(databaseKey, databaseValue, LockMode.DEFAULT) == OperationStatus.SUCCESS){
String theKey = new String(databaseKey.getData(), "UTF-8");
String theData = new String(databaseValue.getData(), "UTF-8");
System.out.println("Key: " + theKey + "Data: " + theData);
@@ -92,7 +93,7 @@ public void searchMultipleByCursor(String key) throws UnsupportedEncodingExcepti
DatabaseEntry databaseValue = new DatabaseEntry();
OperationStatus res = myCursor.getSearchKey(databaseKey, databaseValue, LockMode.DEFAULT);
- if(myCursor.count() > 1){
+ if(res == OperationStatus.SUCCESS){
while(res == OperationStatus.SUCCESS){
String foundKey = new String(databaseKey.getData(), "utf8");
String foundValue = new String(databaseValue.getData(), "utf8");
@@ -157,6 +158,7 @@ public void closeDatabase(){
public static void main(String[] args) throws UnsupportedEncodingException{
Cursor cursor = new Cursor();
+ if (args.length > 0) cursor.envDir = args[0];
cursor.configEnvironment();
cursor.createDatabase();
cursor.addDataByCursor("a", "www.baidu.com");
@@ -167,4 +169,4 @@ public static void main(String[] args) throws UnsupportedEncodingException{
cursor.closeDatabase();
}
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/sleepycat/berkeley/spring/boot/BerkeleyConfigurationTest.java b/src/test/java/com/sleepycat/berkeley/spring/boot/BerkeleyConfigurationTest.java
new file mode 100644
index 0000000..095637c
--- /dev/null
+++ b/src/test/java/com/sleepycat/berkeley/spring/boot/BerkeleyConfigurationTest.java
@@ -0,0 +1,46 @@
+package com.sleepycat.berkeley.spring.boot;
+
+import com.sleepycat.berkeley.spring.boot.hooks.BerkeleyShutdownHook;
+import com.sleepycat.bind.serial.StoredClassCatalog;
+import com.sleepycat.je.Database;
+import com.sleepycat.je.Environment;
+import com.sleepycat.je.EnvironmentConfig;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.springframework.test.util.ReflectionTestUtils;
+import org.springframework.core.io.DefaultResourceLoader;
+
+import java.nio.file.Path;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class BerkeleyConfigurationTest {
+ @TempDir Path home;
+
+ @Test
+ void configuresEnvironmentAndOpensCatalogAndDatabase() {
+ BerkeleyProperties properties = new BerkeleyProperties();
+ properties.setAllowCreate(true);
+ properties.setTransactional(true);
+ properties.setCatalogDatabaseName("catalog");
+ properties.setDatabaseName("items");
+ BerkeleyAutoConfiguration configuration = new BerkeleyAutoConfiguration();
+ ReflectionTestUtils.setField(configuration, "properties", properties);
+ DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
+ configuration.setResourceLoader(resourceLoader);
+ assertSame(resourceLoader, ReflectionTestUtils.getField(configuration, "resourceLoader"));
+ EnvironmentConfig settings = configuration.configEnvironment();
+ assertTrue(settings.getAllowCreate());
+ assertTrue(settings.getTransactional());
+ assertFalse(settings.getReadOnly());
+ assertNotNull(configuration.repConfigProxy());
+
+ Environment environment = new Environment(home.toFile(), settings);
+ Database catalogDatabase = configuration.catalogDatabase(environment);
+ StoredClassCatalog catalog = configuration.catalog();
+ Database database = configuration.berkeleyDatabase(environment);
+ assertEquals("catalog", catalogDatabase.getDatabaseName());
+ assertEquals("items", database.getDatabaseName());
+ new BerkeleyShutdownHook(database, catalog, environment).run();
+ }
+}
diff --git a/src/test/java/com/sleepycat/berkeley/spring/boot/BerkeleyTest.java b/src/test/java/com/sleepycat/berkeley/spring/boot/BerkeleyTest.java
index 98639b8..b23ea45 100644
--- a/src/test/java/com/sleepycat/berkeley/spring/boot/BerkeleyTest.java
+++ b/src/test/java/com/sleepycat/berkeley/spring/boot/BerkeleyTest.java
@@ -1,355 +1,75 @@
-/*
- * Copyright (c) 2018, hiwepy (https://github.com/hiwepy).
- *
- * 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 com.sleepycat.berkeley.spring.boot;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-import org.apache.commons.io.Charsets;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.sleepycat.je.CursorConfig;
-import com.sleepycat.je.DatabaseException;
-import com.sleepycat.je.Environment;
-import com.sleepycat.je.EnvironmentConfig;
-import com.sleepycat.persist.EntityCursor;
-import com.sleepycat.persist.EntityIndex;
-import com.sleepycat.persist.EntityStore;
-import com.sleepycat.persist.PrimaryIndex;
-import com.sleepycat.persist.SecondaryIndex;
-import com.sleepycat.persist.StoreConfig;
-
-public class BerkeleyTest {
-
- private Environment myEnv;
- private EntityStore store;
- private PrimaryIndex inventoryBySku;
- private PrimaryIndex vendorByName;
- private SecondaryIndex inventoryByName;
-
- /* Employer accessors */
- PrimaryIndex employerById;
- SecondaryIndex employerByName;
-
- /* Person accessors */
- PrimaryIndex personBySsn;
- SecondaryIndex personByParentSsn;
- SecondaryIndex personByEmailAddresses;
- SecondaryIndex personByEmployerIds;
-
-
- private File envHome = new File(System.getProperty("user.dir") + File.separator + "bdb");
- private boolean readOnly = false;
-
- @Before
- public void prepare() {
- EnvironmentConfig myEnvConfig = new EnvironmentConfig();
- StoreConfig storeConfig = new StoreConfig();
-
- myEnvConfig.setReadOnly(readOnly);
- storeConfig.setReadOnly(readOnly);
-
- // If the environment is opened for write, then we want to be
- // able to create the environment and entity store if
- // they do not exist.
- myEnvConfig.setAllowCreate(!readOnly);
- storeConfig.setAllowCreate(!readOnly);
-
- // Open the environment and entity store
- System.out.println(envHome.getAbsolutePath());
- if (!envHome.exists()) {
- envHome.mkdir();
- }
- myEnv = new Environment(envHome, myEnvConfig);
- store = new EntityStore(myEnv, "EntityStore", storeConfig);
-
- // Primary key for Inventory classes
- inventoryBySku = store.getPrimaryIndex(String.class, Inventory.class);
- // Secondary key for Inventory classes
- // Last field in the getSecondaryIndex() method must be
- // the name of a class member; in this case, an Inventory.class
- // data member.
- inventoryByName = store.getSecondaryIndex(inventoryBySku, String.class, "itemName");
- // Primary key for Vendor class
- vendorByName = store.getPrimaryIndex(String.class, Vendor.class);
-
- employerById = store.getPrimaryIndex(Long.class, Employer.class);
- employerByName = store.getSecondaryIndex(employerById, String.class, "name");
-
- personBySsn = store.getPrimaryIndex(String.class, Person.class);
- personByParentSsn = store.getSecondaryIndex(personBySsn, String.class, "parentSsn");
- personByEmailAddresses = store.getSecondaryIndex(personBySsn, String.class, "emailAddresses");
- personByEmployerIds = store.getSecondaryIndex(personBySsn, Long.class, "employerIds");
-
- }
-
- //添加数据
- @Test
- public void putData() throws IOException {
-
- List readLines = IOUtils.readLines(this.getClass().getClassLoader().getResourceAsStream("vendors.txt"), Charsets.UTF_8);
- for (String data : readLines) {
- String[] sArray = data.split("#");
- Vendor theVendor = new Vendor();
- theVendor.setVendorName(sArray[0]);
- theVendor.setAddress(sArray[1]);
- theVendor.setCity(sArray[2]);
- theVendor.setState(sArray[3]);
- theVendor.setZipcode(sArray[4]);
- theVendor.setBusinessPhoneNumber(sArray[5]);
- theVendor.setRepName(sArray[6]);
- theVendor.setRepPhoneNumber(sArray[7]);
- // Put it in the store. Because we do not explicitly set
- // a transaction here, and because the store was opened
- // with transactional support, auto commit is used for each
- // write to the store.
- vendorByName.put(theVendor);
- }
-
- // Primary key for Inventory classes
- PrimaryIndex inventoryBySku = store.getPrimaryIndex(String.class, Inventory.class);
- List data = IOUtils.readLines(this.getClass().getClassLoader().getResourceAsStream("inventory.txt"), Charsets.UTF_8);
- for (String row : data) {
- String[] sArray = row.split("#");
- Inventory theInventory = new Inventory();
- theInventory.setItemName(sArray[0]);
- theInventory.setSku(sArray[1]);
- theInventory.setVendorPrice((new Float(sArray[2])).floatValue());
- theInventory.setVendorInventory((new Integer(sArray[3])).intValue());
- theInventory.setCategory(sArray[4]);
- theInventory.setVendor(sArray[5]);
- // Put it in the store. Note that this causes our secondary key
- // to be automatically updated for us.
- inventoryBySku.put(theInventory);
- }
- }
-
- //查询数据
- @Test
- public void getInventoryData() {
- // Use the inventory name secondary key to retrieve
- // these objects.
- EntityCursor items =
- inventoryByName.subIndex("Oranges").entities();
- try {
- for (Inventory item : items) {
- System.out.println(ToStringBuilder.reflectionToString(item));
- }
- } finally {
- items.close();
- }
- }
-
- @Test
- public void getAllInventory() {
- // Get a cursor that will walk every
- // inventory object in the store.
- EntityCursor items = inventoryBySku.entities();
-
- try {
- for (Inventory item : items) {
- System.out.println(ToStringBuilder.reflectionToString(item));
- }
- } finally {
- items.close();
- }
- }
-
- //更新:如果不开启允许重复记录的话,put就是更新
- @Test
- public void update() {
- String pk = "apple-for-update";
- Inventory theInventory = new Inventory();
- theInventory.setItemName("Apples");
- theInventory.setSku(pk);
- theInventory.setVendorPrice(1.20f);
- theInventory.setVendorInventory(728);
- theInventory.setCategory("fruits");
- theInventory.setVendor("Off the Vine");
-
- inventoryBySku.put(theInventory);
-
- Inventory inventory = inventoryBySku.get(pk);
- System.out.println(ToStringBuilder.reflectionToString(inventory));
-
- inventory.setVendor("vendor update");
- inventoryBySku.put(inventory);
-
- System.out.println(ToStringBuilder.reflectionToString(inventoryBySku.get(pk)));
- }
-
- //删除
- @Test
- public void delete() {
-
- String pk = "apple-for-update";
- Inventory theInventory = new Inventory();
- theInventory.setItemName("Apples");
- theInventory.setSku(pk);
- theInventory.setVendorPrice(1.20f);
- theInventory.setVendorInventory(728);
- theInventory.setCategory("fruits");
- theInventory.setVendor("Off the Vine");
-
- inventoryBySku.put(theInventory);
-
- Inventory inventory = inventoryBySku.get(pk);
- System.out.println(ToStringBuilder.reflectionToString(inventory));
-
- boolean rs = inventoryBySku.delete(pk);
- Assert.assertTrue(rs);
-
- Assert.assertNull(inventoryBySku.get(pk));
-
- }
-
- //统计
- @Test
- public void count(){
- EntityCursor cursor = null;
- try{
- cursor = employerById.entities();
- int count = -1;
- if(cursor.next() != null){
- count = cursor.count();
- }
- System.out.println("employee count:" + count);
- }finally {
- if(cursor != null){
- cursor.close();
- }
- }
- }
-
- //级联及主键自增情况
- @Test
- public void sequencePk() {
-
- /*
- * Add a parent and two children using the Person primary index.
- * Specifying a non-null parentSsn adds the child Person to the
- * sub-index of children for that parent key.
- */
- personBySsn.put(new Person("Bob Smith", "111-11-1111", null));
- personBySsn.put(new Person("Mary Smith", "333-33-3333", "111-11-1111"));
- personBySsn.put(new Person("Jack Smith", "222-22-2222", "111-11-1111"));
-
- /* Print the children of a parent using a sub-index and a cursor. */
- EntityCursor children = personByParentSsn.subIndex("111-11-1111").entities();
- try {
- for (Person child : children) {
- System.out.println(child.getSsn() + ' ' + child.getName());
- }
- } finally {
- children.close();
- }
-
- /* Get Bob by primary key using the primary index. */
- Person bob = personBySsn.get("111-11-1111");
- Assert.assertNotNull(bob);
-
- /*
- * Create two employers if they do not already exist. Their primary
- * keys are assigned from a sequence.
- */
- Employer gizmoInc = employerByName.get("Gizmo Inc");
- if (gizmoInc == null) {
- gizmoInc = new Employer("Gizmo Inc");
- employerById.put(gizmoInc);
- }
- Employer gadgetInc = employerByName.get("Gadget Inc");
- if (gadgetInc == null) {
- gadgetInc = new Employer("Gadget Inc");
- employerById.put(gadgetInc);
- }
-
- /* Bob has two jobs and two email addresses. */
- bob.getEmployerIds().add(gizmoInc.getId());
- bob.getEmployerIds().add(gadgetInc.getId());
-
- bob.getEmailAddresses().add("bob@bob.com");
- bob.getEmailAddresses().add("bob@gmail.com");
-
- /* Update Bob's record. */
- personBySsn.put(bob);
-
- /* Bob can now be found by both email addresses. */
- bob = personByEmailAddresses.get("bob@bob.com");
- Assert.assertNotNull(bob);
- bob = personByEmailAddresses.get("bob@gmail.com");
- Assert.assertNotNull(bob);
-
- /* Bob can also be found as an employee of both employers. */
- EntityIndex employees;
- employees = personByEmployerIds.subIndex(gizmoInc.getId());
- Assert.assertTrue( employees.contains("111-11-1111"));
- employees = personByEmployerIds.subIndex(gadgetInc.getId());
- Assert.assertTrue(employees.contains("111-11-1111"));
-
- /*
- * When an employer is deleted, the onRelatedEntityDelete=NULLIFY for
- * the employerIds key causes the deleted ID to be removed from Bob's
- * employerIds.
- */
- employerById.delete(gizmoInc.getId());
- bob = personBySsn.get("111-11-1111");
- Assert.assertNotNull(bob);
- Assert.assertFalse(bob.getEmployerIds().contains(gizmoInc.getId()));
- }
-
- @Test
- public void cursor() {
- CursorConfig cc = new CursorConfig();
- // This is ignored if the store is not opened with uncommitted read
- // support.
- cc.setReadUncommitted(true);
-
- EntityCursor employers = employerById.entities(null, cc);
- try{
- for(Employer employer : employers){
- System.out.println(ToStringBuilder.reflectionToString(employer));
- }
- }finally{
- employers.close();
- }
- }
-
- @After
- public void close() {
- if (store != null) {
- try {
- store.close();
- } catch (DatabaseException dbe) {
- dbe.printStackTrace();
- }
- }
-
- if (myEnv != null) {
- try {
- // Finally, close the store and environment.
- myEnv.close();
- } catch (DatabaseException dbe) {
- dbe.printStackTrace();
- }
- }
- }
-}
+package com.sleepycat.berkeley.spring.boot;
+
+import com.sleepycat.je.Database;
+import com.sleepycat.je.DatabaseConfig;
+import com.sleepycat.je.Environment;
+import com.sleepycat.je.EnvironmentConfig;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.nio.file.Path;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class BerkeleyTest {
+ @TempDir Path home;
+ private Environment environment;
+ private Database database;
+ private BerkeleyTemplate template;
+
+ @BeforeEach
+ void openDatabase() {
+ EnvironmentConfig envConfig = new EnvironmentConfig();
+ envConfig.setAllowCreate(true);
+ envConfig.setTransactional(true);
+ environment = new Environment(home.toFile(), envConfig);
+ DatabaseConfig dbConfig = new DatabaseConfig();
+ dbConfig.setAllowCreate(true);
+ dbConfig.setTransactional(true);
+ database = environment.openDatabase(null, "items", dbConfig);
+ template = new BerkeleyTemplate();
+ template.setDatabase(database);
+ ReflectionTestUtils.setField(template, "myDbEnvironment", environment);
+ }
+
+ @AfterEach
+ void closeDatabase() {
+ if (database != null) database.close();
+ if (environment != null) environment.close();
+ }
+
+ @Test
+ void writesReadsListsAndDeletesTransactionalRecords() throws Exception {
+ assertSame(database, template.getDatabase());
+ template.writeToDatabase(" key ", " first ", false);
+ template.writeToDatabase("key", "ignored", false);
+ assertEquals("first", template.readFromDatabase("key"));
+ template.writeToDatabase("key", "second", true);
+ assertEquals("second", template.readFromDatabase("key"));
+ template.writeToDatabase("other", "value", false);
+ assertEquals(List.of("key", "other"), template.getAllFromDatabase());
+ template.deleteFromDatabase("other");
+ assertEquals("", template.readFromDatabase("other"));
+ }
+
+ @Test
+ void storesPrimitiveValues() {
+ template.writePrimitiveDatabase("primitive", "stored");
+ template.readPrimitiveDatabase("primitive");
+ assertNotEquals("", template.readFromDatabase("primitive"));
+ }
+
+ @Test
+ void truncatesAndReopensTheDatabase() {
+ template.writeToDatabase("keep", "before", true);
+ template.otherMethod();
+ database = template.getDatabase();
+ assertEquals("", template.readFromDatabase("keep"));
+ template.writeToDatabase("after", "value", true);
+ assertEquals("value", template.readFromDatabase("after"));
+ }
+}
diff --git a/src/test/java/com/sleepycat/berkeley/spring/boot/CursorTest.java b/src/test/java/com/sleepycat/berkeley/spring/boot/CursorTest.java
new file mode 100644
index 0000000..47c9e7b
--- /dev/null
+++ b/src/test/java/com/sleepycat/berkeley/spring/boot/CursorTest.java
@@ -0,0 +1,40 @@
+package com.sleepycat.berkeley.spring.boot;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.nio.file.Path;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+class CursorTest {
+ @TempDir Path home;
+
+ @Test
+ void demoRunsAgainstAnIsolatedDatabase() throws Exception {
+ Cursor.main(new String[] { home.toString() });
+ }
+
+ @Test
+ void writesSearchesUpdatesAndDeletesThroughCursor() throws Exception {
+ Cursor cursor = new Cursor();
+ ReflectionTestUtils.setField(cursor, "envDir", home.toString());
+ cursor.configEnvironment();
+ cursor.createDatabase();
+ try {
+ cursor.addDataByCursor("a", "first");
+ cursor.addDataByCursor("b", "second");
+ cursor.getAllByCursor();
+ cursor.searchByCursor("a", "first");
+ cursor.searchByCursor("missing", "missing");
+ cursor.searchMultipleByCursor("a");
+ cursor.changeCursor("a");
+ cursor.searchByCursor("a", "www.baike.com");
+ cursor.deleteDataByCursor("a");
+ assertDoesNotThrow(() -> cursor.searchByCursor("a", "www.baike.com"));
+ } finally {
+ cursor.closeDatabase();
+ }
+ }
+}