1e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/*
2e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Copyright (C) 2011 The Android Open Source Project
3e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown *
4e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * you may not use this file except in compliance with the License.
6e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * You may obtain a copy of the License at
7e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown *
8e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown *
10e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Unless required by applicable law or agreed to in writing, software
11e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * See the License for the specific language governing permissions and
14e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * limitations under the License.
15e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown */
16e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
17e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownpackage android.database.sqlite;
18e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
19e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownimport java.util.ArrayList;
20e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownimport java.util.Locale;
21e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownimport java.util.regex.Pattern;
22e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
23e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/**
24e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Describes how to configure a database.
25e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * <p>
26e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * The purpose of this object is to keep track of all of the little
27e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * configuration settings that are applied to a database after it
28e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * is opened so that they can be applied to all connections in the
29e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * connection pool uniformly.
30e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * </p><p>
31e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Each connection maintains its own copy of this object so it can
32e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * keep track of which settings have already been applied.
33e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * </p>
34e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown *
35e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @hide
36e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown */
37e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownpublic final class SQLiteDatabaseConfiguration {
38e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    // The pattern we use to strip email addresses from database paths
39e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    // when constructing a label to use in log messages.
40e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    private static final Pattern EMAIL_IN_DB_PATTERN =
41e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            Pattern.compile("[\\w\\.\\-]+@[\\w\\.\\-]+");
42e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
43e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    /**
44e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * Special path used by in-memory databases.
45e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     */
46e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    public static final String MEMORY_DB_PATH = ":memory:";
47e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
48e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    /**
49e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * The database path.
50e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     */
51e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    public final String path;
52e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
53e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    /**
54e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * The label to use to describe the database when it appears in logs.
55e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * This is derived from the path but is stripped to remove PII.
56e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     */
57e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    public final String label;
58e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
59e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    /**
60559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown     * The flags used to open the database.
61559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown     */
62559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown    public int openFlags;
63559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown
64559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown    /**
65e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * The maximum size of the prepared statement cache for each database connection.
66e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * Must be non-negative.
67e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     *
68e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * Default is 25.
69e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     */
70e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    public int maxSqlCacheSize;
71e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
72e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    /**
73e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * The database locale.
74e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     *
75e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * Default is the value returned by {@link Locale#getDefault()}.
76e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     */
77e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    public Locale locale;
78e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
79e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    /**
8096496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown     * True if foreign key constraints are enabled.
8196496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown     *
8296496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown     * Default is false.
8396496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown     */
8496496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown    public boolean foreignKeyConstraintsEnabled;
8596496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown
8696496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown    /**
87e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * The custom functions to register.
88e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     */
89e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    public final ArrayList<SQLiteCustomFunction> customFunctions =
90e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            new ArrayList<SQLiteCustomFunction>();
91e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
92e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    /**
93e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * Creates a database configuration with the required parameters for opening a
94e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * database and default values for all other parameters.
95e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     *
96e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * @param path The database path.
97e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * @param openFlags Open flags for the database, such as {@link SQLiteDatabase#OPEN_READWRITE}.
98e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     */
99e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    public SQLiteDatabaseConfiguration(String path, int openFlags) {
100e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        if (path == null) {
101e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            throw new IllegalArgumentException("path must not be null.");
102e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        }
103e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
104e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        this.path = path;
105e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        label = stripPathForLogs(path);
106559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown        this.openFlags = openFlags;
107e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
108e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        // Set default values for optional parameters.
109e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        maxSqlCacheSize = 25;
110e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        locale = Locale.getDefault();
111e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    }
112e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
113e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    /**
114e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * Creates a database configuration as a copy of another configuration.
115e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     *
116e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * @param other The other configuration.
117e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     */
118e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    public SQLiteDatabaseConfiguration(SQLiteDatabaseConfiguration other) {
119e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        if (other == null) {
120e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            throw new IllegalArgumentException("other must not be null.");
121e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        }
122e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
123e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        this.path = other.path;
124e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        this.label = other.label;
125e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        updateParametersFrom(other);
126e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    }
127e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
128e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    /**
129e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * Updates the non-immutable parameters of this configuration object
130e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * from the other configuration object.
131e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     *
132e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * @param other The object from which to copy the parameters.
133e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     */
134e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    public void updateParametersFrom(SQLiteDatabaseConfiguration other) {
135e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        if (other == null) {
136e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            throw new IllegalArgumentException("other must not be null.");
137e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        }
138559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown        if (!path.equals(other.path)) {
139e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            throw new IllegalArgumentException("other configuration must refer to "
140e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown                    + "the same database.");
141e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        }
142e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
143559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown        openFlags = other.openFlags;
144e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        maxSqlCacheSize = other.maxSqlCacheSize;
145e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        locale = other.locale;
14696496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown        foreignKeyConstraintsEnabled = other.foreignKeyConstraintsEnabled;
147e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        customFunctions.clear();
148e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        customFunctions.addAll(other.customFunctions);
149e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    }
150e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
151e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    /**
152e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * Returns true if the database is in-memory.
153e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * @return True if the database is in-memory.
154e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     */
155e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    public boolean isInMemoryDb() {
156e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        return path.equalsIgnoreCase(MEMORY_DB_PATH);
157e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    }
158e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
159e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    private static String stripPathForLogs(String path) {
160e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        if (path.indexOf('@') == -1) {
161e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            return path;
162e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        }
163e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        return EMAIL_IN_DB_PATTERN.matcher(path).replaceAll("XX@YY");
164e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    }
165e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown}
166