Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 1x 4x 4x 4x 4x 4x 4x 1x 3x 3x 3x 1x 2x 2x 9x 2x 1x 1x 1x | /*! * VisualEditor document store class. * * @copyright See AUTHORS.txt */ 'use strict'; /** * @constructor * @param {Object} storageClient MongoClient-like object; passed as a parameter for testing purposes * @param {string} dbName Database name * @param {Object} logger Logger class * @param {Function} logger.logServerEvent Stringify object argument to log, adding timestamp and server ID properties */ ve.dm.DocumentStore = function VeDmDocumentStore( storageClient, dbName, logger ) { this.storageClient = storageClient; this.dbName = dbName; this.logger = logger; this.db = null; this.collection = null; this.startForDoc = new Map(); this.serverId = null; }; /** * @return {Promise} Resolves when connected */ ve.dm.DocumentStore.prototype.connect = function () { const documentStore = this; return this.storageClient.connect().then( ( client ) => { const db = client.db( documentStore.dbName ); documentStore.logger.logServerEvent( { type: 'DocumentStore#connected', dbName: documentStore.dbName }, 'info' ); documentStore.db = db; documentStore.collection = db.collection( 'vedocstore' ); return documentStore.collection.findOneAndUpdate( { config: 'options' }, { $setOnInsert: { serverId: Math.random().toString( 36 ).slice( 2 ) } }, { upsert: true, returnDocument: 'after' } ); } ).then( ( result ) => { documentStore.serverId = result.value.serverId; } ); }; /** * @return {Promise} Drops the entire database */ ve.dm.DocumentStore.prototype.dropDatabase = function () { this.logger.logServerEvent( { type: 'DocumentStore#dropDatabase', dbName: this.dbName }, 'info' ); return this.db.dropDatabase(); }; /** * Load a document from storage (creating as empty if absent) * * @param {string} docName Name of the document * @return {Promise} Confirmed document history as a ve.dm.Change */ ve.dm.DocumentStore.prototype.load = function ( docName ) { const documentStore = this; return this.collection.findOneAndUpdate( { docName: docName }, { $setOnInsert: { start: 0, transactions: [], stores: [] } }, { upsert: true, returnDocument: 'after' } ).then( ( result ) => { const length = result.value.transactions.length || 0; documentStore.logger.logServerEvent( { type: 'DocumentStore#loaded', docName: docName, length: length } ); documentStore.startForDoc.set( docName, result.value.start + length ); return ve.dm.Change.static.deserialize( { start: 0, transactions: result.value.transactions, stores: result.value.stores, selections: {} }, true ); } ); }; /** * Save a new change to storage * * @param {string} docName Name of the document * @param {ve.dm.Change} change The new change * @return {Promise} Resolves when saved */ ve.dm.DocumentStore.prototype.onNewChange = function ( docName, change ) { const serializedChange = change.serialize( true ), expectedStart = this.startForDoc.get( docName ) || 0; if ( expectedStart !== serializedChange.start ) { return Promise.reject( 'Unmatched starts:', expectedStart, serializedChange.start ); } this.startForDoc.set( docName, serializedChange.start + serializedChange.transactions.length ); return this.collection.updateOne( { docName: docName }, { $push: { transactions: { $each: serializedChange.transactions }, stores: { $each: serializedChange.stores || serializedChange.transactions.map( () => null ) } } } ).then( () => { this.logger.logServerEvent( { type: 'DocumentStore#onNewChange', docName: docName, start: serializedChange.start, length: serializedChange.transactions.length } ); } ); }; ve.dm.DocumentStore.prototype.onClose = function () { this.logger.logServerEvent( { type: 'DocumentStore#onClose' }, 'info' ); this.storageClient.close(); }; |