Commit 62b52f37 by John Donnal

fixed recursive deletion bug on folders

parent 19e4dcc9
......@@ -27,9 +27,9 @@ module Joule
# go through the schema and update the database
@db.root_folder ||= DbFolder.create(db: @db)
__update_folder(@db.root_folder, schema, '')
DbFolder.destroy(@deleted_folders)
DbStream.destroy(@deleted_db_streams)
EventStream.destroy(@deleted_event_streams)
DbFolder.destroy(@deleted_folders)
@db.available = true
@db.save
......@@ -98,7 +98,7 @@ module Joule
updated_ids << child_schema[:id]
locked = true if child.locked?
end
# mark any subfolders that are no longer on the folder for deletion
# mark any subfolders that are no longer in the folder for deletion
@deleted_folders += db_folder.subfolders.where.not(joule_id: updated_ids).pluck(:id)
# update or create data streams
......
......@@ -5,7 +5,7 @@
# a folder in the database, may contain one or more DbFiles as files
# and one or more DbFolders as subfolders
class DbFolder < ApplicationRecord
belongs_to :parent, class_name: 'DbFolder', optional: true, dependent: :destroy
belongs_to :parent, class_name: 'DbFolder', optional: true
belongs_to :db, optional: false
has_many :subfolders,
......
......@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 10,
"execution_count": null,
"id": "be19494a-9aa1-47e1-943c-50a6a13fcb2f",
"metadata": {},
"outputs": [],
......@@ -14,18 +14,10 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": null,
"id": "8ab34a29-f046-45d2-b45b-d08ffef4147b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 top level folders\n"
]
}
],
"outputs": [],
"source": [
"node = joule.api.get_node()\n",
"root = await node.folder_get('/')\n",
......@@ -41,7 +33,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": null,
"id": "b45e0f20-4544-4368-8e72-5b51c82254bd",
"metadata": {},
"outputs": [],
......@@ -83,19 +75,10 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": null,
"id": "d5c820d5-6e93-4bea-9d9c-da166e68c69b",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/ubuntu/joule/lib/python3.10/site-packages/urllib3/connectionpool.py:1095: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n",
" warnings.warn(\n"
]
}
],
"outputs": [],
"source": [
"\n",
"stream_1_1 = joule.api.DataStream(\"stream_1_1\",elements=[joule.api.Element(x) for x in \"xyz\"])\n",
......@@ -154,19 +137,10 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": null,
"id": "ac75335d-cd3d-46a5-8aa5-0fd4555efc79",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/ubuntu/joule/lib/python3.10/site-packages/urllib3/connectionpool.py:1095: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n",
" warnings.warn(\n"
]
}
],
"outputs": [],
"source": [
"stream_3_1_1.elements[0].units=\"updated_units\"\n",
"stream_1_2.description = \"updated_description\"\n",
......@@ -206,26 +180,10 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": null,
"id": "3c127916-ae78-461a-bf3d-f0af66829e14",
"metadata": {},
"outputs": [
{
"ename": "ApiError",
"evalue": "stream with the same name exists in the destination folder [400]",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mApiError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[16], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m node\u001b[38;5;241m.\u001b[39mdata_stream_move(stream_1_2, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/folder_4/folder_4_1\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m node\u001b[38;5;241m.\u001b[39mfolder_move(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/folder_3\u001b[39m\u001b[38;5;124m\"\u001b[39m,\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/folder_4\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m save_schema(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m2_moved_schema.json\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
"File \u001b[0;32m/opt/joule/joule/api/node/base_node.py:127\u001b[0m, in \u001b[0;36mBaseNode.data_stream_move\u001b[0;34m(self, stream, folder)\u001b[0m\n\u001b[1;32m 124\u001b[0m \u001b[38;5;28;01masync\u001b[39;00m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mdata_stream_move\u001b[39m(\u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 125\u001b[0m stream: Union[DataStream, \u001b[38;5;28mstr\u001b[39m, \u001b[38;5;28mint\u001b[39m],\n\u001b[1;32m 126\u001b[0m folder: Union[Folder, \u001b[38;5;28mstr\u001b[39m, \u001b[38;5;28mint\u001b[39m]) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 127\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mawait\u001b[39;00m data_stream_move(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msession, stream, folder)\n",
"File \u001b[0;32m/opt/joule/joule/api/data_stream.py:312\u001b[0m, in \u001b[0;36mdata_stream_move\u001b[0;34m(session, source, destination)\u001b[0m\n\u001b[1;32m 310\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 311\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m errors\u001b[38;5;241m.\u001b[39mApiError(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvalid destination datatype. Must be Folder, Path, or ID\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 312\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m session\u001b[38;5;241m.\u001b[39mput(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/stream/move.json\u001b[39m\u001b[38;5;124m\"\u001b[39m, data)\n",
"File \u001b[0;32m/opt/joule/joule/api/session/base_session.py:27\u001b[0m, in \u001b[0;36mBaseSession.put\u001b[0;34m(self, path, json)\u001b[0m\n\u001b[1;32m 26\u001b[0m \u001b[38;5;28;01masync\u001b[39;00m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mput\u001b[39m(\u001b[38;5;28mself\u001b[39m, path, json):\n\u001b[0;32m---> 27\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mawait\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_request(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mPUT\u001b[39m\u001b[38;5;124m\"\u001b[39m, path, json\u001b[38;5;241m=\u001b[39mjson)\n",
"File \u001b[0;32m/opt/joule/joule/api/session/tcp_session.py:62\u001b[0m, in \u001b[0;36mTcpSession._request\u001b[0;34m(self, method, path, data, json, params, chunked)\u001b[0m\n\u001b[1;32m 60\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m asyncio\u001b[38;5;241m.\u001b[39msleep(RETRY_DELAY)\n\u001b[1;32m 61\u001b[0m \u001b[38;5;28;01mcontinue\u001b[39;00m \u001b[38;5;66;03m# retry\u001b[39;00m\n\u001b[0;32m---> 62\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m errors\u001b[38;5;241m.\u001b[39mApiError(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m [\u001b[39m\u001b[38;5;132;01m%d\u001b[39;00m\u001b[38;5;124m]\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m%\u001b[39m (msg, resp\u001b[38;5;241m.\u001b[39mstatus))\n\u001b[1;32m 63\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m resp\u001b[38;5;241m.\u001b[39mcontent_type \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mapplication/json\u001b[39m\u001b[38;5;124m'\u001b[39m:\n\u001b[1;32m 64\u001b[0m body \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mawait\u001b[39;00m resp\u001b[38;5;241m.\u001b[39mtext()\n",
"\u001b[0;31mApiError\u001b[0m: stream with the same name exists in the destination folder [400]"
]
}
],
"outputs": [],
"source": [
"await node.data_stream_move(stream_1_2, \"/folder_4/folder_4_1\")\n",
"await node.folder_move(\"/folder_3\",\"/folder_4\")\n",
......@@ -257,19 +215,10 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": null,
"id": "8e486e6a-9521-4890-b71e-41f4bcf2fcd2",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/ubuntu/joule/lib/python3.10/site-packages/urllib3/connectionpool.py:1095: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n",
" warnings.warn(\n"
]
}
],
"outputs": [],
"source": [
"await node.event_stream_move(load_events,\"/folder_4/folder_4_1\")\n",
"await node.folder_delete(\"/folder_2\")\n",
......@@ -303,19 +252,10 @@
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": null,
"id": "27d91f25-929f-46cf-81da-7f28cd5e4f7d",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/ubuntu/joule/lib/python3.10/site-packages/urllib3/connectionpool.py:1095: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n",
" warnings.warn(\n"
]
}
],
"outputs": [],
"source": [
"new_data_stream = joule.api.DataStream(\"new_data_stream\",elements=[joule.api.Element(f\"{i}\") for i in range(1)])\n",
"new_event_stream = joule.api.EventStream(\"new_event_stream\",event_fields={\"test\":\"string\"})\n",
......@@ -351,7 +291,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.6"
"version": "3.7.9"
}
},
"nbformat": 4,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment