# Buggy code
def save_datasource(self, name, source_type, source, file_path=None):
    if source_type == "file" and (file_path is None):
        raise Exception('`file_path` argument required when source_type == "file"')

    for i in range(1, 1000):
        if name in [x["name"] for x in self.get_datasources()]:
            previous_index = i - 1
            name = name.replace(f"__{previous_index}__", "")
            name = f"{name}__{i}__"
        else:
            break

    ds_meta_dir = os.path.join(self.dir, name)
    os.mkdir(ds_meta_dir)

    ds_dir = os.path.join(ds_meta_dir, "datasource")
    os.mkdir(ds_dir)

    if source_type == "file":
        try:
            source = os.path.join(ds_dir, source)
            os.replace(file_path, source)
            ds = FileDS(source)
        except Exception:
            shutil.rmtree(ds_meta_dir)
            raise

        picklable = {"class": "FileDS", "args": [source], "kwargs": {}}
    elif source_type in self.config["integrations"]:
        integration = self.config["integrations"][source_type]
        dsClass = None
        picklable = {
            "args": [],
            "kwargs": {
                "query": source,
                "user": integration["user"],
                "password": integration["password"],
                "host": integration["host"],
                "port": integration["port"],
            },
        }
        if integration["type"] == "clickhouse":
            dsClass = ClickhouseDS
            picklable["class"] = "ClickhouseDS"
        elif integration["type"] == "mariadb":
            dsClass = MariaDS
            picklable["class"] = "MariaDS"
        elif integration["type"] == "mysql":
            dsClass = MySqlDS
            picklable["class"] = "MySqlDS"
        elif integration["type"] == "postgres":
            dsClass = PostgresDS
            picklable["class"] = "PostgresDS"
        else:
            raise ValueError(f"Unknown DS source_type: {source_type}")
        try:
            ds = dsClass(
                query=source,
                user=integration["user"],
                password=integration["password"],
                host=integration["host"],
                port=integration["port"],
            )
        except Exception:
            shutil.rmtree(ds_meta_dir)
            raise
    else:
        # This probably only happens for urls
        print("Create URL data source !")
        try:
            ds = FileDS(source)
        except Exception:
            shutil.rmtree(ds_meta_dir)
            raise
        picklable = {"class": "FileDS", "args": [source], "kwargs": {}}

    df = ds.df

    df_with_types = cast_df_columns_types(df, self.get_analysis(df)["data_analysis_v2"])
    create_sqlite_db(os.path.join(ds_dir, "sqlite.db"), df_with_types)

    with open(os.path.join(ds_dir, "ds.pickle"), "wb") as fp:
        pickle.dump(picklable, fp)

    with open(os.path.join(ds_dir, "metadata.json"), "w") as fp:
        meta = {
            "name": name,
            "source_type": source_type,
            "source": source,
            "created_at": str(datetime.datetime.now()).split(".")[0],
            "updated_at": str(datetime.datetime.now()).split(".")[0],
            "row_count": len(df),
            "columns": [dict(name=x) for x in list(df.keys())],
        }
        json.dump(meta, fp)

    return self.get_datasource_obj(name, raw=True), name


