Skip to content

Commit

Permalink
Added support for custom database paths on simulator and android.
Browse files Browse the repository at this point in the history
Added method Database.isCustomPathSupported() which returns true on platforms that support custom database paths.  On these platforms (currently only simulator and android), you can pass a file path to the methods Database.openOrCreate(String), Database.exists(String), Database.delete(String), and Database.getDatabasePath(String).  Other platforms will throw an IllegalArgumentException if you provide a file path - or any string containing file separators.
Added unit tests for database functionality, including custom paths.
These changes are fully supported by the CN1Spatialite cn1lib without needing to update that library.
  • Loading branch information
shannah committed Jun 20, 2018
1 parent 5d1824d commit d72917e
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 12 deletions.
35 changes: 31 additions & 4 deletions CodenameOne/src/com/codename1/db/Database.java
Expand Up @@ -48,14 +48,34 @@
public abstract class Database {

/**
* Opens a database or create one if not exists
* Checks if this platform supports custom database paths. On platforms that
* support this, you can pass a file path to {@link #openOrCreate(java.lang.String) }, {@link #exists(java.lang.String) },
* {@link #delete(java.lang.String) }, and {@link #getDatabasePath(java.lang.String) }.
* @return True on platorms that support custom database paths.
*/
public static boolean isCustomPathSupported() {
return Display.getInstance().isDatabaseCustomPathSupported();
}

private static void validateDatabaseNameArgument(String databaseName) {
if (!isCustomPathSupported()) {
if (databaseName.indexOf("/") != -1 || databaseName.indexOf("\\") != -1) {
throw new IllegalArgumentException("This platform does not support custom database paths. The database name cannot contain file separators.");
}
}
}

/**
* Opens a database or create one if not exists.
*
* @param databaseName the name of the database
* @param databaseName the name of the database. Platforms that support custom database
* paths (i.e. {@link #isCustomPathSupported() } return {@literal true}), will also accept a file path here.
* @return Database Object or null if not supported on the platform
*
* @throws IOException if database cannot be created
*/
public static Database openOrCreate(String databaseName) throws IOException{
validateDatabaseNameArgument(databaseName);
return Display.getInstance().openOrCreate(databaseName);
}

Expand All @@ -64,10 +84,12 @@ public static Database openOrCreate(String databaseName) throws IOException{
*
* <p><strong>NOTE:</strong> Not supported in the Javascript port. Will always return false.</p>
*
* @param databaseName the name of the database
* @param databaseName the name of the database. Platforms that support custom database
* paths (i.e. {@link #isCustomPathSupported() } return {@literal true}), will also accept a file path here.
* @return true if database exists
*/
public static boolean exists(String databaseName){
validateDatabaseNameArgument(databaseName);
return Display.getInstance().exists(databaseName);
}

Expand All @@ -76,21 +98,26 @@ public static boolean exists(String databaseName){
*
* <p><strong>NOTE:</strong> This method is not supported in the Javascript port. Will silently fail.</p>
*
* @param databaseName the name of the database
* @param databaseName the name of the database. Platforms that support custom database
* paths (i.e. {@link #isCustomPathSupported() } return {@literal true}), will also accept a file path here.
* @throws IOException if database cannot be deleted
*/
public static void delete(String databaseName) throws IOException{
validateDatabaseNameArgument(databaseName);
Display.getInstance().delete(databaseName);
}

/**
* Returns the file path of the Database if exists and if supported on
* the platform.
*
* @param databaseName The name of the database. Platforms that support custom database
* paths (i.e. {@link #isCustomPathSupported() } return {@literal true}), will also accept a file path here.
* <p><strong>NOTE:</strong> This method will return null in the Javascript port.</p>
* @return the file path of the database
*/
public static String getDatabasePath(String databaseName){
validateDatabaseNameArgument(databaseName);
return Display.getInstance().getDatabasePath(databaseName);
}

Expand Down
10 changes: 10 additions & 0 deletions CodenameOne/src/com/codename1/impl/CodenameOneImplementation.java
Expand Up @@ -6012,6 +6012,16 @@ public void blockCopyPaste(boolean blockCopyPaste) {

}

/**
* Checks if this platform supports custom database paths. On platforms
* where this returns {@literal true}, {@link #openOrCreateDB(java.lang.String) }
* will accept a file path (starting with "file://"
* @return True if platform supports custom paths.
*/
public boolean isDatabaseCustomPathSupported() {
return false;
}

// END TRANSFORMATION METHODS--------------------------------------------------------------------

class RPush implements Runnable {
Expand Down
7 changes: 6 additions & 1 deletion CodenameOne/src/com/codename1/ui/Display.java
Expand Up @@ -3774,7 +3774,8 @@ public String getMediaRecorderingMimeType() {
}

/**
* Opens a database or create one if not exists
* Opens a database or create one if not exists. On platforms where {@link #isDatabaseCustomPathSupported() }
* this method can optionally accept a file path.
*
* @param databaseName the name of the database
* @return Database Object or null if not supported on the platform
Expand All @@ -3785,6 +3786,10 @@ public Database openOrCreate(String databaseName) throws IOException{
return impl.openOrCreateDB(databaseName);
}

public boolean isDatabaseCustomPathSupported() {
return impl.isDatabaseCustomPathSupported();
}

/**
* Deletes database
*
Expand Down
Expand Up @@ -6810,22 +6810,44 @@ public boolean isFormatSupported(String format) {

@Override
public Database openOrCreateDB(String databaseName) throws IOException {
SQLiteDatabase db = getContext().openOrCreateDatabase(databaseName, getContext().MODE_PRIVATE, null);
SQLiteDatabase db;
if (databaseName.startsWith("file://")) {
db = SQLiteDatabase.openOrCreateDatabase(FileSystemStorage.getInstance().toNativePath(databaseName), null);
} else {
db = getContext().openOrCreateDatabase(databaseName, getContext().MODE_PRIVATE, null);
}
return new AndroidDB(db);
}

@Override
public boolean isDatabaseCustomPathSupported() {
return true;
}



@Override
public void deleteDB(String databaseName) throws IOException {
if (databaseName.startsWith("file://")) {
deleteFile(databaseName);
return;
}
getContext().deleteDatabase(databaseName);
}

@Override
public boolean existsDB(String databaseName) {
if (databaseName.startsWith("file://")) {
return exists(databaseName);
}
File db = new File(getContext().getApplicationInfo().dataDir + "/databases/" + databaseName);
return db.exists();
}

public String getDatabasePath(String databaseName) {
if (databaseName.startsWith("file://")) {
return databaseName;
}
File db = new File(getContext().getApplicationInfo().dataDir + "/databases/" + databaseName);
return db.getAbsolutePath();
}
Expand Down
44 changes: 38 additions & 6 deletions Ports/JavaSE/src/com/codename1/impl/javase/JavaSEPort.java
Expand Up @@ -89,6 +89,7 @@
import javax.imageio.stream.MemoryCacheImageInputStream;
import com.codename1.io.BufferedInputStream;
import com.codename1.io.BufferedOutputStream;
import com.codename1.io.FileSystemStorage;
import com.codename1.io.Log;
import com.codename1.io.NetworkManager;
import com.codename1.io.Storage;
Expand Down Expand Up @@ -9189,8 +9190,13 @@ public void run() {
@Override
public String getDatabasePath(String databaseName) {
if(exposeFilesystem){
return getStorageDir() + "/database/" + databaseName;
File f = getDatabaseFile(databaseName);

return f.getAbsolutePath();
}else{
if (databaseName.startsWith("file://")) {
return databaseName;
}
return getAppHomePath() + "database/" + databaseName;
}
}
Expand All @@ -9211,12 +9217,15 @@ public Database openOrCreateDB(String databaseName) throws IOException {
// current working directory
SQLiteConfig config = new SQLiteConfig();
config.enableLoadExtension(true);
File dir = new File(getStorageDir() + "/database");
File file = getDatabaseFile(databaseName);


File dir = file.getParentFile();
if (!dir.exists()) {
dir.mkdir();
}
java.sql.Connection conn = DriverManager.getConnection("jdbc:sqlite:"
+ getStorageDir() + "/database/" + databaseName,
java.sql.Connection conn = DriverManager.getConnection("jdbc:sqlite:" +
file.getAbsolutePath(),
config.toProperties()
);

Expand All @@ -9227,19 +9236,42 @@ public Database openOrCreateDB(String databaseName) throws IOException {
}
}


private File getDatabaseFile(String databaseName) {
File f = new File(getStorageDir() + "/database/" + databaseName);
if (exposeFilesystem) {
if (databaseName.contains("/") || databaseName.contains("\\")) {
f = new File(databaseName);
}
} else {
if (databaseName.startsWith("file://")) {
f = new File(FileSystemStorage.getInstance().toNativePath(databaseName));
}

}
return f;
}

@Override
public boolean isDatabaseCustomPathSupported() {
return true;
}

@Override
public void deleteDB(String databaseName) throws IOException {
System.out.println("**** Database.delete() is not supported in the Javascript port. If you plan to deploy to Javascript, you should avoid this method. *****");
File f = new File(getStorageDir() + "/database/" + databaseName);
File f = getDatabaseFile(databaseName);
if (f.exists()) {
f.delete();
}
}



@Override
public boolean existsDB(String databaseName) {
System.out.println("**** Database.exists() is not supported in the Javascript port. If you plan to deploy to Javascript, you should avoid this method. *****");
File f = new File(getStorageDir() + "/database/" + databaseName);
File f = getDatabaseFile(databaseName);
return f.exists();
}

Expand Down

0 comments on commit d72917e

Please sign in to comment.