| // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| // use this file except in compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| // License for the specific language governing permissions and limitations under |
| // the License. |
| |
| import app from "../../../app"; |
| import {post, get} from '../../../core/ajax'; |
| import FauxtonAPI from "../../../core/api"; |
| import Constants from '../constants'; |
| |
| export const fetchQueryExplain = (databaseName, queryCode) => { |
| const url = FauxtonAPI.urls('mango', 'explain-server', encodeURIComponent(databaseName)); |
| |
| return post(url, queryCode, {rawBody: true}).then((json) => { |
| if (json.error) { |
| throw new Error('(' + json.error + ') ' + json.reason); |
| } |
| return json; |
| }); |
| }; |
| |
| export const createIndex = (databaseName, indexCode) => { |
| const url = FauxtonAPI.urls('mango', 'index-server', |
| app.utils.safeURLName(databaseName)); |
| |
| return post(url, indexCode, {rawBody: true}).then((json) => { |
| if (json.error) { |
| throw new Error('(' + json.error + ') ' + json.reason); |
| } |
| return json; |
| }); |
| }; |
| |
| export const fetchIndexes = (databaseName, params) => { |
| const query = app.utils.queryString(params); |
| let url = FauxtonAPI.urls('mango', 'index-server', app.utils.safeURLName(databaseName)); |
| url = `${url}${url.includes('?') ? '&' : '?'}${query}`; |
| |
| return get(url).then((json) => { |
| if (json.error) { |
| throw new Error('(' + json.error + ') ' + json.reason); |
| } |
| return { |
| docs: json.indexes, |
| docType: Constants.INDEX_RESULTS_DOC_TYPE.MANGO_INDEX |
| }; |
| }); |
| }; |
| |
| // assume all databases being accessed are on the same |
| // host / CouchDB version |
| let supportsExecutionStatsCache = null; |
| const supportsExecutionStats = (databaseName) => { |
| if (supportsExecutionStatsCache === null) { |
| return new FauxtonAPI.Promise((resolve) => { |
| mangoQuery(databaseName, { |
| selector: { |
| "_id": {"$gt": "a" } |
| }, |
| execution_stats: true |
| }, {limit: 1}) |
| .then(resp => { |
| supportsExecutionStatsCache = resp.status == 200; |
| resolve(supportsExecutionStatsCache); |
| }); |
| }); |
| } |
| return Promise.resolve(supportsExecutionStatsCache); |
| }; |
| |
| // Determines what params need to be sent to couch based on the Mango query entered |
| // by the user and what fauxton is using to emulate pagination (fetchParams). |
| export const mergeFetchParams = (queryCode, fetchParams) => { |
| // Since Fauxton pagination's 'limit' is always (docs-per-page + 1), this ensures |
| // (page-number * docs-per-page) doesn't exceed the query's 'limit' value. |
| let limit = fetchParams.limit; |
| const docsPerPage = fetchParams.limit - 1; |
| const pageNumber = Math.floor(fetchParams.skip / docsPerPage) + 1; |
| const docsOverLimit = (pageNumber * docsPerPage) - queryCode.limit; |
| if (docsOverLimit >= 0) { |
| limit = docsPerPage - docsOverLimit; |
| } |
| |
| return { |
| ...queryCode, |
| limit: limit, |
| skip: queryCode.skip ? (fetchParams.skip + queryCode.skip) : fetchParams.skip |
| }; |
| }; |
| |
| export const mangoQuery = (databaseName, queryCode, fetchParams) => { |
| const url = FauxtonAPI.urls('mango', 'query-server', encodeURIComponent(databaseName)); |
| const modifiedQuery = mergeFetchParams(queryCode, fetchParams); |
| |
| return post(url, modifiedQuery, {raw: true}); |
| }; |
| |
| export const mangoQueryDocs = (databaseName, queryCode, fetchParams) => { |
| // we can only add the execution_stats field if it is supported by the server |
| // otherwise Couch throws an error |
| return supportsExecutionStats(databaseName).then((shouldFetchExecutionStats) => { |
| if (shouldFetchExecutionStats) { |
| queryCode.execution_stats = true; |
| } |
| return mangoQuery(databaseName, queryCode, fetchParams) |
| .then((res) => res.json()) |
| .then((json) => { |
| if (json.error) { |
| throw new Error('(' + json.error + ') ' + json.reason); |
| } |
| return { |
| docs: json.docs, |
| docType: Constants.INDEX_RESULTS_DOC_TYPE.MANGO_QUERY, |
| executionStats: json.execution_stats, |
| warning: json.warning |
| }; |
| }); |
| }); |
| }; |