# Traceback (PermissionError)
Exception on /datasources/Somedata [PUT] Traceback (most recent call last): File "C:\Users\jp299\AppData\Roaming\mindsdb_gui\mindsdb_server\env\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request rv = self.dispatch_request() File "C:\Users\jp299\AppData\Roaming\mindsdb_gui\mindsdb_server\env\lib\site-packages\flask\app.py", line 1936, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "C:\Users\jp299\AppData\Roaming\mindsdb_gui\mindsdb_server\env\lib\site-packages\flask_restx\api.py", line 375, in wrapper resp = resource(*args, **kwargs) File "C:\Users\jp299\AppData\Roaming\mindsdb_gui\mindsdb_server\env\lib\site-packages\flask\views.py", line 89, in view return self.dispatch_request(*args, **kwargs) File "C:\Users\jp299\AppData\Roaming\mindsdb_gui\mindsdb_server\env\lib\site-packages\flask_restx\resource.py", line 44, in dispatch_request resp = meth(*args, **kwargs) File "C:\Users\jp299\AppData\Roaming\mindsdb_gui\mindsdb_server\env\lib\site-packages\flask_restx\marshalling.py", line 248, in wrapper resp = f(*args, **kwargs) File "C:\Users\jp299\AppData\Roaming\mindsdb_gui\mindsdb_server\env\lib\site-packages\mindsdb\api\http\namespaces\datasource.py", line 114, in put ca.default_store.save_datasource(ds_name, source_type, source, file_path) File "C:\Users\jp299\AppData\Roaming\mindsdb_gui\mindsdb_server\env\lib\site-packages\mindsdb\interfaces\datastore\datastore.py", line 81, in save_datasource os.replace(file_path, source) PermissionError: [WinError 32] El proceso no tiene acceso al archivo porque est� siendo utilizado por otro proceso: 'C:\\Users\\jp299\\AppData\\Local\\Temp\\datasource_file_pzpfjtzc\\Somedata.xlsx' -> 'C:\\Users\\jp299\\AppData\\Roaming\\mindsdb_gui\\mindsdb_server\\env\\lib\\site-packages/var/datastore\\Somedata\datasource\\Somedata.xlsx'

# Fixed code
def save_datasource(self, name, source_type, source, file_path=None):
    if source_type == "file" and (file_path is None):
        raise Exception('`file_path` argument required when source_type == "file"')

    for i in range(1, 1000):
        if name in [x["name"] for x in self.get_datasources()]:
            previous_index = i - 1
            name = name.replace(f"__{previous_index}__", "")
            name = f"{name}__{i}__"
        else:
            break

    ds_meta_dir = os.path.join(self.dir, name)
    os.mkdir(ds_meta_dir)

    ds_dir = os.path.join(ds_meta_dir, "datasource")
    os.mkdir(ds_dir)

    if source_type == "file":
        try:
            source = os.path.join(ds_dir, source)
            shutil.move(file_path, source)
            ds = FileDS(source)
        except Exception:
            shutil.rmtree(ds_meta_dir)
            raise

        picklable = {"class": "FileDS", "args": [source], "kwargs": {}}
    elif source_type in self.config["integrations"]:
        integration = self.config["integrations"][source_type]
        dsClass = None
        picklable = {
            "args": [],
            "kwargs": {
                "query": source,
                "user": integration["user"],
                "password": integration["password"],
                "host": integration["host"],
                "port": integration["port"],
            },
        }
        if integration["type"] == "clickhouse":
            dsClass = ClickhouseDS
            picklable["class"] = "ClickhouseDS"
        elif integration["type"] == "mariadb":
            dsClass = MariaDS
            picklable["class"] = "MariaDS"
        elif integration["type"] == "mysql":
            dsClass = MySqlDS
            picklable["class"] = "MySqlDS"
        elif integration["type"] == "postgres":
            dsClass = PostgresDS
            picklable["class"] = "PostgresDS"
        else:
            raise ValueError(f"Unknown DS source_type: {source_type}")
        try:
            ds = dsClass(
                query=source,
                user=integration["user"],
                password=integration["password"],
                host=integration["host"],
                port=integration["port"],
            )
        except Exception:
            shutil.rmtree(ds_meta_dir)
            raise
    else:
        # This probably only happens for urls
        print("Create URL data source !")
        try:
            ds = FileDS(source)
        except Exception:
            shutil.rmtree(ds_meta_dir)
            raise
        picklable = {"class": "FileDS", "args": [source], "kwargs": {}}

    df = ds.df

    df_with_types = cast_df_columns_types(df, self.get_analysis(df)["data_analysis_v2"])
    create_sqlite_db(os.path.join(ds_dir, "sqlite.db"), df_with_types)

    with open(os.path.join(ds_dir, "ds.pickle"), "wb") as fp:
        pickle.dump(picklable, fp)

    with open(os.path.join(ds_dir, "metadata.json"), "w") as fp:
        meta = {
            "name": name,
            "source_type": source_type,
            "source": source,
            "created_at": str(datetime.datetime.now()).split(".")[0],
            "updated_at": str(datetime.datetime.now()).split(".")[0],
            "row_count": len(df),
            "columns": [dict(name=x) for x in list(df.keys())],
        }
        json.dump(meta, fp)

    return self.get_datasource_obj(name, raw=True), name