如何使用树遍历将文件夹和文件上传到数据库

How to use tree traversal to upload folders and files into database

提问人:Tarun 提问时间:5/8/2023 最后编辑:Tarun 更新时间:5/9/2023 访问量:53

问:

嘿,大家好,我有这些数据,我想使用它在 mysql 数据库中创建文件夹和文件。

我目前有两个表,一个用于文件,一个用于文件夹,这两个表都有一个属性,用于存储文件或文件夹的父 ID。parent_id

所有这些文件都已上传并存储在数据库中,但我想更新它们并使用 .为此,我需要在创建文件夹时访问 insertIds。parent_idoriginal_path

[ { filename: 'videoplayback.mp4',
    file_id: '75f6d49e60ee472086d6d59220a203e69f797179',
    user_id: 1825874,
    original_path: 'test folder/child 2/child 3/videoplayback.mp4' },
  { filename: 'gcp2.mp4',
    file_id: 'c719eb645a144ab3ac93acd963b343574b59f94d',
    user_id: 1825874,
    original_path: 'test folder/child 2/gcp2.mp4' },
  { filename: 'video file.mp4',
    file_id: '4f7cc6094c6549d0afe5df18f502a19534767f33',
    user_id: 1825874,
    original_path: 'test folder/video file.mp4' },
  { filename: 'gcp.mp4',
    file_id: 'a735eeef15bb4a839624e3af5058897617752d3e',
    user_id: 1825874,
    original_path: 'test folder/child 1/gcp.mp4' } ]

现在我调用了这个函数,它使用 original_path 将这个数组转换为树状结构并返回它。makeTree

var make_tree = (files) => {
        var tree = {};
        var filesArray = Array.from(files);
      
        var addPath = (file, tree, user_id, file_id) => {
            if (file.original_path.endsWith(".DS_Store")) return;
            var path = file.original_path;
          
            // helper function to create child objects
            var createChild = (name, user_id, file_id) => ({
              name,
              user_id,
              children: [],
              ...(file_id !== undefined && { file_id }), // add file_id only if it's defined and is the last child
            });
          
            // split path to array of folders and files
            var parts = path.split("/");
          
            // create tree if empty
            if (!tree.name) {
              var otherFile = filesArray.find((f) => f.original_path !== path);
              var user_id = otherFile ? otherFile.user_id : undefined;
              Object.assign(tree, createChild(parts[0], user_id, undefined));
            }
          
            parts.shift();
          
            // check and add other path parts
            let isLastChild = false;
            parts.reduce((current, part, index) => {
              isLastChild = index === parts.length - 1; // check if this is the last child
              var child = current.children.find((child) => child.name === part);
          
              if (child) {
                return child;
              }
          
              var newChild = createChild(part, user_id, isLastChild ? file_id : undefined); // pass file_id only if it's the last child
              current.children.push(newChild);
              return newChild;
            }, tree);
          };
      
        filesArray.forEach((file) => addPath(file, tree, file.user_id, file.file_id));
        return tree;
    };

当我在此函数中传递数据时,该函数返回此数据结构

{
  name: "test folder",
  user_id: 1825874,
  children: [
    {
      name: "child 2",
      user_id: 1825874,
      children: [
        {
          name: "child 3",
          user_id: 1825874,
          children: [
            {
              name: "videoplayback.mp4",
              user_id: 1825874,
              children: [],
              file_id: "2cef9d399c994973bf7b739841c1268de0d14aa7"
            }
          ]
        },
        {
          name: "gcp2.mp4",
          user_id: 1825874,
          children: [],
          file_id: "6ab41ebbacb546d89a97c4977bbcac8e9004b8c0"
        }
      ]
    },
    {
      name: "video file.mp4",
      user_id: 1825874,
      children: [],
      file_id: "062b6da1e14445fc95259d060c0d0f4273f33d9e"
    },
    {
      name: "child 1",
      user_id: 1825874,
      children: [
        {
          name: "gcp.mp4",
          user_id: 1825874,
          children: [],
          file_id: "8b2acac9c8514b14be93661725863f2448a89af4"
        }
      ]
    }
  ]
}

现在使用此数据,我正在运行此代码以将文件夹和文件插入数据库,但此代码是错误的(仅供参考)


// The folder parameter is the tree that we got from the "makeTree" function.
// parent_id is the parent_id of the root folder.
// the callback runs at the end of the function because I invoke this function using Q.nfcall()

var process_zip_folders = function(folder, parent_id, callback) {
        var mysql = null;
        var query = '';

        Q.fcall(function () {
            return Q.ninvoke(cgws, "mysqlConnection");

        }).then(function (value) {
            mysql = value;

            //inserting the root folder into the database 
            query = "INSERT INTO cgws_folders (name, parent_id, user_id) VALUES (?, ?, ?)";
            return Q.ninvoke(mysql, "query", query, [folder.name, parent_id, folder.user_id]);

        }).then(function(value){
            var info = value[1];
            var parent_id = info.insertId;
            var deferred = Q.defer();
            var child_index = 0;
            var depth_index = 0;
            var child_ids = {};
            var children = [];
            var isLastDepth = true;

            var cb_process_children = function(err){
                if(err){
                    return deferred.reject(err);
                }

                for(let i = 0; i < children.length; i++){
                    if(children[i].children.length > 0){
                        isLastDepth = false;
                        break;
                    }
                }

                if(isLastDepth){
                    deferred.resolve();
                } else {
                    child_index = 0;

                    children = children[depth_index++].children;

                    setImmediate(function(){
                        process_children(child_ids[parent_id][child_index], cb_process_children);
                    });
                }
            }

            var process_child = function(child, parent_id, callback){
                var query = '';

                if(!child){
                    return callback();
                }

                if (child.file_id) {
                    query = "UPDATE cgws_files SET parent_id=? WHERE file_id=?";
                    mysql.query(query, [parent_id, child.file_id], function(err){
                        if(err){
                            return callback(err);
                        }
                        callback();
                    });
                } else {
                    query = "INSERT INTO cgws_folders (name, parent_id, user_id) VALUES (?, ?, ?)";
                    mysql.query(query, [child.name, parent_id, child.user_id], function (err, result, info) {
                        if (err) {
                            return callback(err);
                        }

                        callback(null, info.insertId);
                    });
                }
            }
    
            var process_children = function(parent_id, callback){
                var child = children[child_index];
                var cb_process_child = function(err, child_id){

                    if(err){
                        return callback(err);
                    }

                    if(!child_ids[parent_id]){
                        child_ids[parent_id] = []; 
                    }

                    child_ids[parent_id].push(child_id);

                    if(++child_index < children.length){
                        setImmediate(function(){
                            process_child(children[child_index], parent_id, cb_process_child);
                        });
                    } else {
                        callback();
                    }
                }
    
                process_child(child, parent_id, cb_process_child)
            };

            children = folder.children;

            process_children(parent_id, cb_process_children);

            return deferred.promise;

        }).then(function(){
            callback();

        }).fail(function(error){
            cgws.logError(error)

        }).fin(function () {
            if (mysql) {
                mysql.end()
            }
        })
    };

您可以使用转换后的树结构或仅使用数组中的原始数据来实现此工作。

谢谢:)

javascript sql mysql 后端 q

评论


答: 暂无答案