Skip to content

Commit ff6727c

Browse files
jsayolJosep Sayol
authored and
Josep Sayol
committed
Merge remote-tracking branch 'upstream/database-ts' into db-classes
2 parents 9de1549 + bd03a98 commit ff6727c

20 files changed

+129
-113
lines changed

src/database.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ import { Query } from "./database/api/Query";
2121
import { Reference } from "./database/api/Reference";
2222
import { enableLogging } from "./database/core/util/util";
2323
import { RepoManager } from "./database/core/RepoManager";
24+
import * as INTERNAL from './database/api/internal';
25+
import * as TEST_ACCESS from './database/api/test_access';
2426

2527
export function registerDatabase(instance) {
2628
// Register the Database Service with the 'firebase' namespace.
27-
firebase.INTERNAL.registerService(
29+
instance.INTERNAL.registerService(
2830
'database',
2931
app => RepoManager.getInstance().databaseFromApp(app),
3032
// firebase.database namespace properties
@@ -33,7 +35,9 @@ export function registerDatabase(instance) {
3335
Query,
3436
Database,
3537
enableLogging,
38+
INTERNAL,
3639
ServerValue: Database.ServerValue,
40+
TEST_ACCESS
3741
}
3842
);
3943
}

src/database/api/Database.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,9 @@ export class Database {
1919
root_;
2020
INTERNAL;
2121

22-
static get ServerValue() {
23-
return {
24-
'TIMESTAMP': {
25-
'.sv' : 'timestamp'
26-
}
22+
static ServerValue = {
23+
'TIMESTAMP': {
24+
'.sv' : 'timestamp'
2725
}
2826
}
2927

src/database/core/CompoundWrite.ts

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ImmutableTree } from "./util/ImmutableTree";
22
import { Path } from "./util/Path";
33
import { forEach } from "../../utils/obj";
4-
import { NamedNode } from "./snap/Node";
4+
import { Node, NamedNode } from "./snap/Node";
55
import { PRIORITY_INDEX } from "./snap/indexes/PriorityIndex";
66
import { assert } from "../../utils/assert";
77

@@ -15,32 +15,25 @@ import { assert } from "../../utils/assert";
1515
* @param {!ImmutableTree.<!Node>} writeTree
1616
*/
1717
export class CompoundWrite {
18-
writeTree_;
19-
constructor(writeTree) {
20-
/**
21-
* @type {!ImmutableTree.<!Node>}
22-
* @private
23-
*/
24-
this.writeTree_ = writeTree;
25-
};
18+
constructor(private writeTree_: ImmutableTree) {};
2619
/**
2720
* @type {!CompoundWrite}
2821
*/
29-
static Empty = new CompoundWrite(
30-
/** @type {!ImmutableTree.<!Node>} */ (new ImmutableTree(null))
31-
);
22+
static Empty = new CompoundWrite(new ImmutableTree(null));
23+
3224
/**
3325
* @param {!Path} path
3426
* @param {!Node} node
3527
* @return {!CompoundWrite}
3628
*/
37-
addWrite(path, node) {
29+
addWrite(path: Path, node: Node): CompoundWrite {
3830
if (path.isEmpty()) {
3931
return new CompoundWrite(new ImmutableTree(node));
4032
} else {
4133
var rootmost = this.writeTree_.findRootMostValueAndPath(path);
4234
if (rootmost != null) {
43-
var rootMostPath = rootmost.path, value = rootmost.value;
35+
var rootMostPath = rootmost.path
36+
var value = rootmost.value;
4437
var relativePath = Path.relativePath(rootMostPath, path);
4538
value = value.updateChild(relativePath, node);
4639
return new CompoundWrite(this.writeTree_.set(rootMostPath, value));
@@ -57,8 +50,8 @@ export class CompoundWrite {
5750
* @param {!Object.<string, !Node>} updates
5851
* @return {!CompoundWrite}
5952
*/
60-
addWrites(path, updates) {
61-
var newWrite = <any>this;
53+
addWrites(path: Path, updates: { [name: string]: Node }): CompoundWrite {
54+
var newWrite = <CompoundWrite>this;
6255
forEach(updates, function(childKey, node) {
6356
newWrite = newWrite.addWrite(path.child(childKey), node);
6457
});
@@ -72,7 +65,7 @@ export class CompoundWrite {
7265
* @param {!Path} path The path at which a write and all deeper writes should be removed
7366
* @return {!CompoundWrite} The new CompoundWrite with the removed path
7467
*/
75-
removeWrite(path) {
68+
removeWrite(path: Path): CompoundWrite {
7669
if (path.isEmpty()) {
7770
return CompoundWrite.Empty;
7871
} else {
@@ -88,7 +81,7 @@ export class CompoundWrite {
8881
* @param {!Path} path The path to check for
8982
* @return {boolean} Whether there is a complete write at that path
9083
*/
91-
hasCompleteWrite(path) {
84+
hasCompleteWrite(path: Path): boolean {
9285
return this.getCompleteNode(path) != null;
9386
};
9487

@@ -99,11 +92,10 @@ export class CompoundWrite {
9992
* @param {!Path} path The path to get a complete write
10093
* @return {?Node} The node if complete at that path, or null otherwise.
10194
*/
102-
getCompleteNode(path) {
95+
getCompleteNode(path: Path): Node {
10396
var rootmost = this.writeTree_.findRootMostValueAndPath(path);
10497
if (rootmost != null) {
105-
return this.writeTree_.get(rootmost.path).getChild(
106-
Path.relativePath(rootmost.path, path));
98+
return this.writeTree_.get(rootmost.path).getChild(Path.relativePath(rootmost.path, path));
10799
} else {
108100
return null;
109101
}
@@ -114,7 +106,7 @@ export class CompoundWrite {
114106
*
115107
* @return {!Array.<NamedNode>} A list of all complete children.
116108
*/
117-
getCompleteChildren() {
109+
getCompleteChildren(): Array<NamedNode> {
118110
var children = [];
119111
var node = this.writeTree_.value;
120112
if (node != null) {
@@ -139,7 +131,7 @@ export class CompoundWrite {
139131
* @param {!Path} path
140132
* @return {!CompoundWrite}
141133
*/
142-
childCompoundWrite(path) {
134+
childCompoundWrite(path: Path) {
143135
if (path.isEmpty()) {
144136
return this;
145137
} else {
@@ -166,7 +158,7 @@ export class CompoundWrite {
166158
* @param {!Node} node The node to apply this CompoundWrite to
167159
* @return {!Node} The node with all writes applied
168160
*/
169-
apply(node) {
161+
apply(node: Node) {
170162
return CompoundWrite.applySubtreeWrite_(Path.Empty, this.writeTree_, node);
171163
};
172164

@@ -177,7 +169,7 @@ export class CompoundWrite {
177169
* @return {!Node}
178170
* @private
179171
*/
180-
static applySubtreeWrite_ = function(relativePath, writeTree, node) {
172+
static applySubtreeWrite_ = function(relativePath: Path, writeTree: ImmutableTree, node: Node) {
181173
if (writeTree.value != null) {
182174
// Since there a write is always a leaf, we're done here
183175
return node.updateChild(relativePath, writeTree.value);
@@ -195,8 +187,7 @@ export class CompoundWrite {
195187
});
196188
// If there was a priority write, we only apply it if the node is not empty
197189
if (!node.getChild(relativePath).isEmpty() && priorityWrite !== null) {
198-
node = node.updateChild(relativePath.child('.priority'),
199-
/** @type {!Node} */ (priorityWrite));
190+
node = node.updateChild(relativePath.child('.priority'), priorityWrite);
200191
}
201192
return node;
202193
}

src/database/core/PersistentConnection.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import firebase from "../../app";
2-
import { forEach, contains, isEmpty, getCount } from "../../utils/obj";
2+
import { forEach, contains, isEmpty, getCount, safeGet } from "../../utils/obj";
33
import { stringify } from "../../utils/json";
44
import { assert } from '../../utils/assert';
55
import { error, log, logWrapper, warn, ObjectToUniqueKey } from "./util/util";
@@ -243,7 +243,7 @@ export class PersistentConnection {
243243
*/
244244
warnOnListenWarnings_(payload, query) {
245245
if (payload && typeof payload === 'object' && contains(payload, 'w')) {
246-
var warnings = payload['w'];
246+
var warnings = safeGet(payload, 'w');
247247
if (Array.isArray(warnings) && ~warnings.indexOf('no_index')) {
248248
var indexSpec = '".indexOn": "' + query.getQueryParams().getIndex().toString() + '"';
249249
var indexPath = query.path.toString();

src/database/core/ReadonlyRestClient.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { assert } from "../../utils/assert";
22
import { logWrapper, warn } from "./util/util";
33
import { jsonEval } from "../../utils/json";
4+
import { safeGet } from "../../utils/obj";
45
import { querystring } from "../../utils/util";
56

67
/**
@@ -35,9 +36,9 @@ export class ReadonlyRestClient {
3536
* @return {string}
3637
* @private
3738
*/
38-
static getListenId_(query, opt_tag) {
39-
if (opt_tag !== undefined) {
40-
return 'tag$' + opt_tag;
39+
static getListenId_(query, tag?) {
40+
if (tag !== undefined) {
41+
return 'tag$' + tag;
4142
} else {
4243
assert(query.getQueryParams().isDefault(), "should have a tag if it's not a default query.");
4344
return query.path.toString();
@@ -81,7 +82,7 @@ export class ReadonlyRestClient {
8182
self.onDataUpdate_(pathString, data, /*isMerge=*/false, tag);
8283
}
8384

84-
if (self.listens_[listenId] === thisListen) {
85+
if (safeGet(self.listens_, listenId) === thisListen) {
8586
var status;
8687
if (!error) {
8788
status = 'ok';

src/database/core/RepoManager.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { FirebaseApp } from "../../app/firebase_app";
2+
import { safeGet } from "../../utils/obj";
23
import { Repo } from "./Repo";
34
import { fatal } from "./util/util";
45
import { parseRepoInfo } from "./util/libs/parser";
@@ -8,28 +9,30 @@ import "./Repo_transaction";
89
/** @const {string} */
910
var DATABASE_URL_OPTION = 'databaseURL';
1011

12+
let _staticInstance;
13+
1114
/**
1215
* Creates and caches Repo instances.
1316
*/
1417
export class RepoManager {
1518
/**
1619
* @private {!Object.<string, !Repo>}
1720
*/
18-
private repos_;
21+
private repos_: {
22+
[name: string]: Repo
23+
} = {};
1924

2025
/**
2126
* If true, new Repos will be created to use ReadonlyRestClient (for testing purposes).
2227
* @private {boolean}
2328
*/
24-
private useRestClient_;
29+
private useRestClient_: boolean = false;
2530

2631
static getInstance() {
27-
return new RepoManager();
28-
}
29-
30-
constructor() {
31-
this.repos_ = { };
32-
this.useRestClient_ = false;
32+
if (!_staticInstance) {
33+
_staticInstance = new RepoManager();
34+
}
35+
return _staticInstance;
3336
}
3437

3538
// TODO(koss): Remove these functions unless used in tests?
@@ -79,8 +82,9 @@ export class RepoManager {
7982
* @param {!Repo} repo
8083
*/
8184
deleteRepo(repo) {
85+
8286
// This should never happen...
83-
if (this.repos_[repo.app.name] !== repo) {
87+
if (safeGet(this.repos_, repo.app.name) !== repo) {
8488
fatal("Database " + repo.app.name + " has already been deleted.");
8589
}
8690
repo.interrupt();
@@ -96,7 +100,7 @@ export class RepoManager {
96100
* @return {!Repo} The Repo object for the specified server / repoName.
97101
*/
98102
createRepo(repoInfo, app: FirebaseApp): Repo {
99-
var repo = this.repos_[app.name];
103+
var repo = safeGet(this.repos_, app.name);
100104
if (repo) {
101105
fatal('FIREBASE INTERNAL ERROR: Database initialized multiple times.');
102106
}

0 commit comments

Comments
 (0)