From 1eb3d60457d4fc0ae957832c3ab751b54a24cc21 Mon Sep 17 00:00:00 2001 From: ab Date: Sat, 9 Feb 2019 17:28:27 -0500 Subject: database --- src/Main.tsx | 3 +++ src/Server.ts | 61 ++++++++++++++++++++++++++++++++++++++++++ src/Server.tsx | 61 ------------------------------------------ src/SocketStub.ts | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/SocketStub.tsx | 78 ------------------------------------------------------ src/database.ts | 41 ++++++++++++++++++++++++++++ 6 files changed, 183 insertions(+), 139 deletions(-) create mode 100644 src/Server.ts delete mode 100644 src/Server.tsx create mode 100644 src/SocketStub.ts delete mode 100644 src/SocketStub.tsx create mode 100644 src/database.ts (limited to 'src') diff --git a/src/Main.tsx b/src/Main.tsx index fa6230393..eee8554f3 100644 --- a/src/Main.tsx +++ b/src/Main.tsx @@ -14,6 +14,7 @@ import { ContextMenu } from './views/ContextMenu'; import { DocumentView } from './views/nodes/DocumentView'; import { CompileScript } from './util/Scripting'; import { ImageField } from './fields/ImageField'; +import { database } from './database'; configure({ @@ -40,6 +41,8 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { //runInAction(() => { + let db = new database(); + db.update('1', '2', '3'); let doc1 = Documents.TextDocument({ title: "hello" }); let doc2 = doc1.MakeDelegate(); doc2.Set(KS.X, new NumberField(150)); diff --git a/src/Server.ts b/src/Server.ts new file mode 100644 index 000000000..645420771 --- /dev/null +++ b/src/Server.ts @@ -0,0 +1,61 @@ +import { Field, FieldWaiting, FIELD_ID, FIELD_WAITING, FieldValue } from "./fields/Field" +import { Key, KeyStore } from "./fields/Key" +import { ObservableMap, action } from "mobx"; +import { Document } from "./fields/Document" +import { SocketStub } from "./SocketStub"; + +export class Server { + private static ClientFieldsCached: ObservableMap = new ObservableMap(); + + // Retrieves the cached value of the field and sends a request to the server for the real value (if it's not cached). + // Call this is from within a reaction and test whether the return value is FieldWaiting. + // 'hackTimeout' is here temporarily for simplicity when debugging things. + public static GetField(fieldid: FIELD_ID, callback: (field: Field) => void = (f) => { }, hackTimeout: number = -1) { + if (!this.ClientFieldsCached.get(fieldid)) { + this.ClientFieldsCached.set(fieldid, FieldWaiting); + //simulating a server call with a registered callback action + SocketStub.SEND_FIELD_REQUEST(fieldid, + action((field: Field) => callback(Server.cacheField(field))), + hackTimeout); + } else if (this.ClientFieldsCached.get(fieldid) != FieldWaiting) { + callback(this.ClientFieldsCached.get(fieldid) as Field); + } + return this.ClientFieldsCached.get(fieldid); + } + + static times = 0; // hack for testing + public static GetDocumentField(doc: Document, key: Key) { + var hackTimeout: number = key == KeyStore.Data ? (this.times++ == 0 ? 5000 : 1000) : key == KeyStore.X ? 2500 : 500; + + return this.GetField(doc._proxies.get(key), + action((fieldfromserver: Field) => { + doc._proxies.delete(key); + doc.fields.set(key, fieldfromserver); + }) + , hackTimeout); + } + + public static AddDocument(document: Document) { + SocketStub.SEND_ADD_DOCUMENT(document); + } + public static AddDocumentField(doc: Document, key: Key, value: Field) { + SocketStub.SEND_ADD_DOCUMENT_FIELD(doc, key, value); + } + public static DeleteDocumentField(doc: Document, key: Key) { + SocketStub.SEND_DELETE_DOCUMENT_FIELD(doc, key); + } + public static SetFieldValue(field: Field, value: any) { + SocketStub.SEND_SET_FIELD(field, value); + } + + @action + private static cacheField(clientField: Field) { + var cached = this.ClientFieldsCached.get(clientField.Id); + if (!cached || cached == FieldWaiting) { + this.ClientFieldsCached.set(clientField.Id, clientField); + } else { + // probably should overwrite the values within any field that was already here... + } + return this.ClientFieldsCached.get(clientField.Id) as Field; + } +} diff --git a/src/Server.tsx b/src/Server.tsx deleted file mode 100644 index 645420771..000000000 --- a/src/Server.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { Field, FieldWaiting, FIELD_ID, FIELD_WAITING, FieldValue } from "./fields/Field" -import { Key, KeyStore } from "./fields/Key" -import { ObservableMap, action } from "mobx"; -import { Document } from "./fields/Document" -import { SocketStub } from "./SocketStub"; - -export class Server { - private static ClientFieldsCached: ObservableMap = new ObservableMap(); - - // Retrieves the cached value of the field and sends a request to the server for the real value (if it's not cached). - // Call this is from within a reaction and test whether the return value is FieldWaiting. - // 'hackTimeout' is here temporarily for simplicity when debugging things. - public static GetField(fieldid: FIELD_ID, callback: (field: Field) => void = (f) => { }, hackTimeout: number = -1) { - if (!this.ClientFieldsCached.get(fieldid)) { - this.ClientFieldsCached.set(fieldid, FieldWaiting); - //simulating a server call with a registered callback action - SocketStub.SEND_FIELD_REQUEST(fieldid, - action((field: Field) => callback(Server.cacheField(field))), - hackTimeout); - } else if (this.ClientFieldsCached.get(fieldid) != FieldWaiting) { - callback(this.ClientFieldsCached.get(fieldid) as Field); - } - return this.ClientFieldsCached.get(fieldid); - } - - static times = 0; // hack for testing - public static GetDocumentField(doc: Document, key: Key) { - var hackTimeout: number = key == KeyStore.Data ? (this.times++ == 0 ? 5000 : 1000) : key == KeyStore.X ? 2500 : 500; - - return this.GetField(doc._proxies.get(key), - action((fieldfromserver: Field) => { - doc._proxies.delete(key); - doc.fields.set(key, fieldfromserver); - }) - , hackTimeout); - } - - public static AddDocument(document: Document) { - SocketStub.SEND_ADD_DOCUMENT(document); - } - public static AddDocumentField(doc: Document, key: Key, value: Field) { - SocketStub.SEND_ADD_DOCUMENT_FIELD(doc, key, value); - } - public static DeleteDocumentField(doc: Document, key: Key) { - SocketStub.SEND_DELETE_DOCUMENT_FIELD(doc, key); - } - public static SetFieldValue(field: Field, value: any) { - SocketStub.SEND_SET_FIELD(field, value); - } - - @action - private static cacheField(clientField: Field) { - var cached = this.ClientFieldsCached.get(clientField.Id); - if (!cached || cached == FieldWaiting) { - this.ClientFieldsCached.set(clientField.Id, clientField); - } else { - // probably should overwrite the values within any field that was already here... - } - return this.ClientFieldsCached.get(clientField.Id) as Field; - } -} diff --git a/src/SocketStub.ts b/src/SocketStub.ts new file mode 100644 index 000000000..f9d48c067 --- /dev/null +++ b/src/SocketStub.ts @@ -0,0 +1,78 @@ +import { Field, FIELD_ID } from "./fields/Field" +import { Key, KeyStore } from "./fields/Key" +import { ObservableMap, action } from "mobx"; +import { Document } from "./fields/Document" + +export class SocketStub { + + static FieldStore: ObservableMap = new ObservableMap(); + public static SEND_ADD_DOCUMENT(document: Document) { + + // Send a serialized version of the document to the server + // ...SOCKET(ADD_DOCUMENT, serialied document) + + // server stores each document field in its repository of stored fields + document.fields.forEach((f, key) => this.FieldStore.set((f as Field).Id, f as Field)); + + // server stores stripped down document (w/ only field id proxies) in the field store + this.FieldStore.set(document.Id, new Document(document.Id)); + document.fields.forEach((f, key) => (this.FieldStore.get(document.Id) as Document)._proxies.set(key, (f as Field).Id)); + } + + public static SEND_FIELD_REQUEST(fieldid: FIELD_ID, callback: (field: Field) => void, timeout: number) { + + if (timeout < 0)// this is a hack to make things easier to setup until we have a server... won't be neededa fter that. + callback(this.FieldStore.get(fieldid) as Field); + else { // actual logic here... + + // Send a request for fieldid to the server + // ...SOCKET(RETRIEVE_FIELD, fieldid) + + // server responds (simulated with a timeout) and the callback is invoked + setTimeout(() => + + // when the field data comes back, call the callback() function + callback(this.FieldStore.get(fieldid) as Field), + + + timeout); + } + } + + public static SEND_ADD_DOCUMENT_FIELD(doc: Document, key: Key, value: Field) { + + // Send a serialized version of the field to the server along with the + // associated info of the document id and key where it is used. + + // ...SOCKET(ADD_DOCUMENT_FIELD, document id, key id, serialized field) + + // server updates its document to hold a proxy mapping from key => fieldId + var document = this.FieldStore.get(doc.Id) as Document; + if (document) + document._proxies.set(key, value.Id); + + // server adds the field to its repository of fields + this.FieldStore.set(value.Id, value); + } + + public static SEND_DELETE_DOCUMENT_FIELD(doc: Document, key: Key) { + // Send a request to delete the field stored under the specified key from the document + + // ...SOCKET(DELETE_DOCUMENT_FIELD, document id, key id) + + // Server removes the field id from the document's list of field proxies + var document = this.FieldStore.get(doc.Id) as Document; + if (document) + document._proxies.delete(key); + } + + public static SEND_SET_FIELD(field: Field, value: any) { + // Send a request to set the value of a field + + // ...SOCKET(SET_FIELD, field id, serialized field value) + + // Server updates the value of the field in its fieldstore + if (this.FieldStore.get(field.Id)) + this.FieldStore.get(field.Id)!.TrySetValue(value); + } +} diff --git a/src/SocketStub.tsx b/src/SocketStub.tsx deleted file mode 100644 index f9d48c067..000000000 --- a/src/SocketStub.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { Field, FIELD_ID } from "./fields/Field" -import { Key, KeyStore } from "./fields/Key" -import { ObservableMap, action } from "mobx"; -import { Document } from "./fields/Document" - -export class SocketStub { - - static FieldStore: ObservableMap = new ObservableMap(); - public static SEND_ADD_DOCUMENT(document: Document) { - - // Send a serialized version of the document to the server - // ...SOCKET(ADD_DOCUMENT, serialied document) - - // server stores each document field in its repository of stored fields - document.fields.forEach((f, key) => this.FieldStore.set((f as Field).Id, f as Field)); - - // server stores stripped down document (w/ only field id proxies) in the field store - this.FieldStore.set(document.Id, new Document(document.Id)); - document.fields.forEach((f, key) => (this.FieldStore.get(document.Id) as Document)._proxies.set(key, (f as Field).Id)); - } - - public static SEND_FIELD_REQUEST(fieldid: FIELD_ID, callback: (field: Field) => void, timeout: number) { - - if (timeout < 0)// this is a hack to make things easier to setup until we have a server... won't be neededa fter that. - callback(this.FieldStore.get(fieldid) as Field); - else { // actual logic here... - - // Send a request for fieldid to the server - // ...SOCKET(RETRIEVE_FIELD, fieldid) - - // server responds (simulated with a timeout) and the callback is invoked - setTimeout(() => - - // when the field data comes back, call the callback() function - callback(this.FieldStore.get(fieldid) as Field), - - - timeout); - } - } - - public static SEND_ADD_DOCUMENT_FIELD(doc: Document, key: Key, value: Field) { - - // Send a serialized version of the field to the server along with the - // associated info of the document id and key where it is used. - - // ...SOCKET(ADD_DOCUMENT_FIELD, document id, key id, serialized field) - - // server updates its document to hold a proxy mapping from key => fieldId - var document = this.FieldStore.get(doc.Id) as Document; - if (document) - document._proxies.set(key, value.Id); - - // server adds the field to its repository of fields - this.FieldStore.set(value.Id, value); - } - - public static SEND_DELETE_DOCUMENT_FIELD(doc: Document, key: Key) { - // Send a request to delete the field stored under the specified key from the document - - // ...SOCKET(DELETE_DOCUMENT_FIELD, document id, key id) - - // Server removes the field id from the document's list of field proxies - var document = this.FieldStore.get(doc.Id) as Document; - if (document) - document._proxies.delete(key); - } - - public static SEND_SET_FIELD(field: Field, value: any) { - // Send a request to set the value of a field - - // ...SOCKET(SET_FIELD, field id, serialized field value) - - // Server updates the value of the field in its fieldstore - if (this.FieldStore.get(field.Id)) - this.FieldStore.get(field.Id)!.TrySetValue(value); - } -} diff --git a/src/database.ts b/src/database.ts new file mode 100644 index 000000000..a822b15bf --- /dev/null +++ b/src/database.ts @@ -0,0 +1,41 @@ +import { action, configure } from 'mobx'; +import * as mongodb from 'mongodb'; + +export class database { + private MongoClient = mongodb.MongoClient; + private url = 'mongodb://localhost:27017/website'; + + public update(id: string, field: string, value: string) { + this.MongoClient.connect(this.url, (err, db) => { + let collection = db.db().collection('documents'); + collection.update({ "id": id }, { $set: { field: value } }); + db.close(); + }); + } + + public delete(id: string) { + this.MongoClient.connect(this.url, (err, db) => { + let collection = db.db().collection('documents'); + collection.remove({ "id": id }); + db.close(); + }); + } + + public insert(kvpairs: JSON) { + this.MongoClient.connect(this.url, (err, db) => { + let collection = db.db().collection('documents'); + collection.insert(kvpairs, () => { }); + db.close(); + }); + } + + public getDocument(id: string) { + var result: Array; + this.MongoClient.connect(this.url, (err, db) => { + let collection = db.db().collection('documents'); + collection.find({ "id": id }).toArray((err, db) => { result = db }); + db.close(); + return result[0]; + }); + } +} -- cgit v1.2.3-70-g09d2