Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
tree_nodes.ts302 linesDownload Raw Back to tree
1/////////////////////////////////////////////////////////////2//3// pgAdmin 4 - PostgreSQL Tools4//5// Copyright (C) 2013 - 2024, The pgAdmin Development Team6// This software is released under the PostgreSQL Licence7//8//////////////////////////////////////////////////////////////9 10import * as BrowserFS from 'browserfs';11import url_for from 'sources/url_for';12import pgAdmin from 'sources/pgadmin';13import _ from 'lodash';14import { FileType } from 'react-aspen';15import { findInTree } from './tree';16import gettext from 'sources/gettext';17 18import { unix } from 'path-fx';19import getApiInstance, { parseApiError } from '../api_instance';20 21export class ManageTreeNodes {22  constructor() {23    this.tree = {};24    this.tempTree = new TreeNode(undefined, {});25  }26 27  public init = (_root: string) => new Promise((res) => {28    const node = {parent: null, children: [], data: null};29    this.tree = {};30    this.tree[_root] = {name: 'root', type: FileType.Directory, metadata: node};31    res();32  });33 34  public updateNode = (_path, _data)  => new Promise((res) => {35    const item = this.findNode(_path);36    if (item) {37      item.data = {...item.data, ..._data};38      item.name = _data.label;39      item.metadata.data = _data;40    }41    res(true);42  });43 44  public removeNode = async (_path)  => {45    const item = this.findNode(_path);46 47    if (item && item.parentNode) {48      item.children = [];49      item.parentNode.children.splice(item.parentNode.children.indexOf(item), 1);50    }51    return true;52  };53 54  findNode(path) {55    if (path === null || path === undefined || path.length === 0 || path == '/browser') {56      return this.tempTree;57    }58    return findInTree(this.tempTree, path);59  }60 61  public addNode = (_parent: string, _path: string, _data: []) => new Promise((res) => {62    _data.type = _data.inode ? FileType.Directory : FileType.File;63    _data._label = _data.label;64    _data.label = _.escape(_data.label);65 66    _data.is_collection = isCollectionNode(_data._type);67    const nodeData = {parent: _parent, children: [], data: _data};68 69    const tmpParentNode = this.findNode(_parent);70    const treeNode = new TreeNode(_data.id, _data, {}, tmpParentNode, nodeData, _data.type);71 72    if (tmpParentNode !== null && tmpParentNode !== undefined) tmpParentNode.children.push(treeNode);73 74    res(treeNode);75  });76 77  public readNode = async (_path: string) => {78    let temp_tree_path = _path;79    const node = this.findNode(_path);80    const base_url = pgAdmin.Browser.URL;81    const api = getApiInstance();82 83    if (node && node.children.length > 0) {84      if (node.type !== FileType.File) {85        console.error(node, 'It\'s a leaf node');86        return [];87      }88      else {89        if (node.children.length != 0) return node.children;90      }91    }92 93    const self = this;94    let url = '';95    if (_path == '/browser') {96      url = url_for('browser.nodes');97    } else {98      const _parent_url = self.generate_url(_path);99      if (node.metadata.data._pid == null ) {100        url = node.metadata.data._type + '/children/' + node.metadata.data._id;101      }102      else {103        if (node.metadata.data._type.includes('coll-')) {104          const _type = node.metadata.data._type.replace('coll-', '');105          url = _type + '/nodes/' + _parent_url + '/';106        }107        else {108          url = node.metadata.data._type + '/children/' + _parent_url + '/' + node.metadata.data._id;109        }110      }111 112      url = base_url + url;113 114      temp_tree_path = node.path;115 116      if (node.metadata.data._type == 'server' && !node.metadata.data.connected) {117        url = null;118      }119    }120 121    let treeData = [];122    if (url) {123      try {124        const res = await api.get(url);125        treeData = res.data.data;126      } catch (error) {127        /* react-aspen does not handle reject case */128        console.error(error);129        pgAdmin.Browser.notifier.error(parseApiError(error)||'Node Load Error...');130        return [];131      }132    }133 134    const Path = BrowserFS.BFSRequire('path');135    for (const idx in treeData) {136      const _node: any = treeData[idx];137      const _pathl = Path.join(_path, _node.id);138      await self.addNode(temp_tree_path, _pathl, _node);139    }140    if (node.children.length > 0) return node.children;141    else {142      if (node.data && node.data._type == 'server' && node.data.connected) {143        pgAdmin.Browser.notifier.info(gettext('Server children are not available.'144        +' Please check these nodes are not hidden through the preferences setting `Browser > Nodes`.'), null);145      }146      return [];147    }148  };149 150  public generate_url = (path: string) => {151    let _path = path;152    const _parent_path = [];153    let _partitions = [];154    while(_path != '/') {155      const node = this.findNode(_path);156      const _parent = unix.dirname(_path);157      if(node.parentNode && node.parentNode.path == _parent) {158        if (node.parentNode.metadata.data !== null && !node.parentNode.metadata.data._type.includes('coll-'))159          if(node.parentNode.metadata.data._type.includes('partition')) {160            _partitions.push(node.parentNode.metadata.data._id);161          } else {162            _parent_path.push(node.parentNode.metadata.data._id);163          }164      }165      _path = _parent;166    }167    _partitions = _partitions.reverse();168    // Replace the table with the last partition as in reality partition node is not child of the table169    if(_partitions.length > 0) _parent_path[0]  = _partitions[_partitions.length-1];170 171    return _parent_path.reverse().join('/');172  };173}174 175 176 177export class TreeNode {178  constructor(id, data, domNode, parent, metadata, type) {179    this.id = id;180    this.data = data;181    this.setParent(parent);182    this.children = [];183    this.domNode = domNode;184    this.metadata = metadata;185    this.name = metadata ? metadata.data.label : '';186    this.type = type ? type : undefined;187  }188 189  hasParent() {190    return this.parentNode !== null && this.parentNode !== undefined;191  }192 193  parent() {194    return this.parentNode;195  }196 197  setParent(parent) {198    this.parentNode = parent;199    this.path = this.id;200    if (this.id)201      if (parent !== null && parent !== undefined && parent.path !== undefined) {202        this.path = parent.path + '/' + this.id;203      } else {204        this.path =  '/browser/' + this.id;205      }206  }207 208  getData() {209    if (this.data === undefined) {210      return undefined;211    } else if (this.data === null) {212      return null;213    }214    return Object.assign({}, this.data);215  }216 217  getHtmlIdentifier() {218    return this.domNode;219  }220 221  /*222   * Find the ancestor with matches this condition223   */224  ancestorNode(condition) {225    let node = this;226 227    while (node.hasParent()) {228      node = node.parent();229      if (condition(node)) {230        return node;231      }232    }233 234    return null;235  }236 237  /**238   * Given a condition returns true if the current node239   * or any of the parent nodes condition result is true240   */241  anyFamilyMember(condition) {242    if(condition(this)) {243      return true;244    }245 246    return this.ancestorNode(condition) !== null;247  }248  anyParent(condition) {249    return this.ancestorNode(condition) !== null;250  }251 252  reload(tree) {253    return new Promise((resolve)=>{254      this.unload(tree)255        .then(()=>{256          tree.setInode(this.domNode);257          tree.deselect(this.domNode);258          setTimeout(() => {259            tree.selectNode(this.domNode);260          }, 0);261          resolve();262        });263    });264  }265 266  unload(tree) {267    return new Promise((resolve, reject)=>{268      this.children = [];269      tree.unload(this.domNode)270        .then(271          ()=>{272            resolve(true);273          },274          ()=>{275            reject();276          });277    });278  }279 280 281  open(tree, suppressNoDom) {282    return new Promise((resolve, reject)=>{283      if(suppressNoDom && (this.domNode == null || typeof(this.domNode) === 'undefined')) {284        resolve(true);285      } else if(tree.isOpen(this.domNode)) {286        resolve(true);287      } else {288        tree.open(this.domNode).then(() => resolve(true), () => reject(true));289      }290    });291  }292 293}294 295export function isCollectionNode(node) {296  if (pgAdmin.Browser.Nodes && node in pgAdmin.Browser.Nodes) {297    if (pgAdmin.Browser.Nodes[node].is_collection !== undefined) return pgAdmin.Browser.Nodes[node].is_collection;298    else return false;299  }300  return false;301}302 
codekingpro/portable-devtools · Team Ai