├── .gitignore
├── .idea
├── .name
├── breeze-db.iml
├── copyright
│ ├── Digital_Strawberry_LLC_MIT.xml
│ └── profiles_settings.xml
├── modules.xml
└── vcs.xml
├── .travis.yml
├── BreezeDb.iml
├── LICENSE.md
├── README.md
├── build
├── build.properties
└── build.xml
├── src
├── breezedb
│ ├── BreezeDb.as
│ ├── BreezeDbInstance.as
│ ├── DB.as
│ ├── IBreezeDatabase.as
│ ├── breezedb_internal.as
│ ├── collections
│ │ └── Collection.as
│ ├── events
│ │ ├── BreezeDatabaseEvent.as
│ │ ├── BreezeMigrationEvent.as
│ │ ├── BreezeQueryEvent.as
│ │ └── BreezeSQLStatementEvent.as
│ ├── migrations
│ │ ├── BreezeMigration.as
│ │ ├── BreezeMigrationsRunner.as
│ │ └── breezedb_internal.as
│ ├── models
│ │ ├── BreezeModel.as
│ │ └── BreezeModelQueryBuilder.as
│ ├── queries
│ │ ├── BreezeInnerQueryBuilder.as
│ │ ├── BreezeJoinStatement.as
│ │ ├── BreezeQueryBuilder.as
│ │ ├── BreezeQueryReference.as
│ │ ├── BreezeQueryResult.as
│ │ ├── BreezeQueryRunner.as
│ │ ├── BreezeRawQuery.as
│ │ ├── BreezeSQLMultiStatement.as
│ │ ├── BreezeSQLResult.as
│ │ ├── BreezeSQLStatement.as
│ │ ├── BreezeUnionStatement.as
│ │ ├── IRawQuery.as
│ │ ├── ISQLStatement.as
│ │ ├── SQLStatementQueue.as
│ │ └── breezedb_internal.as
│ ├── schemas
│ │ ├── BreezeSchemaBuilder.as
│ │ ├── ColumnDataType.as
│ │ ├── IColumnConstraint.as
│ │ ├── TableBlueprint.as
│ │ ├── TableColumn.as
│ │ └── breezedb_internal.as
│ └── utils
│ │ ├── Callback.as
│ │ └── GarbagePrevention.as
└── org
│ └── kuwamoto
│ └── Inflect.as
└── test
├── application.xml
├── lib
└── breezetest.swc
├── src
├── Main.as
└── tests
│ ├── TestDatabase.as
│ ├── TestQueryBuilder.as
│ ├── TestQueryQueue.as
│ ├── TestRawQuery.as
│ ├── TestSchema.as
│ ├── collections
│ └── TestCollection.as
│ ├── migrations
│ ├── Migration_Create_Table_Photos.as
│ ├── Migration_Insert_Default_Photos.as
│ ├── Migration_Invalid_Class.as
│ ├── Migration_Unsuccessful.as
│ └── TestMigrations.as
│ └── models
│ ├── CustomTableModel.as
│ ├── Photo.as
│ ├── PhotoAlbum.as
│ └── TestModel.as
└── test.iml
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea/dictionaries
2 | /.idea/compiler.xml
3 | /.idea/flexCompiler.xml
4 | /.idea/misc.xml
5 | /.idea/workspace.xml
6 | /test/bin
7 | /bin
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | BreezeDb
--------------------------------------------------------------------------------
/.idea/breeze-db.iml:
--------------------------------------------------------------------------------
1 |
2 | database
is reserved
70 | * for the default database accessed using BreezeDb.db
or the DB
71 | * facade class.
72 | *
73 | * @param databaseName The name of the database to retrieve. It will be created if it does not exist.
74 | * @return Reference to the database.
75 | *
76 | * @see #db
77 | */
78 | public static function getDb(databaseName:String):IBreezeDatabase
79 | {
80 | if(_databases == null)
81 | {
82 | _databases = new Dictionary();
83 | }
84 |
85 | // Create new database
86 | if(!(databaseName in _databases))
87 | {
88 | _databases[databaseName] = new BreezeDbInstance(databaseName);
89 | }
90 | return _databases[databaseName];
91 | }
92 |
93 |
94 | /**
95 | * The directory where the database files are created.
96 | *
97 | * @default File.applicationStorageDirectory
98 | */
99 | public static function get storageDirectory():File
100 | {
101 | return _storageDirectory;
102 | }
103 |
104 |
105 | /**
106 | * @private
107 | */
108 | public static function set storageDirectory(value:File):void
109 | {
110 | if(value == null)
111 | {
112 | throw new ArgumentError("Storage directory cannot be null.");
113 | }
114 |
115 | if(!value.exists || !value.isDirectory)
116 | {
117 | throw new Error("Storage directory must point to an existing directory.");
118 | }
119 |
120 | _storageDirectory = value;
121 | }
122 |
123 |
124 | /**
125 | * File extension for the database files. It must contain a dot followed by at least one character,
126 | * without spaces.
127 | *
128 | * @default .sqlite
129 | */
130 | public static function get fileExtension():String
131 | {
132 | return _fileExtension;
133 | }
134 |
135 |
136 | /**
137 | * @private
138 | */
139 | public static function set fileExtension(value:String):void
140 | {
141 | if(value == null)
142 | {
143 | throw new ArgumentError("File extension cannot be null.");
144 | }
145 |
146 | if(value.indexOf(" ") >= 0)
147 | {
148 | throw new ArgumentError("Extension cannot contain spaces");
149 | }
150 |
151 | var dotIndex:int = value.lastIndexOf(".");
152 | if(!(dotIndex >= 0 && dotIndex != value.length - 1))
153 | {
154 | throw new ArgumentError("Extension must contain a dot followed by at least one character.");
155 | }
156 |
157 | _fileExtension = value;
158 | }
159 |
160 |
161 | /**
162 | * Flag to control whether BreezeDb should queue SQL queries,
163 | * i.e. run at most one at a time and in the same order as they are created.
164 | *
165 | * Make sure there are no queries running when changing this value.
166 | *
167 | * @default false
168 | */
169 | public static function get isQueryQueueEnabled():Boolean
170 | {
171 | return _isQueryQueueEnabled;
172 | }
173 |
174 |
175 | /**
176 | * @private
177 | */
178 | public static function set isQueryQueueEnabled(value:Boolean):void
179 | {
180 | _isQueryQueueEnabled = value;
181 | BreezeRawQuery.breezedb_internal::useQueryQueue = value;
182 | }
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/src/breezedb/IBreezeDatabase.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb
27 | {
28 | import breezedb.queries.BreezeQueryBuilder;
29 | import breezedb.queries.IRawQuery;
30 | import breezedb.schemas.BreezeSchemaBuilder;
31 |
32 | import flash.data.SQLConnection;
33 |
34 | import flash.events.IEventDispatcher;
35 | import flash.filesystem.File;
36 |
37 | /**
38 | * Interface that defines API to interact with the database.
39 | */
40 | public interface IBreezeDatabase extends IEventDispatcher, IRawQuery
41 | {
42 | /**
43 | * Sets up the database by creating SQL connection and database file, if it does not exist.
44 | * The connection is created asynchronously.
45 | *
46 | * @param callback Function called once the setup finishes. It must have the following signature:
47 | *
BreezeDb.storageDirectory
where the file name is the
57 | * database name followed by BreezeDb.fileExtension
.
58 | *
59 | * @see #close()
60 | * @see breezedb.BreezeDb#fileExtension
61 | * @see breezedb.BreezeDb#storageDirectory
62 | */
63 | function setup(callback:Function, databaseFile:File = null):void;
64 |
65 |
66 | /**
67 | * Returns query builder associated with the given table.
68 | *
69 | * @param tableName The table that will be associated with the returned query builder.
70 | * @return Query builder associated with the given table.
71 | */
72 | function table(tableName:String):BreezeQueryBuilder;
73 |
74 |
75 | /**
76 | * Begins a transaction within which all SQL statements executed against the connection's database are grouped.
77 | *
78 | * @param callback Function triggered once the operation finishes. It should have a single Error
79 | * object as a parameter.
80 | *
81 | * @see #commit()
82 | * @see #rollBack()
83 | */
84 | function beginTransaction(callback:Function):void;
85 |
86 |
87 | /**
88 | * Commits an existing transaction, causing any actions performed by the transaction's statements to be
89 | * permanently applied to the database.
90 | *
91 | * @param callback Function triggered once the operation finishes. It should have a single Error
92 | * object as a parameter.
93 | *
94 | * @see #beginTransaction()
95 | * @see #rollBack()
96 | */
97 | function commit(callback:Function):void;
98 |
99 |
100 | /**
101 | * Rolls back an existing transaction created using the beginTransaction
method,
102 | * meaning all changes made by any SQL statements in the transaction are discarded.
103 | *
104 | * @param callback Function triggered once the operation finishes. It should have a single Error
105 | * object as a parameter.
106 | *
107 | * @see #commit()
108 | * @see #beginTransaction()
109 | */
110 | function rollBack(callback:Function):void;
111 |
112 |
113 | /**
114 | * Closes the existing SQL connection.
115 | *
116 | * @param callback Function called once the operation finishes. It must have the following signature:
117 | * Array
of migration classes.
135 | * Each class must be a subclass of BreezeMigration
.
136 | * @param callback Function called once the migrations are completed. It must have the following signature:
137 | * Array
of migration classes that will be run during the database setup.
160 | * Each class must be a subclass of BreezeMigration
.
161 | *
162 | * @see #runMigrations()
163 | * @see breezedb.migrations.BreezeMigration
164 | */
165 | function get migrations():*;
166 |
167 |
168 | /**
169 | * Returns schema builder associated with the database.
170 | */
171 | function get schema():BreezeSchemaBuilder;
172 |
173 |
174 | /**
175 | * Reference to the file where the database is stored.
176 | */
177 | function get file():File;
178 |
179 |
180 | /**
181 | * Name of the database.
182 | */
183 | function get name():String;
184 |
185 |
186 | /**
187 | * Returns true
if the database is set up and the SQL connection is active.
188 | */
189 | function get isSetup():Boolean;
190 |
191 |
192 | /**
193 | * @private
194 | */
195 | function set encryptionKey(value:*):void;
196 |
197 |
198 | /**
199 | * The value used to encrypt the database file. It be either a String
200 | * (at least one character) or 16 bytes long ByteArray
.
201 | */
202 | function get encryptionKey():*;
203 |
204 |
205 | /**
206 | * The SQL connection for this database.
207 | */
208 | function get connection():SQLConnection;
209 |
210 |
211 | /**
212 | * Returns true
if the database connection is currently involved in a transaction.
213 | */
214 | function get inTransaction():Boolean;
215 | }
216 |
217 | }
218 |
--------------------------------------------------------------------------------
/src/breezedb/breezedb_internal.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb
27 | {
28 |
29 | internal namespace breezedb_internal = "https://getbreeze.io/breezedb";
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/breezedb/events/BreezeDatabaseEvent.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.events
27 | {
28 | import flash.events.Event;
29 |
30 | /**
31 | * Event dispatched after one of the database operations is executed.
32 | */
33 | public class BreezeDatabaseEvent extends Event
34 | {
35 |
36 | /**
37 | * A transaction has begun successfully.
38 | */
39 | public static const BEGIN_SUCCESS:String = "BreezeDatabaseEvent::beginSuccess";
40 |
41 | /**
42 | * Failed to begin a transaction.
43 | */
44 | public static const BEGIN_ERROR:String = "BreezeDatabaseEvent::beginError";
45 |
46 | /**
47 | * A transaction was committed successfully.
48 | */
49 | public static const COMMIT_SUCCESS:String = "BreezeDatabaseEvent::commitSuccess";
50 |
51 | /**
52 | * Failed to commit a transaction.
53 | */
54 | public static const COMMIT_ERROR:String = "BreezeDatabaseEvent::commitError";
55 |
56 | /**
57 | * A transaction was rolled back successfully.
58 | */
59 | public static const ROLL_BACK_SUCCESS:String = "BreezeDatabaseEvent::rollBackSuccess";
60 |
61 | /**
62 | * Failed to roll back a transaction.
63 | */
64 | public static const ROLL_BACK_ERROR:String = "BreezeDatabaseEvent::rollBackError";
65 |
66 | /**
67 | * A database has been set up successfully.
68 | */
69 | public static const SETUP_SUCCESS:String = "BreezeDatabaseEvent::setupSuccess";
70 |
71 | /**
72 | * Failed to set up a database.
73 | */
74 | public static const SETUP_ERROR:String = "BreezeDatabaseEvent::setupError";
75 |
76 | /**
77 | * A database was closed successfully.
78 | */
79 | public static const CLOSE_SUCCESS:String = "BreezeDatabaseEvent::closeSuccess";
80 |
81 | /**
82 | * Failed to close a database.
83 | */
84 | public static const CLOSE_ERROR:String = "BreezeDatabaseEvent::closeError";
85 |
86 |
87 | private var _error:Error;
88 |
89 |
90 | /**
91 | * @private
92 | */
93 | public function BreezeDatabaseEvent(type:String, error:Error = null)
94 | {
95 | super(type, false, false);
96 |
97 | _error = error;
98 | }
99 |
100 |
101 | /**
102 | * @inheritDoc
103 | */
104 | override public function clone():Event
105 | {
106 | return new BreezeDatabaseEvent(type, _error);
107 | }
108 |
109 |
110 | /**
111 | * Error that occurred while executing the corresponding operation, or null
if there is no error.
112 | */
113 | public function get error():Error
114 | {
115 | return _error;
116 | }
117 | }
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/src/breezedb/events/BreezeMigrationEvent.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.events
27 | {
28 | import flash.events.Event;
29 |
30 | /**
31 | * Event dispatched when a database migration is completed, either successfully or with an error.
32 | */
33 | public class BreezeMigrationEvent extends Event
34 | {
35 | /**
36 | * A migration ran successfully.
37 | */
38 | public static const RUN_SUCCESS:String = "BreezeMigrationEvent::runSuccess";
39 |
40 | /**
41 | * Failed to run a migration.
42 | */
43 | public static const RUN_ERROR:String = "BreezeMigrationEvent::runError";
44 |
45 | /**
46 | * A migration was skipped because it had already been run.
47 | */
48 | public static const SKIP:String = "BreezeMigrationEvent::skip";
49 |
50 | /**
51 | * Finished running migrations. Note this does not mean all migrations had run,
52 | * only that no further migrations will run.
53 | */
54 | public static const FINISH:String = "BreezeMigrationEvent::finish";
55 |
56 |
57 | /**
58 | * @private
59 | */
60 | public function BreezeMigrationEvent(type:String)
61 | {
62 | super(type, false, false);
63 | }
64 |
65 |
66 | /**
67 | * @inheritDoc
68 | */
69 | override public function clone():Event
70 | {
71 | return new BreezeMigrationEvent(type);
72 | }
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/breezedb/events/BreezeQueryEvent.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.events
27 | {
28 | import breezedb.queries.BreezeSQLResult;
29 |
30 | import flash.events.Event;
31 |
32 | /**
33 | * Event dispatched when a SQL query execution is finished, either successfully or with an error.
34 | */
35 | public class BreezeQueryEvent extends Event
36 | {
37 | /**
38 | * A query was executed successfully.
39 | */
40 | public static const SUCCESS:String = "BreezeQueryEvent::success";
41 |
42 | /**
43 | * Failed to execute a query.
44 | */
45 | public static const ERROR:String = "BreezeQueryEvent::error";
46 |
47 | private var _error:Error;
48 | private var _result:BreezeSQLResult;
49 | private var _query:String;
50 |
51 |
52 | /**
53 | * @private
54 | */
55 | public function BreezeQueryEvent(type:String, error:Error, result:BreezeSQLResult, query:String)
56 | {
57 | super(type, false, false);
58 | _error = error;
59 | _result = result;
60 | _query = query;
61 | }
62 |
63 |
64 | /**
65 | * @inheritDoc
66 | */
67 | override public function clone():Event
68 | {
69 | return new BreezeQueryEvent(type, _error, _result, _query);
70 | }
71 |
72 |
73 | /**
74 | * Error that occurred while executing the query, or null
if there is no error.
75 | */
76 | public function get error():Error
77 | {
78 | return _error;
79 | }
80 |
81 |
82 | /**
83 | * SQL result of the query. It is null
for queries regarding table / column schema.
84 | */
85 | public function get result():BreezeSQLResult
86 | {
87 | return _result;
88 | }
89 |
90 |
91 | /**
92 | * The raw SQL query that was executed.
93 | */
94 | public function get query():String
95 | {
96 | return _query;
97 | }
98 | }
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/src/breezedb/events/BreezeSQLStatementEvent.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.events
27 | {
28 | import flash.events.Event;
29 |
30 | /**
31 | * Event dispatched when a SQL statement is completed, either successfully or with an error.
32 | * Internal use only.
33 | * @private
34 | */
35 | public class BreezeSQLStatementEvent extends Event
36 | {
37 | /**
38 | * A SQL statement has completed.
39 | */
40 | public static const COMPLETE:String = "BreezeSQLStatementEvent::complete";
41 |
42 |
43 | /**
44 | * @private
45 | */
46 | public function BreezeSQLStatementEvent(type:String)
47 | {
48 | super(type, false, false);
49 | }
50 |
51 |
52 | /**
53 | * @inheritDoc
54 | */
55 | override public function clone():Event
56 | {
57 | return new BreezeSQLStatementEvent(type);
58 | }
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/src/breezedb/migrations/BreezeMigration.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.migrations
27 | {
28 | import breezedb.IBreezeDatabase;
29 | import breezedb.events.BreezeMigrationEvent;
30 |
31 | import flash.events.EventDispatcher;
32 | import flash.utils.getQualifiedClassName;
33 |
34 | /**
35 | * Base class providing API to run a database migration.
36 | */
37 | public class BreezeMigration extends EventDispatcher
38 | {
39 |
40 | /**
41 | * @private
42 | */
43 | public function BreezeMigration()
44 | {
45 | }
46 |
47 |
48 | /**
49 | * Provides the migration functionality. Must be overridden.
50 | *
51 | * @param db Reference to the database used during this migration.
52 | */
53 | public function run(db:IBreezeDatabase):void
54 | {
55 | throw new Error("The run method must be overridden.");
56 | }
57 |
58 |
59 | /**
60 | * The done
method must be called at the end of each migration.
61 | *
62 | * @param successful true
if the migration was successful, false
otherwise.
63 | */
64 | protected final function done(successful:Boolean = true):void
65 | {
66 | var eventType:String = successful ? BreezeMigrationEvent.RUN_SUCCESS : BreezeMigrationEvent.RUN_ERROR;
67 | dispatchEvent(new BreezeMigrationEvent(eventType));
68 | }
69 |
70 |
71 | /**
72 | * @private
73 | * Returns the class name. Stored in a database table to track previously run migrations.
74 | */
75 | internal function get name():String
76 | {
77 | var className:String = getQualifiedClassName(this);
78 | var index:int = className.lastIndexOf("::");
79 | if(index >= 0)
80 | {
81 | className = className.slice(index + 2);
82 | }
83 | return className;
84 | }
85 |
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/src/breezedb/migrations/BreezeMigrationsRunner.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.migrations
27 | {
28 | import breezedb.IBreezeDatabase;
29 | import breezedb.collections.Collection;
30 | import breezedb.events.BreezeMigrationEvent;
31 | import breezedb.schemas.TableBlueprint;
32 |
33 | import flash.events.EventDispatcher;
34 |
35 | /**
36 | * @private
37 | */
38 | public class BreezeMigrationsRunner extends EventDispatcher
39 | {
40 | private static const MIGRATIONS_TABLE:String = "breeze_migrations_internal";
41 |
42 | private var _currentIndex:int = -1;
43 |
44 | // True if this runner is in control of the current transaction
45 | private var _transactionControl:Boolean;
46 |
47 | private var _db:IBreezeDatabase;
48 | private var _callback:Function;
49 | private var _migrations:Vector.Object
(where keys represent column names) used
78 | * to initialize the model's properties.
79 | */
80 | public function BreezeModel(initialValues:Object = null)
81 | {
82 | super(null);
83 |
84 | _databaseName = BreezeDb.DEFAULT_DB;
85 |
86 | if(initialValues != null)
87 | {
88 | populateFromObject(initialValues, false);
89 | }
90 | }
91 |
92 |
93 | /**
94 | *
95 | *
96 | * Public API
97 | *
98 | *
99 | */
100 |
101 |
102 | /**
103 | * Helper method that retrieves an instance of BreezeModelQueryBuilder
for the given model class.
104 | *
105 | * @param modelClass The model to retrieve the builder for. Must be a subclass
106 | * of BreezeModel
class.
107 | * @return Instance of BreezeModelQueryBuilder
associated with the given model.
108 | */
109 | public static function query(modelClass:Class):BreezeModelQueryBuilder
110 | {
111 | return new BreezeModelQueryBuilder(modelClass);
112 | }
113 |
114 |
115 | /**
116 | * Saves this model to the database. If it exists, its values will be updated.
117 | *
118 | * @param callback Function that is triggered when the query is completed. The saved model is returned
119 | * to the callback as the second argument.
120 | *
121 | * BreezeQueryReference
object that allows cancelling the request callback.
132 | */
133 | public function save(callback:Function = null):BreezeQueryReference
134 | {
135 | var modelClass:Class = Object(this).constructor as Class;
136 | return new BreezeModelQueryBuilder(modelClass).save(this, callback);
137 | }
138 |
139 |
140 | /**
141 | * Removes this model from the database.
142 | *
143 | * @param callback Function that is triggered when the query is completed.
144 | *
145 | * BreezeQueryReference
object that allows cancelling the request callback.
159 | */
160 | public function remove(callback:Function = null):BreezeQueryReference
161 | {
162 | var modelClass:Class = Object(this).constructor as Class;
163 | if(primaryKey == null || !(primaryKey in this))
164 | {
165 | throw new IllegalOperationError("The model " + modelClass + " has no primary key set.");
166 | }
167 | return new BreezeModelQueryBuilder(modelClass).removeByKey(this[primaryKey], callback).queryReference;
168 | }
169 |
170 |
171 | /**
172 | *
173 | *
174 | * Internal / Private API
175 | *
176 | *
177 | */
178 |
179 |
180 | /**
181 | * @private
182 | */
183 | internal function populateFromObject(values:Object, exists:Boolean = true):void
184 | {
185 | for(var property:String in values)
186 | {
187 | if(property in this)
188 | {
189 | this[property] = values[property];
190 | }
191 | }
192 |
193 | setExists(exists);
194 | }
195 |
196 |
197 | /**
198 | * @private
199 | */
200 | internal function toKeyValue(omitPrimaryKey:Boolean = false):Object
201 | {
202 | var result:Object = {};
203 |
204 | var description:XML = describeType(this);
205 | var variables:XMLList = description..variable;
206 | for each(var variable:XML in variables)
207 | {
208 | var column:String = variable.@name;
209 | if((column == '') || (omitPrimaryKey && (primaryKey == column)))
210 | {
211 | continue;
212 | }
213 |
214 | result[column] = this[column];
215 | }
216 |
217 | return result;
218 | }
219 |
220 |
221 | /**
222 | * @private
223 | */
224 | internal function setExists(value:Boolean):void
225 | {
226 | _exists = value;
227 | }
228 |
229 |
230 | /**
231 | *
232 | *
233 | * Getters / Setters
234 | *
235 | *
236 | */
237 |
238 |
239 | private function get className():String
240 | {
241 | var className:String = getQualifiedClassName(this);
242 | var index:int = className.lastIndexOf("::");
243 | if(index >= 0)
244 | {
245 | className = className.slice(index + 2);
246 | }
247 | return className;
248 | }
249 |
250 |
251 | /**
252 | * Returns the model's table name.
253 | */
254 | public function get tableName():String
255 | {
256 | if(_tableName != null)
257 | {
258 | return _tableName;
259 | }
260 |
261 | var regExp:RegExp = /(^[a-z]|[A-Z0-9])[a-z]*/g;
262 | var className:String = this.className;
263 | var result:Array = className.match(regExp);
264 |
265 | if(result != null && result.length > 0)
266 | {
267 | className = result.join("_");
268 | }
269 |
270 | className = className.toLowerCase();
271 |
272 | _tableName = Inflect.pluralize(className);
273 | return _tableName;
274 | }
275 |
276 |
277 | /**
278 | * Returns the model's database name.
279 | */
280 | public function get databaseName():String
281 | {
282 | return _databaseName;
283 | }
284 |
285 |
286 | /**
287 | * Returns the name of the model's primary key.
288 | */
289 | public function get primaryKey():String
290 | {
291 | return _primaryKey;
292 | }
293 |
294 |
295 | /**
296 | * Returns true
if the model exists in the database.
297 | */
298 | public function get exists():Boolean
299 | {
300 | return _exists;
301 | }
302 |
303 |
304 | /**
305 | * Returns true
if the model has an auto-incrementing id.
306 | */
307 | public function get autoIncrementId():Boolean
308 | {
309 | return _autoIncrementId;
310 | }
311 | }
312 |
313 | }
314 |
--------------------------------------------------------------------------------
/src/breezedb/models/BreezeModelQueryBuilder.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.models
27 | {
28 | import breezedb.BreezeDb;
29 | import breezedb.IBreezeDatabase;
30 | import breezedb.collections.Collection;
31 | import breezedb.queries.BreezeQueryBuilder;
32 | import breezedb.queries.BreezeQueryReference;
33 | import breezedb.queries.BreezeSQLResult;
34 | import breezedb.utils.Callback;
35 | import breezedb.utils.GarbagePrevention;
36 |
37 | import flash.errors.IllegalOperationError;
38 |
39 | /**
40 | * Class providing API to run queries on a table associated with the given model.
41 | */
42 | public class BreezeModelQueryBuilder extends BreezeQueryBuilder
43 | {
44 | private var _model:BreezeModel;
45 | private var _modelClass:Class;
46 |
47 | /**
48 | * Creates a new builder and associates it with a table of the given model.
49 | *
50 | * @param modelClass The model used to obtain database and table against which the queries will be executed.
51 | */
52 | public function BreezeModelQueryBuilder(modelClass:Class)
53 | {
54 | _modelClass = modelClass;
55 | _model = new modelClass();
56 | var db:IBreezeDatabase = BreezeDb.getDb(_model.databaseName);
57 | super(db, _model.tableName);
58 | }
59 |
60 |
61 | /**
62 | *
63 | *
64 | * Public API
65 | *
66 | *
67 | */
68 |
69 |
70 | /**
71 | * @inheritDoc
72 | */
73 | override public function fetch(callback:* = null):BreezeQueryBuilder
74 | {
75 | if(_callbackProxy == null || _callbackProxy != onFirstCompleted)
76 | {
77 | _callbackProxy = onFetchCompleted;
78 | }
79 | return super.fetch(callback);
80 | }
81 |
82 |
83 | /**
84 | * Finds models that match the given primary keys.
85 | *
86 | * @param primaryKeys Either a single primary key or Array
of primary keys.
87 | * @param callback This parameter can be one of the following:
88 | * Function
, i.e. a callback that is triggered once the query is completed.
90 | * Its signature depends on whether a single or multiple primary keys are passed to the the
91 | * primaryKeys
parameter:
92 | * BreezeDb.DELAY
constant, resulting in the query being delayed. It can be executed
108 | * later by calling the exec
method on the returned instance of BreezeQueryBuilder
.
109 | * BreezeQueryBuilder
allowing you to obtain the query reference
113 | * or execute the query at later time if it was delayed.
114 | */
115 | public function find(primaryKeys:*, callback:* = null):BreezeQueryBuilder
116 | {
117 | if(primaryKeys == null)
118 | {
119 | throw new ArgumentError("Parameter primaryKeys cannot be null.");
120 | }
121 |
122 | if(_model.primaryKey == null)
123 | {
124 | throw new IllegalOperationError("The model " + _modelClass + " has no primary key set.");
125 | }
126 |
127 | // Fetch all the records whose id matches one of the value in the given array
128 | if(primaryKeys is Array)
129 | {
130 | return whereIn(_model.primaryKey, primaryKeys).fetch(callback);
131 | }
132 |
133 | // We are looking for a single value so use the callback proxy of the 'first' method
134 | _callbackProxy = onFirstCompleted;
135 | return where(_model.primaryKey, primaryKeys).fetch(callback);
136 | }
137 |
138 |
139 | /**
140 | * Returns the first model that matches the given values. If match is not found, a new model instance
141 | * with those values is returned. Note this instance is not saved to the database.
142 | * You will need to call the model's save
method.
143 | *
144 | * @param values Key-value object specifying column names and values that will be used to find the matching model.
145 | * @param callback Function that is triggered when the query is completed.
146 | *
147 | * Array
of primary keys.
196 | * @param callback Function that is triggered when the query is completed.
197 | *
198 | * BreezeQueryBuilder
allowing you to obtain the query reference
212 | * or execute the query at later time if it was delayed.
213 | */
214 | public function removeByKey(primaryKeys:*, callback:* = null):BreezeQueryBuilder
215 | {
216 | if(primaryKeys == null)
217 | {
218 | throw new ArgumentError("Parameter primaryKeys cannot be null.");
219 | }
220 |
221 | if(_model.primaryKey == null || !(_model.primaryKey in _model))
222 | {
223 | throw new IllegalOperationError("The model " + _modelClass + " has no primary key set.");
224 | }
225 |
226 | if(primaryKeys is Array)
227 | {
228 | whereIn(_model.primaryKey, primaryKeys);
229 | }
230 | else
231 | {
232 | where(_model.primaryKey, primaryKeys);
233 | }
234 |
235 | return remove(callback);
236 | }
237 |
238 |
239 | /**
240 | *
241 | *
242 | * Internal / Private API
243 | *
244 | *
245 | */
246 |
247 |
248 | private function getTypedCollection(collection:Collection):Collection
249 | {
250 | var castCollection:Collection = new Collection();
251 |
252 | // Cast each Object to model object
253 | for(var i:int = 0; i < collection.length; i++)
254 | {
255 | var model:BreezeModel = new _modelClass();
256 | model.populateFromObject(collection[i]);
257 | castCollection.add(model);
258 | }
259 |
260 | return castCollection;
261 | }
262 |
263 |
264 | /**
265 | * Internal implementation for 'firstOrNew' and 'firstOrCreate'.
266 | */
267 | private function firstOrInit(values:Object, callback:Function = null, saveToDatabase:Boolean = false):void
268 | {
269 | if(values == null)
270 | {
271 | throw new ArgumentError("Parameter values cannot be null.");
272 | }
273 |
274 | // Add 'where' clause for each key-value
275 | for(var key:String in values)
276 | {
277 | where(key, values[key]);
278 | }
279 |
280 | var self:BreezeModelQueryBuilder = this;
281 |
282 | // Retrieve the first model matching the given values
283 | first(function(firstError:Error, model:BreezeModel):void
284 | {
285 | // Match not found, create new model
286 | if(model == null)
287 | {
288 | model = new _modelClass();
289 | model.populateFromObject(values, false);
290 |
291 | // Save the model first then trigger the callback
292 | if(saveToDatabase)
293 | {
294 | GarbagePrevention.instance.add(self);
295 | model.save(function(saveError:Error, savedModel:BreezeModel):void
296 | {
297 | GarbagePrevention.instance.remove(self);
298 | Callback.call(callback, [saveError, model]);
299 | });
300 | return;
301 | }
302 | }
303 |
304 | // Create the model with the next available id
305 | if(!model.exists && model.autoIncrementId && !hasSetId(model))
306 | {
307 | model[model.primaryKey] = _db.connection.lastInsertRowID + 1;
308 | }
309 | Callback.call(callback, [firstError, model]);
310 | });
311 | }
312 |
313 |
314 | /**
315 | * @private
316 | */
317 | internal function save(model:BreezeModel, callback:Function = null):BreezeQueryReference
318 | {
319 | _model = model;
320 |
321 | // Perform update
322 | if(model.exists)
323 | {
324 | // We need the primary key to do that
325 | if(model.primaryKey == null || !(model.primaryKey in model))
326 | {
327 | throw new IllegalOperationError("Cannot update model " + model + " when the primary key is unknown.");
328 | }
329 |
330 | _callbackProxy = onUpdateViaSaveCompleted;
331 | return where(model.primaryKey, model[model.primaryKey])
332 | .update(model.toKeyValue(), callback)
333 | .queryReference;
334 | }
335 |
336 | // Perform insertGetId
337 | _callbackProxy = onInsertViaSaveCompleted;
338 |
339 | // Omit the primary key in the insert statement to have one assigned automatically via auto-increment
340 | var omitPrimaryKey:Boolean = (model.autoIncrementId) && !hasSetId(model);
341 | return insertGetId(model.toKeyValue(omitPrimaryKey), callback).queryReference;
342 | }
343 |
344 |
345 | private function hasSetId(model:BreezeModel):Boolean
346 | {
347 | return !((model.primaryKey != null) && (model.primaryKey in model) && (model[model.primaryKey] is Number) && (model[model.primaryKey] < 1));
348 | }
349 |
350 |
351 | /**
352 | *
353 | * Proxy callbacks
354 | *
355 | * Cast query response to model's class.
356 | *
357 | */
358 |
359 |
360 | /**
361 | * @private
362 | */
363 | override protected function onFirstCompleted(error:Error, results:Collection):void
364 | {
365 | _callbackProxy = null;
366 |
367 | var result:Object = (results.length > 0) ? results[0] : null;
368 | var model:BreezeModel = null;
369 | if(result != null)
370 | {
371 | model = new _modelClass();
372 | model.populateFromObject(result);
373 | }
374 | finishProxiedQuery([error, model]);
375 | }
376 |
377 |
378 | /**
379 | * @private
380 | */
381 | override protected function onChunkCompleted(error:Error, results:Collection):void
382 | {
383 | var castCollection:Collection = getTypedCollection(results);
384 | super.onChunkCompleted(error, castCollection);
385 | }
386 |
387 |
388 | /**
389 | * @private
390 | */
391 | protected function onFetchCompleted(error:Error, results:Collection):void
392 | {
393 | _callbackProxy = null;
394 |
395 | var castCollection:Collection = getTypedCollection(results);
396 | finishProxiedQuery([error, castCollection]);
397 | }
398 |
399 |
400 | /**
401 | * @private
402 | */
403 | protected function onUpdateViaSaveCompleted(error:Error, rowsAffected:int):void
404 | {
405 | _callbackProxy = null;
406 |
407 | finishProxiedQuery([error, _model]);
408 | }
409 |
410 |
411 | /**
412 | * @private
413 | */
414 | protected function onInsertViaSaveCompleted(error:Error, result:BreezeSQLResult):void
415 | {
416 | _callbackProxy = null;
417 |
418 | if(error == null)
419 | {
420 | if(_model.primaryKey != null &&
421 | _model.autoIncrementId &&
422 | _model.hasOwnProperty(_model.primaryKey) &&
423 | (_model[_model.primaryKey] is Number))
424 | {
425 | _model[_model.primaryKey] = result.lastInsertRowID;
426 | }
427 | _model.setExists(true);
428 | }
429 | finishProxiedQuery([error, _model]);
430 | }
431 | }
432 |
433 | }
434 |
--------------------------------------------------------------------------------
/src/breezedb/queries/BreezeJoinStatement.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.queries
27 | {
28 |
29 | internal class BreezeJoinStatement
30 | {
31 | public static const INNER_JOIN:String = "INNER JOIN";
32 | public static const LEFT_OUTER_JOIN:String = "LEFT OUTER JOIN";
33 | public static const CROSS_JOIN:String = "CROSS JOIN";
34 |
35 | private var _type:String;
36 | private var _tableName:String;
37 | private var _predicate:String;
38 |
39 | public function BreezeJoinStatement(type:String, tableName:String, predicate:String = null)
40 | {
41 | _type = type;
42 | _tableName = tableName;
43 | _predicate = predicate;
44 | }
45 |
46 |
47 | public function get type():String
48 | {
49 | return _type;
50 | }
51 |
52 |
53 | public function get tableName():String
54 | {
55 | return _tableName;
56 | }
57 |
58 |
59 | public function get predicate():String
60 | {
61 | return _predicate;
62 | }
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/src/breezedb/queries/BreezeQueryReference.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.queries
27 | {
28 | import flash.events.Event;
29 | import flash.events.EventDispatcher;
30 |
31 | /**
32 | * Class providing API that allows cancelling callback of executed query.
33 | */
34 | public class BreezeQueryReference extends EventDispatcher
35 | {
36 | /**
37 | * Name for event that is dispatched when the query is cancelled.
38 | */
39 | public static const CANCEL:String = "cancel";
40 |
41 | private var _rawQuery:BreezeRawQuery;
42 |
43 |
44 | /**
45 | * @private
46 | */
47 | public function BreezeQueryReference(rawQuery:BreezeRawQuery)
48 | {
49 | _rawQuery = rawQuery;
50 | }
51 |
52 |
53 | /**
54 | * Prevents the query callback from being triggered. Note that this does not stop
55 | * the actual SQL query from running, it only stops the callback from being called.
56 | */
57 | public function cancel():void
58 | {
59 | _rawQuery.cancel();
60 | dispatchEvent(new Event(CANCEL));
61 | }
62 |
63 |
64 | /**
65 | * Returns true
if the query is completed.
66 | */
67 | public function get isCompleted():Boolean
68 | {
69 | return _rawQuery.isCompleted;
70 | }
71 |
72 |
73 | /**
74 | * Returns true
if the query is cancelled.
75 | */
76 | public function get isCancelled():Boolean
77 | {
78 | return _rawQuery.isCancelled;
79 | }
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/src/breezedb/queries/BreezeQueryResult.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.queries
27 | {
28 | import flash.data.SQLResult;
29 |
30 | /**
31 | * Class providing access to results of a single query when executing multiple SQL statements.
32 | */
33 | public class BreezeQueryResult extends BreezeSQLResult
34 | {
35 | private var _error:Error;
36 |
37 |
38 | /**
39 | * @private
40 | */
41 | public function BreezeQueryResult(result:SQLResult, error:Error)
42 | {
43 | super(result);
44 |
45 | _error = error;
46 | }
47 |
48 |
49 | /**
50 | * An error that occurred while executing the query, or null
if there is no error.
51 | */
52 | public function get error():Error
53 | {
54 | return _error;
55 | }
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/breezedb/queries/BreezeQueryRunner.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.queries
27 | {
28 | import breezedb.IBreezeDatabase;
29 | import breezedb.utils.GarbagePrevention;
30 |
31 | import flash.events.Event;
32 |
33 | /**
34 | * Base class for classes that create and run SQL queries.
35 | */
36 | public class BreezeQueryRunner
37 | {
38 | /**
39 | * @private
40 | */
41 | internal static const MULTI_QUERY_RAW:int = 0;
42 |
43 | /**
44 | * @private
45 | */
46 | internal static const MULTI_QUERY_FAIL_ON_ERROR:int = 1;
47 |
48 | /**
49 | * @private
50 | */
51 | internal static const MULTI_QUERY_TRANSACTION:int = 2;
52 |
53 | /**
54 | * @private
55 | */
56 | internal static const QUERY_RAW:int = 0;
57 |
58 | /**
59 | * @private
60 | */
61 | internal static const QUERY_SELECT:int = 1;
62 |
63 | /**
64 | * @private
65 | */
66 | internal static const QUERY_DELETE:int = 2;
67 |
68 | /**
69 | * @private
70 | */
71 | internal static const QUERY_INSERT:int = 3;
72 |
73 | /**
74 | * @private
75 | */
76 | internal static const QUERY_UPDATE:int = 4;
77 |
78 | /**
79 | * @private
80 | */
81 | protected var _db:IBreezeDatabase;
82 |
83 | /**
84 | * @private
85 | */
86 | protected var _queryString:String;
87 |
88 | /**
89 | * @private
90 | */
91 | protected var _queryType:int;
92 |
93 | /**
94 | * @private
95 | */
96 | protected var _queryParams:Object;
97 |
98 | /**
99 | * @private
100 | */
101 | protected var _queryReference:BreezeQueryReference;
102 |
103 | /**
104 | * @private
105 | */
106 | protected var _multiQueryMethod:int;
107 |
108 | /**
109 | * @private
110 | * Reference to the original callback, if callback proxy is used.
111 | */
112 | protected var _originalCallback:Function;
113 |
114 | /**
115 | * @private
116 | * Callback used in place of the provided callback. Useful when the query response
117 | * needs further processing, e.g. during query builder's chunk call.
118 | */
119 | protected var _callbackProxy:Function;
120 |
121 |
122 | /**
123 | * @private
124 | */
125 | public function BreezeQueryRunner(db:IBreezeDatabase)
126 | {
127 | if(db == null)
128 | {
129 | throw new ArgumentError("Parameter db cannot be null.");
130 | }
131 |
132 | _db = db;
133 | _queryParams = null;
134 | _queryType = QUERY_RAW;
135 | _multiQueryMethod = MULTI_QUERY_TRANSACTION;
136 | }
137 |
138 |
139 | /**
140 | * Executes the query, if it was delayed initially.
141 | *
142 | * @param callback Function that is triggered when the query is completed. The function's signature
143 | * depends on the original query being executed. Refer to the documentation of the method
144 | * used to create the query.
145 | * @return Reference to the executed query.
146 | */
147 | public function exec(callback:Function = null):BreezeQueryReference
148 | {
149 | if(_queryReference != null)
150 | {
151 | return _queryReference;
152 | }
153 |
154 | // Check if there are multiple statements
155 | var queries:Array = _queryString.split(";");
156 |
157 | // Remove empty queries
158 | for(var i:int = 0; i < queries.length; )
159 | {
160 | var queryString:String = queries[i];
161 | if(!(/\S/.test(queryString)))
162 | {
163 | queries.removeAt(i);
164 | continue;
165 | }
166 | ++i;
167 | }
168 |
169 | if(_callbackProxy != null)
170 | {
171 | _originalCallback = callback;
172 | callback = _callbackProxy;
173 |
174 | GarbagePrevention.instance.add(this);
175 | }
176 |
177 | // Run multi query if there are multiple statements
178 | if(queries.length > 1)
179 | {
180 | switch(_multiQueryMethod)
181 | {
182 | case MULTI_QUERY_RAW:
183 | _queryReference = _db.multiQuery(queries, _queryParams, callback);
184 | break;
185 | case MULTI_QUERY_FAIL_ON_ERROR:
186 | _queryReference = _db.multiQueryFailOnError(queries, _queryParams, callback);
187 | break;
188 | case MULTI_QUERY_TRANSACTION:
189 | _queryReference = _db.multiQueryTransaction(queries, _queryParams, callback);
190 | break;
191 | }
192 | listenToQueryCancel();
193 | return _queryReference;
194 | }
195 |
196 | _queryString = queries.join(";");
197 | _queryString += ";";
198 |
199 | switch(_queryType)
200 | {
201 | case QUERY_RAW:
202 | _queryReference = _db.query(_queryString, _queryParams, callback);
203 | break;
204 | case QUERY_SELECT:
205 | _queryReference = _db.select(_queryString, _queryParams, callback);
206 | break;
207 | case QUERY_DELETE:
208 | _queryReference = _db.remove(_queryString, _queryParams, callback);
209 | break;
210 | case QUERY_INSERT:
211 | _queryReference = _db.insert(_queryString, _queryParams, callback);
212 | break;
213 | case QUERY_UPDATE:
214 | _queryReference = _db.update(_queryString, _queryParams, callback);
215 | break;
216 | }
217 | listenToQueryCancel();
218 | return _queryReference;
219 | }
220 |
221 |
222 | /**
223 | *
224 | *
225 | * Private API
226 | *
227 | *
228 | */
229 |
230 |
231 | private function listenToQueryCancel():void
232 | {
233 | // If we are using a proxy, we need to remove this object from GarbagePrevention
234 | // when the query is cancelled, since the proxy will not be triggered
235 | if(_callbackProxy != null)
236 | {
237 | _queryReference.addEventListener(BreezeQueryReference.CANCEL, onQueryCancelled, false, 0, true);
238 | }
239 | }
240 |
241 |
242 | private function onQueryCancelled(event:Event):void
243 | {
244 | _queryReference.removeEventListener(BreezeQueryReference.CANCEL, onQueryCancelled);
245 | GarbagePrevention.instance.remove(this);
246 | }
247 |
248 |
249 | /**
250 | * @private
251 | */
252 | protected function finishProxiedQuery(params:Array):*
253 | {
254 | _queryReference.removeEventListener(BreezeQueryReference.CANCEL, onQueryCancelled);
255 | GarbagePrevention.instance.remove(this);
256 |
257 | if(!_queryReference.isCancelled && _originalCallback != null)
258 | {
259 | params = (params == null) ? null : params.slice(0, _originalCallback.length);
260 |
261 | return _originalCallback.apply(_originalCallback, params);
262 | }
263 | }
264 |
265 |
266 | /**
267 | * @private
268 | */
269 | internal function setMultiQueryMethod(value:int):void
270 | {
271 | _multiQueryMethod = value;
272 | }
273 |
274 |
275 | /**
276 | * @private
277 | */
278 | internal function get database():IBreezeDatabase
279 | {
280 | return _db;
281 | }
282 |
283 |
284 | /**
285 | * @private
286 | */
287 | internal function get parameters():Object
288 | {
289 | return _queryParams;
290 | }
291 |
292 |
293 | /**
294 | *
295 | *
296 | * Getters / Setters
297 | *
298 | *
299 | */
300 |
301 |
302 | /**
303 | * The SQL query to be executed.
304 | */
305 | public function get queryString():String
306 | {
307 | return _queryString;
308 | }
309 |
310 |
311 | /**
312 | * Reference to the query that is being executed. It is null
if the query execution is delayed.
313 | */
314 | public function get queryReference():BreezeQueryReference
315 | {
316 | return _queryReference;
317 | }
318 |
319 | }
320 |
321 | }
322 |
--------------------------------------------------------------------------------
/src/breezedb/queries/BreezeSQLMultiStatement.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.queries
27 | {
28 | import breezedb.BreezeDb;
29 | import breezedb.IBreezeDatabase;
30 | import breezedb.collections.Collection;
31 | import breezedb.events.BreezeQueryEvent;
32 | import breezedb.events.BreezeSQLStatementEvent;
33 | import breezedb.utils.Callback;
34 | import breezedb.utils.GarbagePrevention;
35 |
36 | import flash.data.SQLResult;
37 | import flash.data.SQLStatement;
38 | import flash.errors.IllegalOperationError;
39 | import flash.events.EventDispatcher;
40 |
41 | internal class BreezeSQLMultiStatement extends EventDispatcher implements ISQLStatement
42 | {
43 | private var _isRunning:Boolean;
44 | private var _currentIndex:int = -1;
45 | private var _currentRawQuery:String;
46 | private var _failOnError:Boolean;
47 | private var _transaction:Boolean;
48 |
49 | // True if this multi-statement is in control of the current transaction
50 | private var _transactionControl:Boolean;
51 |
52 | private var _db:IBreezeDatabase;
53 | private var _callback:Function;
54 | private var _queries:Array;
55 | private var _results:Vector.INSERT
, UPDATE
, or DELETE
statement are counted.
62 | */
63 | public function get rowsAffected():Number
64 | {
65 | return (_result != null) ? _result.rowsAffected : -1;
66 | }
67 |
68 |
69 | /**
70 | * The last generated row identifier generated by a SQL INSERT
statement.
71 | */
72 | public function get lastInsertRowID():Number
73 | {
74 | return (_result != null) ? _result.lastInsertRowID : -1;
75 | }
76 |
77 |
78 | /**
79 | * The data returned as a result of the statement execution, specifically when a SQL SELECT
80 | * statement is executed.
81 | *
82 | * When a statement returns one or more rows this property is an array containing objects that 83 | * represent the rows of result data. Each object in the array has property names that correspond 84 | * to the result data set's column names.
85 | * 86 | *The returned Collection
is never null
.
BreezeSQLResult
object.
36 | *
37 | * @param rawQuery SQL query to execute.
38 | * @param params Optional query parameters, i.e. key-value Object
. If query parameters
39 | * are not used, this parameter can specify a callback Function
.
40 | * @param callback Function that is triggered when the query is completed.
41 | *
42 | * BreezeQueryReference
object that allows cancelling the request callback.
56 | */
57 | function query(rawQuery:String, params:* = null, callback:Function = null):BreezeQueryReference;
58 |
59 |
60 | /**
61 | * Executes a SELECT
query on the associated database. The result is cast to a
62 | * Collection
object.
63 | *
64 | * @param rawQuery SQL query to execute.
65 | * @param params Optional query parameters, i.e. key-value Object
. If query parameters
66 | * are not used, this parameter can specify a callback Function
.
67 | * @param callback Function that is triggered when the query is completed.
68 | *
69 | * BreezeQueryReference
object that allows cancelling the request callback.
82 | */
83 | function select(rawQuery:String, params:* = null, callback:Function = null):BreezeQueryReference;
84 |
85 |
86 | /**
87 | * Executes an INSERT
query on the associated database.
88 | *
89 | * @param rawQuery SQL query to execute.
90 | * @param params Optional query parameters, i.e. key-value Object
. If query parameters
91 | * are not used, this parameter can specify a callback Function
.
92 | * @param callback Function that is triggered when the query is completed.
93 | *
94 | * BreezeQueryReference
object that allows cancelling the request callback.
111 | */
112 | function insert(rawQuery:String, params:* = null, callback:Function = null):BreezeQueryReference;
113 |
114 |
115 | /**
116 | * Executes an UPDATE
query on the associated database. The result is cast to
117 | * an int
that provides information about the number of rows affected by the query.
118 | *
119 | * @param rawQuery SQL query to execute.
120 | * @param params Optional query parameters, i.e. key-value Object
. If query parameters
121 | * are not used, this parameter can specify a callback Function
.
122 | * @param callback Function that is triggered when the query is completed.
123 | *
124 | * BreezeQueryReference
object that allows cancelling the request callback.
137 | */
138 | function update(rawQuery:String, params:* = null, callback:Function = null):BreezeQueryReference;
139 |
140 |
141 | /**
142 | * Executes a DELETE
query on the associated database. The result is cast to
143 | * an int
that provides information about the number of rows deleted by the query.
144 | *
145 | * @param rawQuery SQL query to execute.
146 | * @param params Optional query parameters, i.e. key-value Object
. If query parameters
147 | * are not used, this parameter can specify a callback Function
.
148 | * @param callback Function that is triggered when the query is completed.
149 | *
150 | * BreezeQueryReference
object that allows cancelling the request callback.
163 | */
164 | function remove(rawQuery:String, params:* = null, callback:Function = null):BreezeQueryReference;
165 |
166 |
167 | /**
168 | * Executes multiple queries on the associated database. All queries are executed, regardless
169 | * of any errors that occur in earlier queries.
170 | *
171 | * The result is cast to a list of BreezeQueryResult
and the results are in
172 | * the same order as the executed queries. Each result contains an error and result objects.
String
)
175 | * or delayed BreezeQueryRunner
(super class of BreezeQueryBuilder
).
176 | * Note all BreezeQueryRunner
objects must use the same database connection.
177 | * @param params Optional query parameters, i.e. Array
of key-value Objects
178 | * or null
. If query parameters are not used, this parameter can specify
179 | * a callback Function
.
180 | * @param callback Function that is triggered when the query is completed.
181 | *
182 | * BreezeQueryReference
object that allows cancelling the request callback.
209 | */
210 | function multiQuery(rawQueries:Array, params:* = null, callback:Function = null):BreezeQueryReference;
211 |
212 |
213 | /**
214 | * Executes multiple queries on the associated database. If a query fails, the queries that follow
215 | * will not be executed. Successful queries are not rolled back.
216 | *
217 | * The first callback parameter is an Error
object that references the error that
218 | * caused the execution to stop. Additionally, a list of BreezeQueryResult
is provided
219 | * and the results are in the same order as the executed queries. Each result contains an error
220 | * and result objects.
String
)
223 | * or delayed BreezeQueryRunner
(super class of BreezeQueryBuilder
).
224 | * Note all BreezeQueryRunner
objects must use the same database connection.
225 | * @param params Optional query parameters, i.e. Array
of key-value Objects
226 | * or null
. If query parameters are not used, this parameter can specify
227 | * a callback Function
.
228 | * @param callback Function that is triggered when the query is completed.
229 | *
230 | * BreezeQueryReference
object that allows cancelling the request callback.
248 | */
249 | function multiQueryFailOnError(rawQueries:Array, params:* = null, callback:Function = null):BreezeQueryReference;
250 |
251 |
252 | /**
253 | * Executes multiple queries on the associated database. If a query fails, the queries that follow
254 | * will not be executed and the database is rolled back to the state before executing
255 | * the queries.
256 | *
257 | * The first callback parameter is an Error
object that references the error that
258 | * caused the execution to stop. Additionally, a list of BreezeQueryResult
is provided
259 | * and the results are in the same order as the executed queries. Each result contains an error
260 | * and result objects.
String
)
263 | * or delayed BreezeQueryRunner
(super class of BreezeQueryBuilder
).
264 | * Note all BreezeQueryRunner
objects must use the same database connection.
265 | * @param params Optional query parameters, i.e. Array
of key-value Objects
266 | * or null
. If query parameters are not used, this parameter can specify
267 | * a callback Function
.
268 | * @param callback Function that is triggered when the query is completed.
269 | *
270 | * BreezeQueryReference
object that allows cancelling the request callback.
287 | */
288 | function multiQueryTransaction(rawQueries:Array, params:* = null, callback:Function = null):BreezeQueryReference;
289 | }
290 |
291 | }
292 |
--------------------------------------------------------------------------------
/src/breezedb/queries/ISQLStatement.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.queries
27 | {
28 | import flash.events.IEventDispatcher;
29 |
30 | /**
31 | * @private
32 | */
33 | public interface ISQLStatement extends IEventDispatcher
34 | {
35 |
36 | function exec():void;
37 |
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/breezedb/queries/SQLStatementQueue.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.queries
27 | {
28 | import breezedb.IBreezeDatabase;
29 | import breezedb.events.BreezeDatabaseEvent;
30 | import breezedb.events.BreezeSQLStatementEvent;
31 |
32 | import flash.utils.Dictionary;
33 |
34 | internal class SQLStatementQueue
35 | {
36 | private static var _queues:Dictionary;
37 |
38 | private var _db:IBreezeDatabase;
39 | private var _currentStatement:ISQLStatement;
40 | private var _queue:Vector.NOT NULL
constraint on the column.
36 | *
37 | * @return Reference to IColumnConstraint
allowing to chain additional constraints.
38 | */
39 | function notNull():IColumnConstraint;
40 |
41 |
42 | /**
43 | * Adds a DEFAULT [value]
constraint on the column.
44 | *
45 | * @return Reference to IColumnConstraint
allowing to chain additional constraints.
46 | */
47 | function defaultTo(value:*):IColumnConstraint;
48 |
49 |
50 | /**
51 | * Adds a DEFAULT NULL
constraint on the column.
52 | *
53 | * @return Reference to IColumnConstraint
allowing to chain additional constraints.
54 | */
55 | function defaultNull():IColumnConstraint;
56 |
57 |
58 | /**
59 | * Adds a UNIQUE
constraint on the column, ensuring that the column contains a unique value.
60 | *
61 | * @return Reference to IColumnConstraint
allowing to chain additional constraints.
62 | */
63 | function unique():IColumnConstraint;
64 |
65 |
66 | /**
67 | * Designates the column as primary key.
68 | *
69 | * @return Reference to IColumnConstraint
allowing to chain additional constraints.
70 | */
71 | function primary():IColumnConstraint;
72 |
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/breezedb/schemas/TableBlueprint.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.schemas
27 | {
28 | import flash.errors.IllegalOperationError;
29 |
30 | /**
31 | * Class providing API to create and edit table structure.
32 | */
33 | public class TableBlueprint
34 | {
35 | /**
36 | * @private
37 | */
38 | internal static const CREATE:int = 0;
39 |
40 | /**
41 | * @private
42 | */
43 | internal static const ALTER:int = 1;
44 |
45 | private var _statement:int;
46 | private var _tableName:String;
47 | private var _columns:Vector.INTEGER
.
63 | * The column is created as follows: [name] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
,
64 | * additional constraints cannot be applied.
65 | *
66 | * @param columnName Name of the column.
67 | */
68 | public function increments(columnName:String):void
69 | {
70 | addColumn(columnName, ColumnDataType.INTEGER)
71 | .autoIncrement()
72 | .primary()
73 | .notNull();
74 | // No more constraints should be added to this column
75 | }
76 |
77 |
78 | /**
79 | * Adds a new column with the given name and type INTEGER
.
80 | *
81 | * @param columnName Name of the column.
82 | * @return IColumnConstraint
object that allows adding additional constraints on the column.
83 | */
84 | public function integer(columnName:String):IColumnConstraint
85 | {
86 | return addColumn(columnName, ColumnDataType.INTEGER);
87 | }
88 |
89 |
90 | /**
91 | * Adds a new column with the given name and type INTEGER
.
92 | *
93 | * @param columnName Name of the column.
94 | * @return IColumnConstraint
object that allows adding additional constraints on the column.
95 | */
96 | public function string(columnName:String):IColumnConstraint
97 | {
98 | return addColumn(columnName, ColumnDataType.TEXT);
99 | }
100 |
101 |
102 | /**
103 | * Adds a new column with the given name and type BLOB
.
104 | *
105 | * @param columnName Name of the column.
106 | * @return IColumnConstraint
object that allows adding additional constraints on the column.
107 | */
108 | public function blob(columnName:String):IColumnConstraint
109 | {
110 | return addColumn(columnName, ColumnDataType.BLOB);
111 | }
112 |
113 |
114 | /**
115 | * Adds a new column with the given name and type INTEGER
.
116 | *
117 | * @param columnName Name of the column.
118 | * @return IColumnConstraint
object that allows adding additional constraints on the column.
119 | */
120 | public function boolean(columnName:String):IColumnConstraint
121 | {
122 | return addColumn(columnName, ColumnDataType.INTEGER);
123 | }
124 |
125 |
126 | /**
127 | * Adds a new column with the given name and type NUMERIC
.
128 | *
129 | * @param columnName Name of the column.
130 | * @return IColumnConstraint
object that allows adding additional constraints on the column.
131 | */
132 | public function number(columnName:String):IColumnConstraint
133 | {
134 | return addColumn(columnName, ColumnDataType.NUMERIC);
135 | }
136 |
137 |
138 | /**
139 | * Adds a new column with the given name and type DATE
.
140 | *
141 | * @param columnName Name of the column.
142 | * @return IColumnConstraint
object that allows adding additional constraints on the column.
143 | */
144 | public function date(columnName:String):IColumnConstraint
145 | {
146 | return addColumn(columnName, ColumnDataType.DATE);
147 | }
148 |
149 |
150 | /**
151 | * Adds a new column with the given name and type DATETIME
.
152 | *
153 | * @param columnName Name of the column.
154 | * @return IColumnConstraint
object that allows adding additional constraints on the column.
155 | */
156 | public function timestamp(columnName:String):IColumnConstraint
157 | {
158 | return addColumn(columnName, ColumnDataType.DATE_TIME);
159 | }
160 |
161 |
162 | /**
163 | * Creates primary key on one or multiple columns. You can only use this method when creating table.
164 | *
165 | * @param rest List of names (String
) for existing columns on which the primary key will be created.
166 | */
167 | public function primary(...rest):void
168 | {
169 | if(_statement == ALTER)
170 | {
171 | throw new IllegalOperationError("Primary key cannot be changed after the table is created.");
172 | }
173 |
174 | var length:int = rest.length;
175 | for(var i:int = 0; i < length; ++i)
176 | {
177 | var columnName:String = rest[i] as String;
178 | if(columnName == null)
179 | {
180 | throw new ArgumentError("The name of the column must be a String.");
181 | }
182 |
183 | var column:TableColumn = getColumn(columnName);
184 | if(column == null)
185 | {
186 | throw new Error("Cannot create primary key on non-existing column '" + columnName + "'.");
187 | }
188 | column.primary();
189 | }
190 | }
191 |
192 |
193 | /**
194 | * Creates an index on the given column(s).
195 | *
196 | * @param columns Either a String
(column name) or Array
of Strings
197 | * (multiple column names) on which the index should be created.
198 | * @param indexName Optional index name. If not specified, it will default to index_{column_name}
.
199 | * @param unique Similar to UNIQUE
constraint, unique index prevents duplicate entries
200 | * in the column or combination of columns on which there's an index.
201 | */
202 | public function index(columns:*, indexName:String = null, unique:Boolean = false):void
203 | {
204 | if(columns is String)
205 | {
206 | columns = [columns];
207 | }
208 |
209 | if(!(columns is Array))
210 | {
211 | throw new ArgumentError("Parameter columns must be either a String or Array.");
212 | }
213 |
214 | if((columns as Array).length == 0)
215 | {
216 | throw new ArgumentError("At least one column name must be specified.");
217 | }
218 |
219 | _createIndex = "CREATE " + (unique ? "UNIQUE " : "") + "INDEX IF NOT EXISTS ";
220 |
221 | var customIndexName:Boolean = indexName != null;
222 | if(!customIndexName)
223 | {
224 | indexName = "index_";
225 | }
226 |
227 | var columnsString:String = "(";
228 | var length:int = columns.length;
229 | for(var i:int = 0; i < length; ++i)
230 | {
231 | var index:String = columns[i] as String;
232 | if(index == null)
233 | {
234 | throw new ArgumentError("The name of the column must be a String.");
235 | }
236 |
237 | if(i > 0)
238 | {
239 | columnsString += ", ";
240 | }
241 | columnsString += index;
242 |
243 | if(!customIndexName)
244 | {
245 | if(i > 0)
246 | {
247 | indexName += "_";
248 | }
249 | indexName += index;
250 | }
251 | }
252 | columnsString += ")";
253 |
254 | _createIndex += "[" + indexName + "]";
255 | _createIndex += " ON " + _tableName + " ";
256 | _createIndex += columnsString + ";";
257 | }
258 |
259 |
260 | /**
261 | * Removes index with the given name. You can only use this method when editing table.
262 | *
263 | * @param indexName Name of the index to remove.
264 | */
265 | public function dropIndex(indexName:String):void
266 | {
267 | if(_statement == CREATE)
268 | {
269 | throw new IllegalOperationError("Index can be dropped only when editing table.");
270 | }
271 |
272 | if(indexName == null)
273 | {
274 | throw new ArgumentError("Parameter indexName cannot be null.");
275 | }
276 |
277 | _dropIndex = "DROP INDEX " + indexName + ";";
278 | }
279 |
280 |
281 | /**
282 | *
283 | *
284 | * Private API
285 | *
286 | *
287 | */
288 |
289 |
290 | private function addColumn(columnName:String, dataType:int):TableColumn
291 | {
292 | if(columnName == null)
293 | {
294 | throw new ArgumentError("Parameter columnName cannot be null.");
295 | }
296 |
297 | var newColumn:TableColumn = new TableColumn(columnName, dataType, _statement == CREATE);
298 | var index:int = 0;
299 | for each(var column:TableColumn in _columns)
300 | {
301 | if(column.name == newColumn.name)
302 | {
303 | break;
304 | }
305 | index++;
306 | }
307 | _columns[index] = newColumn;
308 | return newColumn;
309 | }
310 |
311 |
312 | private function getColumn(columnName:String):TableColumn
313 | {
314 | for each(var column:TableColumn in _columns)
315 | {
316 | if(column.name == columnName)
317 | {
318 | return column;
319 | }
320 | }
321 | return null;
322 | }
323 |
324 |
325 | /**
326 | * @private
327 | */
328 | internal function setStatement(value:int):void
329 | {
330 | _statement = value;
331 | }
332 |
333 |
334 | /**
335 | * @private
336 | */
337 | internal function setTable(tableName:String):void
338 | {
339 | _tableName = tableName;
340 | if(_tableName.indexOf("[") < 0)
341 | {
342 | _tableName = "[" + _tableName + "]";
343 | }
344 | }
345 |
346 |
347 | /**
348 | * @private
349 | */
350 | internal function get query():String
351 | {
352 | var result:String = "";
353 | if(_columns.length > 0)
354 | {
355 | if(_statement == CREATE)
356 | {
357 | result = (_statement == CREATE) ? "CREATE TABLE IF NOT EXISTS " + _tableName + " (" : "";
358 | }
359 |
360 | var primaryKeys:Vector.IColumnConstraint
allowing to chain additional constraints.
63 | */
64 | public function autoIncrement():IColumnConstraint
65 | {
66 | _autoIncrement = true;
67 | return this;
68 | }
69 |
70 |
71 | /**
72 | * @inheritDoc
73 | */
74 | public function notNull():IColumnConstraint
75 | {
76 | _notNull = true;
77 | return this;
78 | }
79 |
80 |
81 | /**
82 | * @inheritDoc
83 | * @return
84 | */
85 | public function defaultTo(value:*):IColumnConstraint
86 | {
87 | _defaultTo = value;
88 | _defaultNull = false;
89 | return this;
90 | }
91 |
92 |
93 | /**
94 | * @inheritDoc
95 | */
96 | public function defaultNull():IColumnConstraint
97 | {
98 | _defaultNull = true;
99 | _defaultTo = null;
100 | return this;
101 | }
102 |
103 |
104 | /**
105 | * @inheritDoc
106 | */
107 | public function unique():IColumnConstraint
108 | {
109 | _unique = true;
110 | return this;
111 | }
112 |
113 |
114 | /**
115 | * @inheritDoc
116 | */
117 | public function primary():IColumnConstraint
118 | {
119 | if(!_creationMode)
120 | {
121 | throw new IllegalOperationError("Primary key cannot be changed after the table is created.");
122 | }
123 |
124 | _primaryKey = true;
125 | return this;
126 | }
127 |
128 |
129 | /**
130 | * @private
131 | */
132 | internal function get isPrimaryKey():Boolean
133 | {
134 | return _primaryKey;
135 | }
136 |
137 |
138 | /**
139 | * @private
140 | */
141 | internal function get name():String
142 | {
143 | return _name;
144 | }
145 |
146 |
147 | /**
148 | * @private
149 | * @param includePrimaryKey If the column is designated as primary key and this parameter is true
150 | * then the result text will contain PRIMARY KEY. The parameter should be false in cases
151 | * when there are multiple primary keys, which requires different SQL syntax.
152 | */
153 | internal function getSQLText(includePrimaryKey:Boolean):String
154 | {
155 | var result:String = _name + " " + ColumnDataType.toString(_dataType);
156 |
157 | if(_primaryKey && includePrimaryKey)
158 | {
159 | result += " PRIMARY KEY";
160 | }
161 |
162 | if(_autoIncrement)
163 | {
164 | result += " AUTOINCREMENT";
165 | }
166 |
167 | if(_notNull)
168 | {
169 | result += " NOT NULL";
170 | }
171 |
172 | if(_unique)
173 | {
174 | result += " UNIQUE";
175 | }
176 |
177 | if(_defaultNull)
178 | {
179 | result += " DEFAULT (NULL)";
180 | }
181 | else if(_defaultTo !== null)
182 | {
183 | result += " DEFAULT (" + defaultValue + ")";
184 | }
185 | return result;
186 | }
187 |
188 |
189 | private function get defaultValue():*
190 | {
191 | if(_defaultTo is String)
192 | {
193 | return "'" + _defaultTo + "'";
194 | }
195 | return _defaultTo;
196 | }
197 | }
198 |
199 | }
200 |
--------------------------------------------------------------------------------
/src/breezedb/schemas/breezedb_internal.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.schemas
27 | {
28 |
29 | internal namespace breezedb_internal = "https://getbreeze.io/breezedb";
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/breezedb/utils/Callback.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.utils
27 | {
28 |
29 | /**
30 | * @private
31 | */
32 | public class Callback
33 | {
34 |
35 | public static function call(fn:Function, args:Array):Boolean
36 | {
37 | if(fn == null)
38 | {
39 | return false;
40 | }
41 |
42 | var numArgs:int = fn.length;
43 | for(var i:int = args.length; i < numArgs; ++i)
44 | {
45 | args[i] = null;
46 | }
47 |
48 | // There are less than 3 arguments most of the time,
49 | // so we call the method directly to avoid the 'slice' allocations
50 |
51 | switch(numArgs)
52 | {
53 | case 0:
54 | fn();
55 | break;
56 | case 1:
57 | fn(args[0]);
58 | break;
59 | case 2:
60 | fn(args[0], args[1]);
61 | break;
62 | case 3:
63 | fn(args[0], args[1], args[2]);
64 | break;
65 | default:
66 | fn.apply(null, args.slice(0, numArgs));
67 | break;
68 | }
69 |
70 | return true;
71 | }
72 |
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/breezedb/utils/GarbagePrevention.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2017 Digital Strawberry LLC
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | */
25 |
26 | package breezedb.utils
27 | {
28 |
29 | /**
30 | * Utility class that prevents garbage collection on objects until told to delete them.
31 | * @private
32 | */
33 | public class GarbagePrevention
34 | {
35 | private static var _instance:GarbagePrevention;
36 |
37 | private var _objects:Array = [];
38 |
39 |
40 | public function GarbagePrevention()
41 | {
42 | if(!_instance)
43 | {
44 | _instance = this;
45 | }
46 | else
47 | {
48 | throw new Error('GarbagePrevention is a singleton.');
49 | }
50 | }
51 |
52 |
53 | public function add(object:*):void
54 | {
55 | _objects.push(object);
56 | }
57 |
58 |
59 | public function addOnce(object:*):void
60 | {
61 | if(!contains(object))
62 | {
63 | add(object);
64 | }
65 | }
66 |
67 |
68 | public function remove(object:*):Boolean
69 | {
70 | var index:int = _objects.indexOf(object);
71 | if(index > -1)
72 | {
73 | _objects.removeAt(index);
74 | return true;
75 | }
76 |
77 | return false;
78 | }
79 |
80 |
81 | public function removeAll():void
82 | {
83 | _objects.length = 0;
84 | }
85 |
86 |
87 | public function contains(object:*):Boolean
88 | {
89 | return _objects.indexOf(object) > -1;
90 | }
91 |
92 |
93 | public static function get instance():GarbagePrevention
94 | {
95 | return _instance ? _instance : new GarbagePrevention();
96 | }
97 |
98 | }
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/src/org/kuwamoto/Inflect.as:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) kuwamoto.org
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | *
24 | * http://kuwamoto.org/2007/12/17/improved-pluralizing-in-php-actionscript-and-ror/
25 | *
26 | */
27 |
28 | package org.kuwamoto
29 | {
30 | public class Inflect
31 | {
32 | private static var plural:Array = [
33 | [/(quiz)$/i, "$1zes"],
34 | [/^(ox)$/i, "$1en"],
35 | [/([m|l])ouse$/i, "$1ice"],
36 | [/(matr|vert|ind)ix|ex$/i, "$1ices"],
37 | [/(x|ch|ss|sh)$/i, "$1es"],
38 | [/([^aeiouy]|qu)y$/i, "$1ies"],
39 | [/(hive)$/i, "$1s"],
40 | [/(?:([^f])fe|([lr])f)$/i, "$1$2ves"],
41 | [/(shea|lea|loa|thie)f$/i, "$1ves"],
42 | [/sis$/i, "ses"],
43 | [/([ti])um$/i, "$1a"],
44 | [/(tomat|potat|ech|her|vet)o$/i, "$1oes"],
45 | [/(bu)s$/i, "$1ses"],
46 | [/(alias|status)$/i, "$1es"],
47 | [/(octop)us$/i, "$1i"],
48 | [/(ax|test)is$/i, "$1es"],
49 | [/(us)$/i, "$1es"],
50 | [/s$/i, "s"],
51 | [/$/i, "s"]
52 | ];
53 |
54 | private static var irregular:Array = [
55 | ['move', 'moves'],
56 | ['foot', 'feet'],
57 | ['goose', 'geese'],
58 | ['sex', 'sexes'],
59 | ['child', 'children'],
60 | ['man', 'men'],
61 | ['tooth', 'teeth'],
62 | ['person', 'people']
63 | ];
64 |
65 | private static var uncountable:Array = [
66 | 'sheep',
67 | 'fish',
68 | 'deer',
69 | 'series',
70 | 'species',
71 | 'money',
72 | 'rice',
73 | 'information',
74 | 'equipment'
75 | ];
76 |
77 |
78 | public static function pluralize(string:String):String
79 | {
80 | var pattern:RegExp;
81 | var result:String;
82 |
83 | // save some time in the case that singular and plural are the same
84 | if(uncountable.indexOf(string.toLowerCase()) != -1)
85 | {
86 | return string;
87 | }
88 |
89 | // check for irregular singular forms
90 | var item:Array;
91 | for each (item in irregular)
92 | {
93 | pattern = new RegExp(item[0] + "$", "i");
94 | result = item[1];
95 |
96 | if(pattern.test(string))
97 | {
98 | return string.replace(pattern, result);
99 | }
100 | }
101 |
102 | // check for matches using regular expressions
103 | for each (item in plural)
104 | {
105 | pattern = item[0];
106 | result = item[1];
107 |
108 | if(pattern.test(string))
109 | {
110 | return string.replace(pattern, result);
111 | }
112 | }
113 |
114 | return string;
115 | }
116 |
117 | }
118 | }
--------------------------------------------------------------------------------
/test/application.xml:
--------------------------------------------------------------------------------
1 |
2 |