diff --git a/docker-compose.yml b/docker-compose.yml index 747ed2044..c59a43c09 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -63,12 +63,12 @@ services: networks: classroom: fbs: - healthcheck: - test: curl -k https://localhost:443/actuator/health - timeout: 10s - interval: 10s - start_period: 10s - retries: 3 + #healthcheck: + # test: curl -k https://localhost:443/actuator/health + # timeout: 10s + # interval: 10s + # start_period: 10s + # retries: 3 mysql-checker: image: mysql:8.0 @@ -201,7 +201,8 @@ services: BASH_DOCKER: thmmniii/fbs-runtime-bash:dev-latest HOST_TMP_DIR: /tmp/feebi # Need to be the same folder as mounted to /dockertemp INSIDE_DOCKER: "true" - RESULT_SERVER_HOST: core + RESULT_SERVER_HOST: 172.17.0.1 + RESULT_SERVER_PORT: 8443 MYSQL_SERVER_URL: jdbc:mysql://mysql-checker:3306?allowMultiQueries=true MYSQL_SERVER_PASSWORD: SqfyBWhiFGr7FK60cVR2rel PSQL_SERVER_URL: jdbc:postgresql://psql-checker:5432/?allowMultiQueries=true @@ -263,6 +264,16 @@ services: - FBS_BASE_URL=https://core:443 - FBS_TLS_NO_VERIFY=true + collab: + build: + context: modules/fbs-collab + restart: always + ports: + - 1234:1234 + environment: + - FBS_ROOT_URL=https://core + - NODE_TLS_REJECT_UNAUTHORIZED=0 + networks: classroom: fbs: diff --git a/modules/fbs-collab/Dockerfile b/modules/fbs-collab/Dockerfile new file mode 100644 index 000000000..acb37fc43 --- /dev/null +++ b/modules/fbs-collab/Dockerfile @@ -0,0 +1,8 @@ +FROM node:22-alpine +USER node +COPY --chown=node package.json package-lock.json tsconfig.json /app/ +WORKDIR /app +RUN npm ci +COPY --chown=node src/ src/ +RUN npm run build +CMD ["node", "src/app.js"] diff --git a/modules/fbs-collab/package-lock.json b/modules/fbs-collab/package-lock.json new file mode 100644 index 000000000..357c80032 --- /dev/null +++ b/modules/fbs-collab/package-lock.json @@ -0,0 +1,710 @@ +{ + "name": "fbs-collab", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "fbs-collab", + "version": "0.1.0", + "license": "Apache-2.0", + "dependencies": { + "@hocuspocus/server": "^2.13.5", + "jose": "^5.9.6" + }, + "devDependencies": { + "nodemon": "^3.1.4", + "ts-node": "^10.9.2", + "typescript": "^5.5.3" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@hocuspocus/common": { + "version": "2.13.5", + "resolved": "https://registry.npmjs.org/@hocuspocus/common/-/common-2.13.5.tgz", + "integrity": "sha512-8D9FzhZFlt0WsgXw5yT2zwSxi6z9d4V2vUz6co2vo3Cj+Y2bvGZsdDiTvU/MerGcCLME5k/w6PwLPojLYH/4pg==", + "dependencies": { + "lib0": "^0.2.87" + } + }, + "node_modules/@hocuspocus/server": { + "version": "2.13.5", + "resolved": "https://registry.npmjs.org/@hocuspocus/server/-/server-2.13.5.tgz", + "integrity": "sha512-gDYax5ruaj30mMtFjq5+o5USXQD31hDOxBVU8eTAzezS6hpVllaP7HmM8iRda+UmQoeybHxzqsWAf74JCmYDug==", + "dependencies": { + "@hocuspocus/common": "^2.13.5", + "async-lock": "^1.3.1", + "kleur": "^4.1.4", + "lib0": "^0.2.47", + "uuid": "^10.0.0", + "ws": "^8.5.0" + }, + "peerDependencies": { + "y-protocols": "^1.0.6", + "yjs": "^13.6.8" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "dev": true, + "peer": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/async-lock": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", + "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isomorphic.js": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/isomorphic.js/-/isomorphic.js-0.2.5.tgz", + "integrity": "sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==", + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, + "node_modules/jose": { + "version": "5.9.6", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.9.6.tgz", + "integrity": "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lib0": { + "version": "0.2.94", + "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.94.tgz", + "integrity": "sha512-hZ3p54jL4Wpu7IOg26uC7dnEWiMyNlUrb9KoG7+xYs45WkQwpVvKFndVq2+pqLYKe1u8Fp3+zAfZHVvTK34PvQ==", + "dependencies": { + "isomorphic.js": "^0.2.4" + }, + "bin": { + "0ecdsa-generate-keypair": "bin/0ecdsa-generate-keypair.js", + "0gentesthtml": "bin/gentesthtml.js", + "0serve": "bin/0serve.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nodemon": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", + "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "peer": true + }, + "node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y-protocols": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/y-protocols/-/y-protocols-1.0.6.tgz", + "integrity": "sha512-vHRF2L6iT3rwj1jub/K5tYcTT/mEYDUppgNPXwp8fmLpui9f7Yeq3OEtTLVF012j39QnV+KEQpNqoN7CWU7Y9Q==", + "peer": true, + "dependencies": { + "lib0": "^0.2.85" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + }, + "peerDependencies": { + "yjs": "^13.0.0" + } + }, + "node_modules/yjs": { + "version": "13.6.18", + "resolved": "https://registry.npmjs.org/yjs/-/yjs-13.6.18.tgz", + "integrity": "sha512-GBTjO4QCmv2HFKFkYIJl7U77hIB1o22vSCSQD1Ge8ZxWbIbn8AltI4gyXbtL+g5/GJep67HCMq3Y5AmNwDSyEg==", + "peer": true, + "dependencies": { + "lib0": "^0.2.86" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + } +} diff --git a/modules/fbs-collab/package.json b/modules/fbs-collab/package.json new file mode 100644 index 000000000..e03458ee7 --- /dev/null +++ b/modules/fbs-collab/package.json @@ -0,0 +1,23 @@ +{ + "name": "fbs-colab", + "version": "0.1.0", + "description": "", + "main": "app.js", + "scripts": { + "dev": "nodemon -e ts -x ts-node src/app.ts", + "build": "tsc src/app.ts", + "start": "node src/app.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "Apache-2.0", + "dependencies": { + "@hocuspocus/server": "^2.13.5", + "jose": "^5.9.6" + }, + "devDependencies": { + "nodemon": "^3.1.4", + "ts-node": "^10.9.2", + "typescript": "^5.5.3" + } +} diff --git a/modules/fbs-collab/src/app.ts b/modules/fbs-collab/src/app.ts new file mode 100644 index 000000000..85ca6da65 --- /dev/null +++ b/modules/fbs-collab/src/app.ts @@ -0,0 +1,25 @@ +import {Hocuspocus, onAuthenticatePayload, onConnectPayload} from "@hocuspocus/server"; +import * as jose from 'jose' + +const FBS_ROOT_URL = process.env.FBS_ROOT_URL ?? 'https://feedback.mni.thm.de'; + +const server = new Hocuspocus({ + port: 1234, + async onAuthenticate(data: onAuthenticatePayload): Promise { + let userId; + try { + userId = jose.decodeJwt(data.token).id; + } catch (e) { + throw new Error("Unauthorized"); + } + if (!userId) throw new Error("Unauthorized"); + const resp = await fetch(`${FBS_ROOT_URL}/api/v1/users/${userId}/groups`, {headers: {'Authorization': `Bearer ${data.token}`}}); + if (resp.status !== 200) throw new Error("Unauthorized"); + const body = await resp.json(); + const ok = Boolean(body.find(({id}: {id: string}) => id.toString() === data.documentName)); + if (!ok) throw new Error("Forbidden"); + return {user: {id: userId}}; + }, +}); + +server.listen(); diff --git a/modules/fbs-collab/tsconfig.json b/modules/fbs-collab/tsconfig.json new file mode 100644 index 000000000..8bb6097f8 --- /dev/null +++ b/modules/fbs-collab/tsconfig.json @@ -0,0 +1,108 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/modules/fbs-core/api/build.gradle b/modules/fbs-core/api/build.gradle index bca24a9ec..89e072b25 100644 --- a/modules/fbs-core/api/build.gradle +++ b/modules/fbs-core/api/build.gradle @@ -70,7 +70,7 @@ dependencies { implementation 'org.springframework.data:spring-data-commons' implementation 'org.springframework.data:spring-data-mongodb' implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'org.springframework.boot:spring-boot-starter-actuator' + //implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.projectreactor:reactor-core:3.5.6' implementation 'jakarta.platform:jakarta.jakartaee-api:10.0.0' implementation project(':fbs-core.math-parser') diff --git a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/controller/v2/PlaygroundController.kt b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/controller/v2/PlaygroundController.kt index 0e8ae31d2..ccc95db0f 100644 --- a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/controller/v2/PlaygroundController.kt +++ b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/controller/v2/PlaygroundController.kt @@ -4,18 +4,18 @@ package de.thm.ii.fbs.controller.v2 import com.fasterxml.jackson.databind.node.ArrayNode import com.fasterxml.jackson.databind.node.JsonNodeFactory +import de.thm.ii.fbs.model.v2.group.Group import de.thm.ii.fbs.model.v2.playground.* -import de.thm.ii.fbs.model.v2.playground.api.SqlPlaygroundDatabaseCreation -import de.thm.ii.fbs.model.v2.playground.api.SqlPlaygroundQueryCreation -import de.thm.ii.fbs.model.v2.playground.api.SqlPlaygroundResult -import de.thm.ii.fbs.model.v2.playground.api.SqlPlaygroundShareResponse +import de.thm.ii.fbs.model.v2.playground.api.* import de.thm.ii.fbs.model.v2.security.LegacyToken import de.thm.ii.fbs.services.v2.checker.SqlPlaygroundCheckerService import de.thm.ii.fbs.services.v2.persistence.* import de.thm.ii.fbs.utils.v2.annotations.CurrentToken +import de.thm.ii.fbs.utils.v2.exceptions.ForbiddenException import de.thm.ii.fbs.utils.v2.exceptions.NotFoundException import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.* +import kotlin.jvm.optionals.getOrNull @RestController @RequestMapping(path = ["/api/v2/playground/{uid}/databases"]) @@ -24,7 +24,8 @@ class PlaygroundController( private val databaseRepository: SqlPlaygroundDatabaseRepository, private val entityRepository: SqlPlaygroundEntityRepository, private val queryRepository: SqlPlaygroundQueryRepository, - private val sqlPlaygroundCheckerService: SqlPlaygroundCheckerService + private val sqlPlaygroundCheckerService: SqlPlaygroundCheckerService, + private val groupRepository: GroupRepository ) { @GetMapping @ResponseBody @@ -58,7 +59,7 @@ class PlaygroundController( @GetMapping("/{dbId}") @ResponseBody fun get(@CurrentToken currentToken: LegacyToken, @PathVariable("dbId") dbId: Int): SqlPlaygroundDatabase = - databaseRepository.findByOwner_IdAndIdAndDeleted(currentToken.id, dbId, false) ?: throw NotFoundException() + getDatabase(currentToken.id, dbId) @PostMapping("/{dbId}/activate") @ResponseBody @@ -81,6 +82,33 @@ class PlaygroundController( return SqlPlaygroundShareResponse(url) } + @PutMapping("/{dbId}/share-with-group") + @ResponseBody + fun setPlaygroundShareWithGroup(@CurrentToken currentToken: LegacyToken, @PathVariable("dbId") dbId: Int, @RequestBody shareWithGroup: SqlPlaygroundShareWithGroupRequest): SqlPlaygroundDatabase { + val db = databaseRepository.findByOwner_IdAndIdAndDeleted(currentToken.id, dbId, false) ?: throw NotFoundException() + val group = getGroup(shareWithGroup.groupId, currentToken.id) + db.shareWithGroup = group + return databaseRepository.save(db) + } + + @OptIn(ExperimentalStdlibApi::class) + private fun getGroup( + groupId: Int, + userId: Int + ): Group { + val group = groupRepository.findById(groupId).getOrNull() ?: throw NotFoundException() + if (group.users.find { it.userId == userId } == null) throw ForbiddenException() + return group + } + + @DeleteMapping("/{dbId}/share-with-group") + @ResponseBody + fun unsetPlaygroundShareWithGroup(@CurrentToken currentToken: LegacyToken, @PathVariable("dbId") dbId: Int): SqlPlaygroundDatabase { + val db = databaseRepository.findByOwner_IdAndIdAndDeleted(currentToken.id, dbId, false) ?: throw NotFoundException() + db.shareWithGroup = null + return databaseRepository.save(db) + } + @PostMapping("/{dbId}/reset") @ResponseBody @ResponseStatus(HttpStatus.NOT_IMPLEMENTED) @@ -90,7 +118,7 @@ class PlaygroundController( @ResponseBody @ResponseStatus(HttpStatus.ACCEPTED) fun execute(@CurrentToken currentToken: LegacyToken, @PathVariable("dbId") dbId: Int, @RequestBody sqlQuery: SqlPlaygroundQueryCreation): SqlPlaygroundQuery { - val db = databaseRepository.findByOwner_IdAndIdAndDeleted(currentToken.id, dbId, false) ?: throw NotFoundException() + val db = getDatabase(currentToken.id, dbId) val query = queryRepository.save(SqlPlaygroundQuery(sqlQuery.statement, db)) sqlPlaygroundCheckerService.submit(query) return query @@ -98,13 +126,18 @@ class PlaygroundController( @GetMapping("/{dbId}/results") @ResponseBody - fun getResults(@CurrentToken currentToken: LegacyToken, @PathVariable("dbId") dbId: Int): List = - queryRepository.findByRunIn_Owner_IdAndRunIn_id(currentToken.id, dbId).mapNotNull { it.result } + fun getResults(@CurrentToken currentToken: LegacyToken, @PathVariable("dbId") dbId: Int): List { + getDatabase(currentToken.id, dbId) + return queryRepository.findByRunIn_id(dbId).mapNotNull { it.result } + } @GetMapping("/{dbId}/results/{qId}") @ResponseBody - fun getResult(@CurrentToken currentToken: LegacyToken, @PathVariable("dbId") dbId: Int, @PathVariable("qId") qId: Int): SqlPlaygroundResult = - queryRepository.findByRunIn_Owner_IdAndRunIn_idAndId(currentToken.id, dbId, qId)?.result ?: throw NotFoundException() + fun getResult(@CurrentToken currentToken: LegacyToken, @PathVariable("dbId") dbId: Int, @PathVariable("qId") qId: Int): SqlPlaygroundResult { + getDatabase(currentToken.id, dbId) + return queryRepository.findByRunIn_idAndId(dbId, qId)?.result + ?: throw NotFoundException() + } @GetMapping("/{dbId}/tables") @ResponseBody @@ -131,10 +164,26 @@ class PlaygroundController( fun getTriggers(@CurrentToken currentToken: LegacyToken, @PathVariable("dbId") dbId: Int): ArrayNode = getEntity(currentToken.id, dbId, "triggers") - private fun getEntity(userId: Int, databaseId: Int, type: String) = - entityRepository.findByDatabase_Owner_IdAndDatabase_idAndDatabase_DeletedAndType(userId, databaseId, false, type)?.data ?: throw NotFoundException() + @GetMapping("/shared-with-group/{groupId}") + @ResponseBody + fun getByGroupId(@CurrentToken currentToken: LegacyToken, @PathVariable("groupId") groupId: Int): SqlPlaygroundDatabase? { + getGroup(groupId, currentToken.id) + return databaseRepository.findByShareWithGroup(groupId) + } + + private fun getEntity(userId: Int, databaseId: Int, type: String): ArrayNode { + getDatabase(userId, databaseId) + return entityRepository.findByDatabase_idAndDatabase_DeletedAndType(databaseId, false, type)?.data ?: throw NotFoundException() + } private fun createAllEntities(database: SqlPlaygroundDatabase) = listOf("tables", "constraints", "views", "routines", "triggers").forEach { type -> entityRepository.save(SqlPlaygroundEntity(database, type, ArrayNode(JsonNodeFactory(false)))) } + + private fun getDatabase(userId: Int, databaseId: Int): SqlPlaygroundDatabase { + val database = databaseRepository.findByIdAndDeleted(databaseId, false) ?: throw NotFoundException() + if (database.owner.id == userId) return database + if (database.shareWithGroup?.users?.find { it.userId == userId } != null) return database + throw NotFoundException() + } } diff --git a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/group/Group.kt b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/group/Group.kt new file mode 100644 index 000000000..11167e33a --- /dev/null +++ b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/group/Group.kt @@ -0,0 +1,24 @@ +@file:Suppress("ktlint:no-wildcard-imports") + +package de.thm.ii.fbs.model.v2.group + +import javax.persistence.* + +@Entity +@Table(name = "`group`") +class Group( + @Column(nullable = false) + var courseId: Int, + @Column(nullable = false) + var name: String, + @Column(nullable = false) + var membership: Int, + @Column(nullable = false) + var visible: Boolean, + @OneToMany(mappedBy = "groupId") + var users: List, + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "group_id") + var id: Int? = null +) diff --git a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/group/UserGroup.kt b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/group/UserGroup.kt new file mode 100644 index 000000000..4aa879250 --- /dev/null +++ b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/group/UserGroup.kt @@ -0,0 +1,20 @@ +@file:Suppress("ktlint:no-wildcard-imports") + +package de.thm.ii.fbs.model.v2.group + +import java.io.Serializable +import javax.persistence.* + +@Entity +@Table(name = "user_group") +class UserGroup( + @Id + @Column(name = "group_id", nullable = false) + var groupId: Int, + @Id + @Column(name = "user_id", nullable = false) + var userId: Int, + @Id + @Column(name = "course_id", nullable = false) + var courseId: Int +) : Serializable diff --git a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/playground/SqlPlaygroundDatabase.kt b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/playground/SqlPlaygroundDatabase.kt index 553c9b592..a7ea06031 100644 --- a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/playground/SqlPlaygroundDatabase.kt +++ b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/playground/SqlPlaygroundDatabase.kt @@ -3,6 +3,7 @@ package de.thm.ii.fbs.model.v2.playground import com.fasterxml.jackson.annotation.JsonIgnore +import de.thm.ii.fbs.model.v2.group.Group import de.thm.ii.fbs.model.v2.security.User import javax.persistence.* @@ -19,6 +20,8 @@ class SqlPlaygroundDatabase( var owner: User, @Column(nullable = false) var active: Boolean = false, + @OneToOne + var shareWithGroup: Group? = null, @Column(nullable = false) @JsonIgnore var deleted: Boolean = false, diff --git a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/playground/api/SqlPlaygroundShareWithGroupRequest.kt b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/playground/api/SqlPlaygroundShareWithGroupRequest.kt new file mode 100644 index 000000000..1a51dae64 --- /dev/null +++ b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/model/v2/playground/api/SqlPlaygroundShareWithGroupRequest.kt @@ -0,0 +1,8 @@ +package de.thm.ii.fbs.model.v2.playground.api + +import com.fasterxml.jackson.annotation.JsonProperty + +data class SqlPlaygroundShareWithGroupRequest( + @JsonProperty("groupId") + var groupId: Int +) diff --git a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/GroupRepository.kt b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/GroupRepository.kt new file mode 100644 index 000000000..c310b2067 --- /dev/null +++ b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/GroupRepository.kt @@ -0,0 +1,6 @@ +package de.thm.ii.fbs.services.v2.persistence + +import de.thm.ii.fbs.model.v2.group.Group +import org.springframework.data.jpa.repository.JpaRepository + +interface GroupRepository : JpaRepository diff --git a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/SqlPlaygroundDatabaseRepository.kt b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/SqlPlaygroundDatabaseRepository.kt index 49b045289..e2183afa2 100644 --- a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/SqlPlaygroundDatabaseRepository.kt +++ b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/SqlPlaygroundDatabaseRepository.kt @@ -7,4 +7,6 @@ interface SqlPlaygroundDatabaseRepository : JpaRepository fun findByOwner_IdAndIdAndDeleted(ownerId: Int, id: Int, deleted: Boolean): SqlPlaygroundDatabase? fun findByOwner_IdAndActiveAndDeleted(ownerId: Int, active: Boolean, deleted: Boolean): SqlPlaygroundDatabase? + fun findByIdAndDeleted(id: Int, deleted: Boolean): SqlPlaygroundDatabase? + fun findByShareWithGroup(shareWithGroup: Int): SqlPlaygroundDatabase? } diff --git a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/SqlPlaygroundEntityRepository.kt b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/SqlPlaygroundEntityRepository.kt index 98b97139a..1594a91fa 100644 --- a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/SqlPlaygroundEntityRepository.kt +++ b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/SqlPlaygroundEntityRepository.kt @@ -5,4 +5,5 @@ import org.springframework.data.jpa.repository.JpaRepository interface SqlPlaygroundEntityRepository : JpaRepository { fun findByDatabase_Owner_IdAndDatabase_idAndDatabase_DeletedAndType(ownerId: Int, databaseId: Int, deleted: Boolean, type: String): SqlPlaygroundEntity? + fun findByDatabase_idAndDatabase_DeletedAndType(databaseId: Int, deleted: Boolean, type: String): SqlPlaygroundEntity? } diff --git a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/SqlPlaygroundQueryRepository.kt b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/SqlPlaygroundQueryRepository.kt index bfeb18b39..9dd2095cb 100644 --- a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/SqlPlaygroundQueryRepository.kt +++ b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/services/v2/persistence/SqlPlaygroundQueryRepository.kt @@ -6,4 +6,6 @@ import org.springframework.data.jpa.repository.JpaRepository interface SqlPlaygroundQueryRepository : JpaRepository { fun findByRunIn_Owner_IdAndRunIn_id(ownerId: Int, databaseId: Int): List fun findByRunIn_Owner_IdAndRunIn_idAndId(ownerId: Int, databaseId: Int, queryId: Int): SqlPlaygroundQuery? + fun findByRunIn_id(databaseId: Int): List + fun findByRunIn_idAndId(dbId: Int, qId: Int): SqlPlaygroundQuery? } diff --git a/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/utils/v2/exceptions/ForbiddenException.kt b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/utils/v2/exceptions/ForbiddenException.kt new file mode 100644 index 000000000..e0383a50c --- /dev/null +++ b/modules/fbs-core/api/src/main/kotlin/de/thm/ii/fbs/utils/v2/exceptions/ForbiddenException.kt @@ -0,0 +1,7 @@ +package de.thm.ii.fbs.utils.v2.exceptions + +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.ResponseStatus + +@ResponseStatus(value = HttpStatus.FORBIDDEN) +class ForbiddenException : RuntimeException("forbidden") diff --git a/modules/fbs-core/api/src/main/resources/migrations/23_playground_group_sharing.sql b/modules/fbs-core/api/src/main/resources/migrations/23_playground_group_sharing.sql new file mode 100644 index 000000000..040b790cf --- /dev/null +++ b/modules/fbs-core/api/src/main/resources/migrations/23_playground_group_sharing.sql @@ -0,0 +1,8 @@ +BEGIN; + +ALTER TABLE `fbs`.`sql_playground_database` + ADD `share_with_group_group_id` INT NULL DEFAULT NULL REFERENCES `group`(`group_id`); + +INSERT INTO migration (number) VALUES (23); + +COMMIT; diff --git a/modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/services/health/DatabaseHealthService.scala b/modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/services/health/DatabaseHealthService.scala index 25037bcb2..5c25aca30 100644 --- a/modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/services/health/DatabaseHealthService.scala +++ b/modules/fbs-core/api/src/main/scala/de/thm/ii/fbs/services/health/DatabaseHealthService.scala @@ -1,6 +1,6 @@ package de.thm.ii.fbs.services.health -import de.thm.ii.fbs.util.DB +/*import de.thm.ii.fbs.util.DB import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.actuate.health.{Health, ReactiveHealthIndicator} import org.springframework.jdbc.core.JdbcTemplate @@ -17,3 +17,4 @@ class DatabaseHealthService extends ReactiveHealthIndicator { }) } } +*/ diff --git a/modules/fbs-core/web/.eslintrc.json b/modules/fbs-core/web/.eslintrc.json index 3a3ecb7ab..c0ed95f9d 100644 --- a/modules/fbs-core/web/.eslintrc.json +++ b/modules/fbs-core/web/.eslintrc.json @@ -31,7 +31,10 @@ } ], "prettier/prettier": "warn", - "@typescript-eslint/no-unused-vars": "warn" + "@typescript-eslint/no-unused-vars": ["warn", { + "varsIgnorePattern": "^_", + "argsIgnorePattern": "^_" + }] } }, { diff --git a/modules/fbs-core/web/package-lock.json b/modules/fbs-core/web/package-lock.json index 8674625ba..4c9273248 100644 --- a/modules/fbs-core/web/package-lock.json +++ b/modules/fbs-core/web/package-lock.json @@ -24,6 +24,11 @@ "@cortex-js/compute-engine": "^0.12.2", "@fontsource/material-icons": "^4.5.4", "@fontsource/roboto": "^4.5.8", + "@hocuspocus/provider": "^2.13.5", + "@ngrx/effects": "^14.3.3", + "@ngrx/entity": "^14.3.3", + "@ngrx/store": "^14.3.3", + "@ngrx/store-devtools": "^14.3.3", "angular-i18next": "^14.2.0", "canvas-datagrid": "^0.4.5", "chart.js": "^2.9.4", @@ -38,6 +43,7 @@ "ngx-markdown": "^14.0.1", "prismjs": "^1.29.0", "xlsx": "^0.18.5", + "yjs": "^13.6.18", "zone.js": "~0.11.7" }, "devDependencies": { @@ -3362,6 +3368,49 @@ "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", "dev": true }, + "node_modules/@hocuspocus/common": { + "version": "2.13.5", + "resolved": "https://registry.npmjs.org/@hocuspocus/common/-/common-2.13.5.tgz", + "integrity": "sha512-8D9FzhZFlt0WsgXw5yT2zwSxi6z9d4V2vUz6co2vo3Cj+Y2bvGZsdDiTvU/MerGcCLME5k/w6PwLPojLYH/4pg==", + "dependencies": { + "lib0": "^0.2.87" + } + }, + "node_modules/@hocuspocus/provider": { + "version": "2.13.5", + "resolved": "https://registry.npmjs.org/@hocuspocus/provider/-/provider-2.13.5.tgz", + "integrity": "sha512-G3S0OiFSYkmbOwnbhV7FyJs4OBqB/+1YT9c44Ujux1RKowGm5H8+0p3FUHfXwd/3v9V0jE+E1FnFKoGonJSQwA==", + "dependencies": { + "@hocuspocus/common": "^2.13.5", + "@lifeomic/attempt": "^3.0.2", + "lib0": "^0.2.87", + "ws": "^8.17.1" + }, + "peerDependencies": { + "y-protocols": "^1.0.6", + "yjs": "^13.6.8" + } + }, + "node_modules/@hocuspocus/provider/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.9.5", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", @@ -3484,6 +3533,81 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "dev": true }, + "node_modules/@lifeomic/attempt": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@lifeomic/attempt/-/attempt-3.1.0.tgz", + "integrity": "sha512-QZqem4QuAnAyzfz+Gj5/+SLxqwCAw2qmt7732ZXodr6VDWGeYLG6w1i/vYLa55JQM9wRuBKLmXmiZ2P0LtE5rw==" + }, + "node_modules/@ngrx/effects": { + "version": "14.3.3", + "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-14.3.3.tgz", + "integrity": "sha512-bP7rIHlu1KAj5Wm0TWR7Q8VlOQOBu8uiN/fDP3Lqi8FwVW6HOq9eBGcFwJGyqwVAmulsvLFB68MhpMYg2W78+w==", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/core": "^14.0.0", + "@ngrx/store": "14.3.3", + "rxjs": "^6.5.3 || ^7.5.0" + } + }, + "node_modules/@ngrx/effects/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/@ngrx/entity": { + "version": "14.3.3", + "resolved": "https://registry.npmjs.org/@ngrx/entity/-/entity-14.3.3.tgz", + "integrity": "sha512-UWSJg2WknLxstT/c9axVY8N3XGSgmY3fPcngPZvsyVjCo7pS/LMeh2/+F6pmQeWfTr/CdHsY1iLBJkjhAjHpYg==", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/core": "^14.0.0", + "@ngrx/store": "14.3.3", + "rxjs": "^6.5.3 || ^7.5.0" + } + }, + "node_modules/@ngrx/entity/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/@ngrx/store": { + "version": "14.3.3", + "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-14.3.3.tgz", + "integrity": "sha512-VhPDR2a5OQJfrVRah3vdJgL/F6UC8NU/X7lxKFqBW3NC+pmlIeFO/y8jLrZOKBXwG45tY9wrg15S70nEGoZtHA==", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/core": "^14.0.0", + "rxjs": "^6.5.3 || ^7.5.0" + } + }, + "node_modules/@ngrx/store-devtools": { + "version": "14.3.3", + "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-14.3.3.tgz", + "integrity": "sha512-YQFFKYRnmREHCUb0aAaAgSXWKjZqV+5pmzsjW6HZ0GTKoy9R3JI7Miw0gplwkJpLO7Z3AFCuLQIpTs5ryAOwPQ==", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@ngrx/store": "14.3.3", + "rxjs": "^6.5.3 || ^7.5.0" + } + }, + "node_modules/@ngrx/store-devtools/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/@ngrx/store/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, "node_modules/@ngtools/webpack": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.1.0.tgz", @@ -9896,6 +10020,15 @@ "node": ">=0.10.0" } }, + "node_modules/isomorphic.js": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/isomorphic.js/-/isomorphic.js-0.2.5.tgz", + "integrity": "sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==", + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -10589,6 +10722,26 @@ "node": ">= 0.8.0" } }, + "node_modules/lib0": { + "version": "0.2.94", + "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.94.tgz", + "integrity": "sha512-hZ3p54jL4Wpu7IOg26uC7dnEWiMyNlUrb9KoG7+xYs45WkQwpVvKFndVq2+pqLYKe1u8Fp3+zAfZHVvTK34PvQ==", + "dependencies": { + "isomorphic.js": "^0.2.4" + }, + "bin": { + "0ecdsa-generate-keypair": "bin/0ecdsa-generate-keypair.js", + "0gentesthtml": "bin/gentesthtml.js", + "0serve": "bin/0serve.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/license-webpack-plugin": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", @@ -16391,6 +16544,26 @@ "node": ">=4.0" } }, + "node_modules/y-protocols": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/y-protocols/-/y-protocols-1.0.6.tgz", + "integrity": "sha512-vHRF2L6iT3rwj1jub/K5tYcTT/mEYDUppgNPXwp8fmLpui9f7Yeq3OEtTLVF012j39QnV+KEQpNqoN7CWU7Y9Q==", + "peer": true, + "dependencies": { + "lib0": "^0.2.85" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + }, + "peerDependencies": { + "yjs": "^13.0.0" + } + }, "node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", @@ -16448,6 +16621,22 @@ "node": ">=10" } }, + "node_modules/yjs": { + "version": "13.6.18", + "resolved": "https://registry.npmjs.org/yjs/-/yjs-13.6.18.tgz", + "integrity": "sha512-GBTjO4QCmv2HFKFkYIJl7U77hIB1o22vSCSQD1Ge8ZxWbIbn8AltI4gyXbtL+g5/GJep67HCMq3Y5AmNwDSyEg==", + "dependencies": { + "lib0": "^0.2.86" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/modules/fbs-core/web/package.json b/modules/fbs-core/web/package.json index 51e0b9af3..f28b1aee3 100644 --- a/modules/fbs-core/web/package.json +++ b/modules/fbs-core/web/package.json @@ -29,6 +29,11 @@ "@cortex-js/compute-engine": "^0.12.2", "@fontsource/material-icons": "^4.5.4", "@fontsource/roboto": "^4.5.8", + "@hocuspocus/provider": "^2.13.5", + "@ngrx/effects": "^14.3.3", + "@ngrx/entity": "^14.3.3", + "@ngrx/store": "^14.3.3", + "@ngrx/store-devtools": "^14.3.3", "angular-i18next": "^14.2.0", "canvas-datagrid": "^0.4.5", "chart.js": "^2.9.4", @@ -43,6 +48,7 @@ "ngx-markdown": "^14.0.1", "prismjs": "^1.29.0", "xlsx": "^0.18.5", + "yjs": "^13.6.18", "zone.js": "~0.11.7" }, "devDependencies": { diff --git a/modules/fbs-core/web/proxy.config.json b/modules/fbs-core/web/proxy.config.json index ceac9958c..22953e919 100644 --- a/modules/fbs-core/web/proxy.config.json +++ b/modules/fbs-core/web/proxy.config.json @@ -1,6 +1,6 @@ { "/api/**": { - "target": "https://127.0.0.1:443", + "target": "https://127.0.0.1:8443", "secure": false, "logLevel": "debug", "changeOrigin": true diff --git a/modules/fbs-core/web/src/app/app.module.ts b/modules/fbs-core/web/src/app/app.module.ts index 850260010..389431abf 100644 --- a/modules/fbs-core/web/src/app/app.module.ts +++ b/modules/fbs-core/web/src/app/app.module.ts @@ -87,23 +87,9 @@ import { SqlCheckerComponent } from "./page-components/sql-checker/sql-checker.c import { SqlCheckerResultsComponent } from "./page-components/sql-checker/sql-checker-results/sql-checker-results.component"; import { MatTableModule } from "@angular/material/table"; import { MatSortModule } from "@angular/material/sort"; -import { SqlPlaygroundComponent } from "./page-components/sql-playground/sql-playground.component"; import { AnalyticsToolComponent } from "./page-components/analytics-tool/analytics-tool.component"; -import { BorderedContainerComponent } from "./page-components/bordered-container/bordered-container.component"; -import { DynamicResultTableComponent } from "./page-components/sql-playground/dynamic-result-table/dynamic-result-table.component"; -import { DbControlPanelComponent } from "./page-components/sql-playground/db-control-panel/db-control-panel.component"; -import { SqlInputTabsComponent } from "./page-components/sql-playground/sql-input-tabs/sql-input-tabs.component"; -import { DbSchemeComponent } from "./page-components/sql-playground/db-scheme/db-scheme.component"; -import { DbSchemeViewsComponent } from "./page-components/sql-playground/db-scheme/db-scheme-views/db-scheme-views.component"; -import { DbSchemeTriggersComponent } from "./page-components/sql-playground/db-scheme/db-scheme-triggers/db-scheme-triggers.component"; -import { DbSchemeRoutinesComponent } from "./page-components/sql-playground/db-scheme/db-scheme-routines/db-scheme-routines.component"; -import { DbSchemeTablesComponent } from "./page-components/sql-playground/db-scheme/db-scheme-tables/db-scheme-tables.component"; -import { DbControlTemplatesComponent } from "./page-components/sql-playground/db-control-panel/db-control-templates/db-control-templates.component"; -import { DbControlCoWorkingComponent } from "./page-components/sql-playground/db-control-panel/db-control-co-working/db-control-co-working.component"; -import { DbControlDbOverviewComponent } from "./page-components/sql-playground/db-control-panel/db-control-db-overview/db-control-db-overview.component"; import { NewSqlTemplateComponent } from "./dialogs/new-sql-template/new-sql-template.component"; import { ExportTasksDialogComponent } from "./dialogs/export-tasks-dialog/export-tasks-dialog.component"; -import { HighlightedInputComponent } from "./page-components/sql-playground/sql-input-tabs/highlighted-input/highlighted-input.component"; import "mathlive"; import "@cortex-js/compute-engine"; @@ -117,6 +103,7 @@ import { LanguageMenuComponent } from "./page-components/sidebar/language-menu/l import { registerLocaleData } from "@angular/common"; import localeDe from "@angular/common/locales/de"; import localeDeExtra from "@angular/common/locales/extra/de"; +import { SqlPlaygroundModule } from "./page-components/sql-playground/sql-playground.module"; import { MyGroupsComponent } from "./page-components/my-groups/my-groups.component"; import { GroupSelectionComponent } from "./page-components/course-detail/group-selection/group-selection.component"; import { NewGroupDialogComponent } from "./dialogs/new-group-dialog/new-group-dialog.component"; @@ -203,24 +190,10 @@ export const httpInterceptorProviders = [ SqlCheckerComponent, SqlCheckerResultsComponent, TextConfirmDialogComponent, - SqlPlaygroundComponent, AnalyticsToolComponent, - BorderedContainerComponent, - DynamicResultTableComponent, - DbControlPanelComponent, - SqlInputTabsComponent, - DbSchemeComponent, - DbSchemeViewsComponent, - DbSchemeTriggersComponent, - DbSchemeRoutinesComponent, - DbSchemeTablesComponent, NewDbDialogComponent, - DbControlTemplatesComponent, - DbControlCoWorkingComponent, - DbControlDbOverviewComponent, NewSqlTemplateComponent, ExportTasksDialogComponent, - HighlightedInputComponent, MathInputComponent, SharePlaygroundLinkDialogComponent, FbsModellingComponent, @@ -267,6 +240,7 @@ export const httpInterceptorProviders = [ MatTableModule, MatSortModule, I18NextModule.forRoot(), + SqlPlaygroundModule, ], entryComponents: [ DataprivacyDialogComponent, diff --git a/modules/fbs-core/web/src/app/model/ResultTab.ts b/modules/fbs-core/web/src/app/model/ResultTab.ts index e0ae5efed..aa26c01bc 100644 --- a/modules/fbs-core/web/src/app/model/ResultTab.ts +++ b/modules/fbs-core/web/src/app/model/ResultTab.ts @@ -1,10 +1,8 @@ -import { MatTableDataSource } from "@angular/material/table"; - export interface ResultTab { - id: number; + id: string; name: string; error?: boolean; errorMsg?: string; - dataSource?: MatTableDataSource; + resultset?: any; displayedColumns?: string[]; } diff --git a/modules/fbs-core/web/src/app/model/sql_playground/QueryTab.ts b/modules/fbs-core/web/src/app/model/sql_playground/QueryTab.ts index 851f9abb1..7ee24301f 100644 --- a/modules/fbs-core/web/src/app/model/sql_playground/QueryTab.ts +++ b/modules/fbs-core/web/src/app/model/sql_playground/QueryTab.ts @@ -1,7 +1,9 @@ import { Course } from "../Course"; import { Task } from "../Task"; +import { BackendUser } from "../../page-components/sql-playground/collab/backend.service"; export interface QueryTab { + id: string; name: string; content: string; error: boolean; @@ -13,4 +15,18 @@ export interface QueryTab { selectedTask: Task; selectedCourseName: string; selectedTaskName: string; + active: BackendUser[]; +} + +export function queryTabEquals( + a: Partial, + b: Partial +): boolean { + return ( + typeof a === "object" && + typeof b === "object" && + a.id === b.id && + a.name === b.name && + a.content === b.content + ); } diff --git a/modules/fbs-core/web/src/app/page-components/bordered-container/bordered-container.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/bordered-container/bordered-container.component.html similarity index 100% rename from modules/fbs-core/web/src/app/page-components/bordered-container/bordered-container.component.html rename to modules/fbs-core/web/src/app/page-components/sql-playground/bordered-container/bordered-container.component.html diff --git a/modules/fbs-core/web/src/app/page-components/bordered-container/bordered-container.component.scss b/modules/fbs-core/web/src/app/page-components/sql-playground/bordered-container/bordered-container.component.scss similarity index 100% rename from modules/fbs-core/web/src/app/page-components/bordered-container/bordered-container.component.scss rename to modules/fbs-core/web/src/app/page-components/sql-playground/bordered-container/bordered-container.component.scss diff --git a/modules/fbs-core/web/src/app/page-components/bordered-container/bordered-container.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/bordered-container/bordered-container.component.ts similarity index 100% rename from modules/fbs-core/web/src/app/page-components/bordered-container/bordered-container.component.ts rename to modules/fbs-core/web/src/app/page-components/sql-playground/bordered-container/bordered-container.component.ts diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/collab/backend.service.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/collab/backend.service.ts new file mode 100644 index 000000000..33bb2f5dc --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/collab/backend.service.ts @@ -0,0 +1,265 @@ +import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; +import { first } from "rxjs/operators"; +import { QueryTab } from "../../../model/sql_playground/QueryTab"; +import { Store } from "@ngrx/store"; +import { selectBackend } from "../state/sql-playground.selectors"; +import { LocalBackend } from "./local.backend"; +import { CollaborativeBackend } from "./collab.backend"; +import * as SqlInputTabsActions from "../sql-input-tabs/state/sql-input-tabs.actions"; +import { + selectActiveTab, + selectTabs as selectInputTabs, +} from "../sql-input-tabs/state/sql-input-tabs.selectors"; +import { AuthService } from "../../../service/auth.service"; +import { setDatabaseInformation } from "../state/sql-playground.actions"; + +export interface Identity { + id: I; +} + +export interface Tab { + id: string; + title: string; +} + +export interface ResultTab extends Tab {} + +export type ChangeEvent, I = T["id"]> = + | { event: "create"; payload: T } + | { event: "update"; payload: Partial & { id: I } } + | { event: "delete"; id: I }; + +export type BackendUser = { id: string; color: string }; + +export type AwarenessState = { user: BackendUser; stateId: string }; + +export type DatabaseInformation = { id: number; name: string; owner: string }; + +export type BackendDefintion = + | { type: "local" } + | { type: "collaborative"; id: string; database?: DatabaseInformation }; + +export interface Backend { + setMeta(databaseInformation: DatabaseInformation): Observable; + streamMetaChanges(): Observable<{ key: string; value: any }>; + streamInputChanges(): Observable>; + streamResultChanges(): Observable>; + emitInputChange(event: ChangeEvent): Observable; + emitResultChange(event: ChangeEvent): Observable; + announceSelectedInput(id: string): Observable; + streamSelectedInputs(): Observable; +} + +@Injectable({ providedIn: "root" }) +export class BackendService { + private i: number = 0; + private currentBackend: Backend; + private knowInputState: QueryTab[] = []; + private currentType?: string; + + constructor(private store: Store, private authService: AuthService) {} + + private findTabIndex(tabs: any[], id: string): number { + return tabs.findIndex((tab) => tab.id === id); + } + + setupBackendHandler() { + this.store.select(selectBackend).subscribe((backend) => { + if (this.currentType === backend.type) return; + this.currentType = backend.type; + if (backend.type === "local") { + this.currentBackend = new LocalBackend(); + } else if (backend.type === "collaborative") { + this.currentBackend = new CollaborativeBackend( + backend.id, + this.authService.getToken().username, + this.authService.loadToken() + ); + this.currentBackend.streamMetaChanges().subscribe(({ key, value }) => { + if (key === "database") { + this.store.dispatch( + setDatabaseInformation({ databaseInformation: value }) + ); + } + }); + if (backend.database) this.currentBackend.setMeta(backend.database); + } + + /*this.store.dispatch(SqlInputTabsActions.closeAllTabs()); + this.store.dispatch(DynamicResultTableActions.closeTab({ index: -1 })); // Close all tabs*/ + + this.currentBackend.streamInputChanges().subscribe((change) => { + /*if (this.i > 10) { + return; + }*/ + + this.i++; + this.store + .select(selectInputTabs) + .pipe(first()) + .subscribe((tabs) => { + switch (change.event) { + case "create": + const existingIndex = this.findTabIndex( + tabs, + change.payload.id + ); + if (existingIndex === -1) { + this.store.dispatch( + SqlInputTabsActions.addTab({ tab: change.payload }) + ); + this.knowInputState.push(change.payload); + } + break; + case "update": + const updateIndex = this.findTabIndex(tabs, change.payload.id); + if ( + updateIndex !== -1 && + tabs[updateIndex].content !== change.payload.content + ) { + this.store.dispatch( + SqlInputTabsActions.updateTabContent({ + index: updateIndex, + content: change.payload.content, + }) + ); + } else if ( + updateIndex !== -1 && + tabs[updateIndex].name !== change.payload.name + ) { + this.store.dispatch( + SqlInputTabsActions.updateTabName({ + index: updateIndex, + name: change.payload.name, + }) + ); + } + break; + case "delete": + const deleteIndex = this.findTabIndex(tabs, change.id); + if (deleteIndex !== -1) { + this.store.dispatch( + SqlInputTabsActions.closeTab({ index: deleteIndex }) + ); + this.knowInputState = this.knowInputState.filter( + (tab) => tab.id !== change.id + ); + } + break; + } + }); + }); + + /*this.currentBackend.streamResultChanges().subscribe((change) => { + this.store + .select(selectResultTabs) + .pipe(first()) + .subscribe((resultTabs) => { + switch (change.event) { + case "create": + this.store.dispatch(DynamicResultTableActions.addTab()); + // Assuming the last added tab is the one we just created + const newIndex = resultTabs.length; + this.store.dispatch( + DynamicResultTableActions.updateResultset({ + resultset: { ...change.payload, index: newIndex }, + }) + ); + break; + case "update": + const updateIndex = this.findTabIndex( + resultTabs, + change.payload.id + ); + if ( + updateIndex !== -1 && + resultTabs[updateIndex].resultset !== change.payload + ) { + this.store.dispatch( + DynamicResultTableActions.updateResultset({ + resultset: { ...change.payload, index: updateIndex }, + }) + ); + } + break; + case "delete": + const deleteIndex = this.findTabIndex(resultTabs, change.id); + if (deleteIndex !== -1) { + this.store.dispatch( + DynamicResultTableActions.closeTab({ index: deleteIndex }) + ); + } + break; + } + }); + });*/ + + this.store.select(selectInputTabs).subscribe((inputTabs) => { + inputTabs.forEach((tab) => { + const known = + this.knowInputState && + Boolean( + this.knowInputState.find((knownTab) => knownTab.id === tab.id) + ); + this.currentBackend + .emitInputChange({ + event: known ? "update" : "create", + payload: tab, + }) + .subscribe(() => {}); + }); + if (this.knowInputState) + this.knowInputState.forEach((knownTab) => { + const exists = Boolean( + inputTabs.find((tab) => tab.id === knownTab.id) + ); + if (!exists) + this.currentBackend + .emitInputChange({ + event: "delete", + id: knownTab.id, + }) + .subscribe(() => {}); + }); + this.knowInputState = inputTabs; + }); + + this.store.select(selectActiveTab).subscribe((activeTab) => { + if (activeTab) + this.currentBackend + .announceSelectedInput(activeTab.id) + .subscribe(() => {}); + }); + + this.currentBackend + .streamSelectedInputs() + .subscribe((awarenessStates) => { + this.store.dispatch( + SqlInputTabsActions.updateActiveTabUsers({ awarenessStates }) + ); + }); + + setTimeout(() => { + this.store + .select(selectInputTabs) + .pipe(first()) + .subscribe((inputTabs) => { + if (inputTabs.length === 0) + this.store.dispatch(SqlInputTabsActions.addTab({})); + }); + }, 1000); + + /*this.store.select(selectResultTabs).subscribe((resultTabs) => { + resultTabs.forEach((tab) => { + this.currentBackend + .emitResultChange({ + event: "update", + payload: { id: tab.id, ...tab }, + }) + .subscribe(() => {}); + }); + });*/ + }); + } +} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/collab/collab.backend.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/collab/collab.backend.ts new file mode 100644 index 000000000..459cd866b --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/collab/collab.backend.ts @@ -0,0 +1,197 @@ +import * as Y from "yjs"; +import { HocuspocusProvider } from "@hocuspocus/provider"; +import { + Backend, + ChangeEvent, + ResultTab, + AwarenessState, + BackendUser, + DatabaseInformation, +} from "./backend.service"; +import { Observable, of } from "rxjs"; +import { + QueryTab, + queryTabEquals, +} from "src/app/model/sql_playground/QueryTab"; + +export class CollaborativeBackend implements Backend { + private provider: HocuspocusProvider; + private yDoc: Y.Doc; + private metaMap: Y.Map; + private inputMap: Y.Map; + private resultMap: Y.Map; + private me: BackendUser; + + constructor( + readonly id: string, + readonly username: string, + private readonly token: string + ) { + this.provider = new HocuspocusProvider({ + url: + window.location.hostname === "localhost" + ? "ws://127.0.0.1:1234" + : "wss://feedback.mni.thm.de/collab", + name: id, + token, + }); + this.yDoc = this.provider.document; + this.metaMap = this.yDoc.getMap("meta"); + this.inputMap = this.yDoc.getMap("inputs"); + this.resultMap = this.yDoc.getMap("results"); + this.me = { + id: username, + color: "#" + Math.floor(Math.random() * 16777215).toString(16), + }; + this.provider.awareness.setLocalStateField("user", this.me); + } + + setMeta(databaseInformation: DatabaseInformation): Observable { + this.metaMap.set("database", databaseInformation); + return of(); + } + + streamInputChanges(): Observable> { + return new Observable>((observer) => { + const handler = (event: Y.YMapEvent) => { + event.changes.keys.forEach((change, key) => { + let changeEvent: ChangeEvent; + if (change.action === "add") { + changeEvent = { + event: "create", + payload: this.inputMap.get(key) as QueryTab, + }; + } else if (change.action === "update") { + changeEvent = { + event: "update", + payload: { + id: key, + ...this.inputMap.get(key), + }, + }; + } else if (change.action === "delete") { + changeEvent = { + event: "delete", + id: key, + }; + } + observer.next(changeEvent); + }); + }; + + this.inputMap.observe(handler); + + return () => { + this.inputMap.unobserve(handler); + }; + }); + } + + streamResultChanges(): Observable> { + return new Observable>((observer) => { + const handler = (event: Y.YMapEvent) => { + event.changes.keys.forEach((change, key) => { + let changeEvent: ChangeEvent; + if (change.action === "add") { + changeEvent = { + event: "create", + payload: this.resultMap.get(key) as ResultTab, + }; + } else if (change.action === "update") { + changeEvent = { + event: "update", + payload: { + id: key, + ...this.resultMap.get(key), + }, + }; + } else if (change.action === "delete") { + changeEvent = { + event: "delete", + id: key, + }; + } + observer.next(changeEvent); + }); + }; + + this.resultMap.observe(handler); + + return () => { + this.resultMap.unobserve(handler); + }; + }); + } + + emitInputChange(event: ChangeEvent): Observable { + return new Observable((observer) => { + this.yDoc.transact(() => { + if (event.event === "create" || event.event === "update") { + const currentState = this.inputMap.get(event.payload.id); + if (!queryTabEquals(currentState, event.payload)) { + this.inputMap.set(event.payload.id, event.payload as QueryTab); + } + } else if (event.event === "delete") { + this.inputMap.delete(event.id); + } + }); + observer.next(); + observer.complete(); + }); + } + + emitResultChange(event: ChangeEvent): Observable { + return new Observable((observer) => { + this.yDoc.transact(() => { + if (event.event === "create" || event.event === "update") { + this.resultMap.set(event.payload.id, event.payload as ResultTab); + } else if (event.event === "delete") { + this.resultMap.delete(event.id); + } + }); + observer.next(); + observer.complete(); + }); + } + + announceSelectedInput(id: string): Observable { + return new Observable((observer) => { + this.provider.awareness.setLocalStateField("currentInputTab", id); + + observer.next(); + observer.complete(); + }); + } + streamSelectedInputs(): Observable { + return new Observable((observer) => { + this.provider.awareness.on("change", () => { + observer.next( + Array.from(this.provider.awareness.getStates().values()) + .filter(({ user }) => user.id !== this.me.id) + .map(({ user, currentInputTab }) => { + return { user, stateId: currentInputTab }; + }) + ); + }); + }); + } + + streamMetaChanges(): Observable { + return new Observable<{ key: string; value: any }>((observer) => { + const handler = (event: Y.YMapEvent) => { + event.changes.keys.forEach((change, key) => { + observer.next({ + key, + value: this.metaMap.get(key), + }); + }); + }; + + this.metaMap.observe(handler); + + return () => { + this.metaMap.unobserve(handler); + }; + }); + } +} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/collab/local.backend.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/collab/local.backend.ts new file mode 100644 index 000000000..673c195ba --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/collab/local.backend.ts @@ -0,0 +1,66 @@ +import { from, Observable, of } from "rxjs"; +import { + Backend, + ChangeEvent, + ResultTab, + AwarenessState, + DatabaseInformation, +} from "./backend.service"; +import { QueryTab } from "../../../model/sql_playground/QueryTab"; + +export class LocalBackend implements Backend { + setMeta(_databaseInformation: DatabaseInformation): Observable { + return undefined; + } + streamInputChanges(): Observable> { + return from( + this.loadLocalStorage().map( + (qt) => ({ event: "create", payload: qt } as ChangeEvent) + ) + ); + } + streamResultChanges(): Observable> { + return of(); + } + emitInputChange(event: ChangeEvent): Observable { + const currentState = this.loadLocalStorage(); + if (event.event === "create") { + currentState.push(event.payload); + } else if (event.event === "update") { + for (const entry of currentState) { + if (entry.id === event.payload.id) { + Object.assign(entry, event.payload); + } + } + } else if (event.event === "delete") { + let i = 0; + for (const entry of currentState) { + if (entry.id === event.id) { + currentState.splice(i, 1); + break; + } + i++; + } + } + localStorage.setItem("tabs", JSON.stringify({ tabs: currentState })); + return of(); + } + emitResultChange(_event: ChangeEvent): Observable { + return of(); + } + announceSelectedInput(_id: string): Observable { + return of(); + } + streamSelectedInputs(): Observable { + return of(); + } + + private loadLocalStorage(): QueryTab[] { + const loadedData = localStorage.getItem("tabs"); + return JSON.parse(loadedData)?.tabs ?? []; + } + + streamMetaChanges(): Observable<{ key: string; value: any }> { + return of(); + } +} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-co-working/db-control-co-working.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-co-working/db-control-co-working.component.html index 9a082f2af..33e00e3e3 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-co-working/db-control-co-working.component.html +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-co-working/db-control-co-working.component.html @@ -3,13 +3,9 @@ {{ "sql-playground.db-control-panel.co-working.select-group" | i18nextEager }} - - - {{ group.name }} + + + {{ db.name }} @@ -18,41 +14,37 @@ "sql-playground.db-control-panel.co-working.select-database" | i18nextEager }} - - + + {{ db.name }}
- +
diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-co-working/db-control-co-working.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-co-working/db-control-co-working.component.ts index 422a683ca..e9d3199a2 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-co-working/db-control-co-working.component.ts +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-co-working/db-control-co-working.component.ts @@ -1,13 +1,22 @@ -import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; +import { Store } from "@ngrx/store"; import { Observable } from "rxjs"; import { Database } from "../../../../model/sql_playground/Database"; import { MatSnackBar } from "@angular/material/snack-bar"; import { AuthService } from "src/app/service/auth.service"; -import { SqlPlaygroundService } from "src/app/service/sql-playground.service"; -import { JWTToken } from "src/app/model/JWTToken"; -import { TextConfirmDialogComponent } from "../../../../dialogs/text-confirm-dialog/text-confirm-dialog.component"; -import { NewDbDialogComponent } from "../../../../dialogs/new-db-dialog/new-db-dialog.component"; import { MatDialog } from "@angular/material/dialog"; +import { loadDatabases } from "src/app/page-components/sql-playground/db-control-panel/state/databases.actions"; +import { + selectAllDatabases, + selectDatabasesError, +} from "src/app/page-components/sql-playground/db-control-panel/state/databases.selectors"; +import { setBackend } from "../../state/sql-playground.actions"; +import { loadGroups } from "../state/groups.actions"; +import { selectAllGroups } from "../state/groups.selector"; +import { Group } from "../../../../model/Group"; +import { SqlPlaygroundService } from "../../../../service/sql-playground.service"; +import { selectBackend } from "../../state/sql-playground.selectors"; +import { BackendDefintion } from "../../collab/backend.service"; @Component({ selector: "app-db-control-co-working", @@ -15,200 +24,77 @@ import { MatDialog } from "@angular/material/dialog"; styleUrls: ["./db-control-co-working.component.scss"], }) export class DbControlCoWorkingComponent implements OnInit { - @Input() collaborativeMode: boolean; - @Output() collaborativeModeChange = new EventEmitter(); + databases$: Observable; + groups$: Observable; + error$: Observable; + backend$: Observable; + selectedDatabase: number = 0; + selectedGroup: number = 0; + token = this.authService.getToken(); + pending: boolean = false; + + groups: Group[]; - @Output() changeActiveDb = new EventEmitter(); + collaborativeMode: boolean = false; constructor( + private store: Store, private snackbar: MatSnackBar, private authService: AuthService, - private sqlPlaygroundService: SqlPlaygroundService, - private dialog: MatDialog + private dialog: MatDialog, + private playgroundService: SqlPlaygroundService ) {} - dbs: Database[] = []; - activeDb: Database; - selectedDb: number = 0; - token: JWTToken = this.authService.getToken(); - pending: boolean = false; - - selectedDbGroup: number = 0; - groups: any[] = [ - { id: 0, name: "Gruppe 1" }, - { id: 1, name: "Gruppe 2" }, - ]; - ngOnInit(): void { - this.sqlPlaygroundService.getDatabases(this.token.id).subscribe( - (data) => { - this.dbs = data; - - if (this.dbs.length == 0) { - // create default database if none exists - this.createDatabase("Standard Datenbank").subscribe((result) => { - if (result != null) { - this.activeDb = this.getActiveDb(this.dbs); - this.selectedDb = this.activeDb.id; - } - }); - } else if (this.getActiveDb(this.dbs) == null) { - this.activeDb = this.dbs[0]; - this.selectedDb = this.activeDb.id; - this.activateDb(this.selectedDb); - } else { - this.activeDb = this.getActiveDb(this.dbs); - this.selectedDb = this.activeDb.id; - } - this.changeActiveDb.emit(this.activeDb); - }, - (error) => { - console.log(error); - this.snackbar.open("Fehler beim Laden der Datenbanken", "Ok", { - duration: 3000, - }); - } - ); - } - - changeCollaborativeMode() { - this.collaborativeModeChange.emit(!this.collaborativeMode); - } - - getActiveDb(dbs: Database[]): Database { - const activeDB = dbs.find((db) => db.active == true); - if (activeDB !== undefined) { - return activeDB; - } else { - return null; - } - } - - isSelectDbActive(): boolean { - if (this.activeDb !== undefined) { - return this.selectedDb == this.activeDb.id; - } else { - return false; - } - } - - createDatabase(name: string): Observable { - this.sqlPlaygroundService.createDatabase(this.token.id, name).subscribe( - (data) => { - this.snackbar.open("Datenbank erfolgreich erstellt", "Ok", { - duration: 3000, - }); - this.ngOnInit(); - return data; - }, - (error) => { - console.log(error); - this.snackbar.open("Fehler beim Erstellen der Datenbank", "Ok", { - duration: 3000, - }); - } - ); - return null; - } - - deleteDatabase() { - const selectedDb = this.dbs.find((db) => db.id == this.selectedDb); - - this.openTextConfirmDialog( - "Datenbank löschen", - "Möchten Sie die Datenbank wirklich löschen?", - `${selectedDb.name}` - ).subscribe((result) => { - if (result === true) { - this.sqlPlaygroundService - .deleteDatabase(this.token.id, selectedDb.id) - .subscribe( - () => { - this.snackbar.open( - `Datenbank ${selectedDb.name} erfolgreich gelöscht`, - "Ok", - { - duration: 3000, - } - ); - this.ngOnInit(); - }, - (error) => { - console.log(error); - this.snackbar.open("Fehler beim Löschen der Datenbank", "Ok", { - duration: 3000, - }); - } - ); - } + this.store.dispatch(loadDatabases()); + this.store.dispatch(loadGroups()); + this.databases$ = this.store.select(selectAllDatabases); + this.groups$ = this.store.select(selectAllGroups); + this.error$ = this.store.select(selectDatabasesError); + this.backend$ = this.store.select(selectBackend); + this.groups$.subscribe((groups) => { + this.groups = groups; }); } - activateDb(dbId: number) { - this.pending = true; - const selectedDb = this.dbs.find((db) => db.id == dbId); - - this.sqlPlaygroundService - .activateDatabase(this.token.id, selectedDb.id) - .subscribe( - () => { - this.snackbar.open( - `Datenbank ${selectedDb.name} erfolgreich aktiviert`, - "Ok", - { - duration: 3000, - } - ); - this.ngOnInit(); - this.pending = false; - }, - (error) => { - console.log(error); - this.snackbar.open("Fehler beim Aktivieren der Datenbank", "Ok", { - duration: 3000, - }); - this.pending = false; - } - ); + disconect() { + this.store.dispatch(setBackend({ backend: { type: "local" } })); } - private openTextConfirmDialog( - title: string, - message: string, - textToRepeat: string - ) { - const dialogRef = this.dialog.open(TextConfirmDialogComponent, { - data: { - title: title, - message: message, - textToRepeat: textToRepeat, - }, + create() { + this.databases$.subscribe((dbs) => { + const database = dbs.find(({ id }) => id === this.selectedDatabase); + this.playgroundService + .shareWithGroup( + this.authService.getToken().id, + this.selectedDatabase, + this.selectedGroup + ) + .subscribe(() => { + this.store.dispatch( + setBackend({ + backend: { + type: "collaborative", + id: this.selectedGroup.toString(), + database: { + id: database.id, + name: database.name, + owner: this.authService.getToken().username, + }, + }, + }) + ); + this.collaborativeMode = true; + }); }); - return dialogRef.afterClosed(); } - addDb() { - this.dialog - .open(NewDbDialogComponent, { - height: "auto", - width: "50%", - data: { - token: this.token, - }, + join() { + this.store.dispatch( + setBackend({ + backend: { type: "collaborative", id: this.selectedGroup.toString() }, }) - .afterClosed() - .subscribe((res) => { - if (res.success) { - this.ngOnInit(); - this.snackbar.open("Datenbank erfolgreich erstellt", "Ok", { - duration: 3000, - }); - } else { - this.snackbar.open("Fehler beim Erstellen der Datenbank", "Ok", { - duration: 3000, - }); - } - }); + ); } activateGroup(groupId: number) { diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-db-overview/db-control-db-overview.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-db-overview/db-control-db-overview.component.html index 0b68c3a0a..0afe4e7c3 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-db-overview/db-control-db-overview.component.html +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-db-overview/db-control-db-overview.component.html @@ -1,70 +1,79 @@
-
-

- {{ "sql-playground.db-control-panel.overview.version" | i18nextEager }}: - - {{ this.activeDb.version }} - -    -

-
- - - {{ - "sql-playground.db-control-panel.overview.selectDatabase" | i18nextEager - }} - - - {{ db.name }} - - - -
- - - - +
+
+

+ {{ "sql-playground.db-control-panel.overview.version" | i18nextEager }}: + {{ activeDb[0]?.version }} +    +

+
- + + {{ + "sql-playground.db-control-panel.overview.selectDatabase" | i18nextEager + }} + + + {{ db.name }} + + + +
+ + + + +
+
+
+

Sie sind mit dem Co-Working verbunden.

+

+ Datenbankname: {{ databaseInformation?.name ?? "-" }}
+ Datenbankursprung: {{ databaseInformation?.owner ?? "-" }} +

+

+ Bitte verwenden Sie das Co-Working-Tab, wenn Sie die Verbindung trennen + wollen. +

diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-db-overview/db-control-db-overview.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-db-overview/db-control-db-overview.component.ts index 35ff47d6f..f6ddf91ff 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-db-overview/db-control-db-overview.component.ts +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-db-overview/db-control-db-overview.component.ts @@ -1,14 +1,33 @@ -import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; +import { Store } from "@ngrx/store"; import { Observable } from "rxjs"; import { Database } from "../../../../model/sql_playground/Database"; import { MatSnackBar } from "@angular/material/snack-bar"; import { AuthService } from "src/app/service/auth.service"; -import { SqlPlaygroundService } from "src/app/service/sql-playground.service"; -import { JWTToken } from "src/app/model/JWTToken"; +import { MatDialog } from "@angular/material/dialog"; import { TextConfirmDialogComponent } from "../../../../dialogs/text-confirm-dialog/text-confirm-dialog.component"; import { NewDbDialogComponent } from "../../../../dialogs/new-db-dialog/new-db-dialog.component"; -import { MatDialog } from "@angular/material/dialog"; import { SharePlaygroundLinkDialogComponent } from "src/app/dialogs/share-playground-link-dialog/share-playground-link-dialog.component"; +import { + loadDatabases, + createDatabase, + deleteDatabase, + activateDatabase, +} from "src/app/page-components/sql-playground/db-control-panel/state/databases.actions"; +import { + selectAllDatabases, + selectDatabasesError, +} from "src/app/page-components/sql-playground/db-control-panel/state/databases.selectors"; +import { SqlPlaygroundService } from "../../../../service/sql-playground.service"; +import { map } from "rxjs/operators"; +import { + BackendDefintion, + DatabaseInformation, +} from "../../collab/backend.service"; +import { + selectBackend, + selectBackendDatabaseInformation, +} from "../../state/sql-playground.selectors"; @Component({ selector: "app-db-control-db-overview", @@ -16,186 +35,80 @@ import { SharePlaygroundLinkDialogComponent } from "src/app/dialogs/share-playgr styleUrls: ["./db-control-db-overview.component.scss"], }) export class DbControlDbOverviewComponent implements OnInit { - @Input() collaborativeMode: boolean; - @Output() collaborativeModeChange = new EventEmitter(); - @Output() changeActiveDb = new EventEmitter(); + databases$: Observable; + error$: Observable; + selectedDb: number = 0; + token = this.authService.getToken(); + pending: boolean = false; + + activeDb$: Observable; + collaborativeMode: boolean = false; + backend$: Observable; + backend: BackendDefintion; + backendDatabaseInformation$: Observable; + databaseInformation: DatabaseInformation; constructor( + private store: Store, private snackbar: MatSnackBar, private authService: AuthService, - private sqlPlaygroundService: SqlPlaygroundService, - private dialog: MatDialog + private dialog: MatDialog, + private playgroundService: SqlPlaygroundService ) {} - dbs: Database[] = []; - activeDb: Database; - selectedDb: number = 0; - token: JWTToken = this.authService.getToken(); - pending: boolean = false; - ngOnInit(): void { - this.sqlPlaygroundService.getDatabases(this.token.id).subscribe( - (data) => { - this.dbs = data; - - if (this.dbs.length == 0) { - // create default database if none exists - this.createDatabase("Standard Datenbank").subscribe((result) => { - if (result != null) { - this.activeDb = this.getActiveDb(this.dbs); - this.selectedDb = this.activeDb.id; - } - }); - } else if (this.getActiveDb(this.dbs) == null) { - this.activeDb = this.dbs[0]; - this.selectedDb = this.activeDb.id; - this.activateDb(this.selectedDb); - } else { - this.activeDb = this.getActiveDb(this.dbs); - this.selectedDb = this.activeDb.id; - } - this.changeActiveDb.emit(this.activeDb); - }, - (error) => { - console.log(error); - this.snackbar.open("Fehler beim Laden der Datenbanken", "Ok", { - duration: 3000, - }); - } + this.store.dispatch(loadDatabases()); + this.databases$ = this.store.select(selectAllDatabases); + this.error$ = this.store.select(selectDatabasesError); + this.backendDatabaseInformation$ = this.store.select( + selectBackendDatabaseInformation ); - } - - changeCollaborativeMode() { - this.collaborativeModeChange.emit(!this.collaborativeMode); - } - - getActiveDb(dbs: Database[]): Database { - const activeDB = dbs.find((db) => db.active == true); - if (activeDB !== undefined) { - return activeDB; - } else { - return null; - } - } - - isSelectDbActive(): boolean { - if (this.activeDb !== undefined) { - return this.selectedDb == this.activeDb.id; - } else { - return false; - } - } - - createDatabase(name: string): Observable { - this.sqlPlaygroundService.createDatabase(this.token.id, name).subscribe( - (data) => { - this.snackbar.open("Datenbank erfolgreich erstellt", "Ok", { - duration: 3000, - }); - this.ngOnInit(); - return data; - }, - (error) => { - console.log(error); - this.snackbar.open("Fehler beim Erstellen der Datenbank", "Ok", { - duration: 3000, - }); - } + this.backendDatabaseInformation$.subscribe((databaseInformation) => { + console.log("dbi", databaseInformation); + this.databaseInformation = databaseInformation; + }); + this.backend$ = this.store.select(selectBackend); + this.backend$.subscribe((backend) => { + console.log("backend", backend); + this.backend = backend; + }); + this.activeDb$ = this.databases$.pipe( + map((databases) => databases.find((database) => database.active)) ); - return null; - } - - deleteDatabase() { - const selectedDb = this.dbs.find((db) => db.id == this.selectedDb); - - this.openTextConfirmDialog( - "Datenbank löschen", - "Möchten Sie die Datenbank wirklich löschen?", - `${selectedDb.name}` - ).subscribe((result) => { - if (result === true) { - this.sqlPlaygroundService - .deleteDatabase(this.token.id, selectedDb.id) - .subscribe( - () => { - this.snackbar.open( - `Datenbank ${selectedDb.name} erfolgreich gelöscht`, - "Ok", - { - duration: 3000, - } - ); - this.ngOnInit(); - }, - (error) => { - console.log(error); - this.snackbar.open("Fehler beim Löschen der Datenbank", "Ok", { - duration: 3000, - }); - } - ); + this.activeDb$.subscribe((activeDb) => { + if (activeDb) { + this.selectedDb = activeDb.id; } }); } - activateDb(dbId: number) { - this.pending = true; - const selectedDb = this.dbs.find((db) => db.id == dbId); - - this.sqlPlaygroundService - .activateDatabase(this.token.id, selectedDb.id) - .subscribe( - () => { - this.snackbar.open( - `Datenbank ${selectedDb.name} erfolgreich aktiviert`, - "Ok", - { - duration: 3000, - } - ); - this.ngOnInit(); - this.pending = false; - }, - (error) => { - console.log(error); - this.snackbar.open("Fehler beim Aktivieren der Datenbank", "Ok", { - duration: 3000, - }); - this.pending = false; - } - ); + createDatabase(name: string) { + this.store.dispatch(createDatabase({ name })); } - private openTextConfirmDialog( - title: string, - message: string, - textToRepeat: string - ) { + deleteDatabase() { + const selectedDb = this.selectedDb; const dialogRef = this.dialog.open(TextConfirmDialogComponent, { data: { - title: title, - message: message, - textToRepeat: textToRepeat, + title: "Datenbank löschen", + message: "Möchten Sie die Datenbank wirklich löschen?", + textToRepeat: `${selectedDb}`, }, }); - return dialogRef.afterClosed(); + + dialogRef.afterClosed().subscribe((result) => { + if (result) { + this.store.dispatch(deleteDatabase({ id: selectedDb })); + } + }); } - getTempURI() { - const selectedDb = this.dbs.find((db) => db.id == this.selectedDb); - this.sqlPlaygroundService - .getSharePlaygroundURI(this.token.id, selectedDb.id) - .subscribe((share) => { - this.dialog.open(SharePlaygroundLinkDialogComponent, { - height: "auto", - width: "50%", - autoFocus: false, - data: { - message: `Der URI-Link zu deiner Datenbank \" ${selectedDb.name} \" ist nur für 24 Stunden verfügbar!\n`, - uri: share.url, - }, - }); - }); + activateDatabase(id: number) { + this.store.dispatch(activateDatabase({ id })); + } + + changeCollaborativeMode() { + this.collaborativeMode = !this.collaborativeMode; } addDb() { @@ -203,14 +116,11 @@ export class DbControlDbOverviewComponent implements OnInit { .open(NewDbDialogComponent, { height: "auto", width: "50%", - data: { - token: this.token, - }, + data: { token: this.token }, }) .afterClosed() .subscribe((res) => { if (res.success) { - this.ngOnInit(); this.snackbar.open("Datenbank erfolgreich erstellt", "Ok", { duration: 3000, }); @@ -221,4 +131,25 @@ export class DbControlDbOverviewComponent implements OnInit { } }); } + + getTempURI() { + this.databases$.subscribe((databases) => { + const selectedDb = databases.find((db) => db.id === this.selectedDb); + if (selectedDb) { + this.playgroundService + .getSharePlaygroundURI(this.token.id, selectedDb.id) + .subscribe((share) => { + this.dialog.open(SharePlaygroundLinkDialogComponent, { + height: "auto", + width: "50%", + autoFocus: false, + data: { + message: `Der URI-Link zu deiner Datenbank \"${selectedDb.name}\" ist nur für 24 Stunden verfügbar!\n`, + uri: share.url, + }, + }); + }); + } + }); + } } diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-panel.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-panel.component.html index 56d012b4c..4bc75c1f3 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-panel.component.html +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-panel.component.html @@ -6,27 +6,21 @@ - + - + diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-panel.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-panel.component.ts index ac9e69972..173dc7980 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-panel.component.ts +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-panel.component.ts @@ -1,7 +1,16 @@ import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; +import { Store } from "@ngrx/store"; +import { Observable } from "rxjs"; import { Roles } from "src/app/model/Roles"; import { Database } from "src/app/model/sql_playground/Database"; import { AuthService } from "src/app/service/auth.service"; +import { + loadDatabases, + createDatabase, + deleteDatabase, + activateDatabase, +} from "src/app/page-components/sql-playground/db-control-panel/state/databases.actions"; +import { selectAllDatabases } from "src/app/page-components/sql-playground/db-control-panel/state/databases.selectors"; @Component({ selector: "app-db-control-panel", @@ -13,20 +22,28 @@ export class DbControlPanelComponent implements OnInit { @Output() changeActiveDbId = new EventEmitter(); @Output() submitStatement = new EventEmitter(); - constructor(private auth: AuthService) {} - isAdmin: boolean; selectedTab: number = 0; + activeDb: Database; + collaborativeMode: boolean = false; + + databases$: Observable; + + constructor(private auth: AuthService, private store: Store) {} ngOnInit(): void { const globalRole = this.auth.getToken().globalRole; this.isAdmin = Roles.GlobalRole.isAdmin(globalRole); - } - activeDb: Database; - collaborativeMode: boolean = false; + this.store.dispatch(loadDatabases()); + this.databases$ = this.store.select(selectAllDatabases); - changeDb(db: any) { + this.databases$.subscribe((databases) => { + this.activeDb = databases.find((database) => database.active); + }); + } + + changeDb(db: Database) { this.activeDb = db; this.changeActiveDbId.emit(db.id); } @@ -35,4 +52,16 @@ export class DbControlPanelComponent implements OnInit { this.selectedTab = 0; this.submitStatement.emit(statement); } + + onCreateDatabase(name: string) { + this.store.dispatch(createDatabase({ name })); + } + + onDeleteDatabase(id: number) { + this.store.dispatch(deleteDatabase({ id })); + } + + onActivateDatabase(id: number) { + this.store.dispatch(activateDatabase({ id })); + } } diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-templates/db-control-templates.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-templates/db-control-templates.component.html index cd78ff127..a2071a2a9 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-templates/db-control-templates.component.html +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-templates/db-control-templates.component.html @@ -1,11 +1,9 @@
-

+

{{ "sql-playground.db-control-panel.templates.selected-db" | i18nextEager }}: - - {{ this.activeDb.name }} - + {{ activeDb[0]?.name }}

@@ -21,11 +19,11 @@ -- {{ template.name }} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-templates/db-control-templates.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-templates/db-control-templates.component.ts index 75f56ff7c..778dcbd3c 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-templates/db-control-templates.component.ts +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/db-control-templates/db-control-templates.component.ts @@ -1,11 +1,24 @@ -import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; +import { Component, EventEmitter, OnInit, Output } from "@angular/core"; +import { Store } from "@ngrx/store"; import { MatDialog } from "@angular/material/dialog"; +import { Observable } from "rxjs"; +import { + addTemplates, + addCategories, +} from "src/app/page-components/sql-playground/db-control-panel/state/templates.actions"; +import { + selectAllTemplates, + selectAllCategories, + selectTemplatesError, +} from "src/app/page-components/sql-playground/db-control-panel/state/templates.selectors"; import { NewSqlTemplateComponent } from "src/app/dialogs/new-sql-template/new-sql-template.component"; +import { AuthService } from "src/app/service/auth.service"; import { JWTToken } from "src/app/model/JWTToken"; import { Database } from "src/app/model/sql_playground/Database"; -import { SqlTemplates } from "src/app/model/sql_playground/SqlTemplates"; -import { TemplateCategory } from "src/app/model/sql_playground/TemplateCategory"; -import { AuthService } from "src/app/service/auth.service"; +import { selectAllDatabases } from "src/app/page-components/sql-playground/db-control-panel/state/databases.selectors"; +import { SqlTemplates } from "../../../../model/sql_playground/SqlTemplates"; +import { TemplateCategory } from "../../../../model/sql_playground/TemplateCategory"; +import { Roles } from "../../../../model/Roles"; @Component({ selector: "app-db-control-templates", @@ -13,133 +26,132 @@ import { AuthService } from "src/app/service/auth.service"; styleUrls: ["./db-control-templates.component.scss"], }) export class DbControlTemplatesComponent implements OnInit { - @Input() activeDb: Database; - @Input() isAdmin: boolean; @Output() submitStatement = new EventEmitter(); - - constructor(private dialog: MatDialog, private authService: AuthService) {} - - ngOnInit(): void { - console.log(""); - } + templates$: Observable; + categories$: Observable; + error$: Observable; + activeDb$: Observable; selectedTemplateId: number = 0; token: JWTToken = this.authService.getToken(); + isAdmin: boolean = false; - categories: TemplateCategory[] = [ - { - id: 1, - name: "Allgemein", - }, - { - id: 2, - name: "Übungsaufgaben", - }, - , - ]; + constructor( + private store: Store, + private dialog: MatDialog, + private authService: AuthService + ) {} - templates: SqlTemplates[] = [ - { - id: 1, - name: "Hotel, Schema (DML)", - category: this.categories[0], - templateQuery: - "CREATE TABLE hotel ( HoNr INTEGER NOT NULL, HName VARCHAR(40), Ort VARCHAR(40), Straße VARCHAR(40), HausNr VARCHAR(5), PLZ CHAR(5), CONSTRAINT pk_hotel PRIMARY KEY(HoNr)); CREATE TABLE zimmer ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ZName VARCHAR(40), Kapazitaet INTEGER, Preis DECIMAL(8,2), CONSTRAINT pk_zimmer PRIMARY KEY(HoNr, ZNr), CONSTRAINT fk_zimmer FOREIGN KEY(HoNr) REFERENCES hotel(HoNr)); CREATE TABLE ausstattung ( ANr INTEGER NOT NULL, Bezeichnung VARCHAR(40), Zusatzkosten DECIMAL(8,2), CONSTRAINT pk_ausstattung PRIMARY KEY(ANr)); CREATE TABLE normal ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ANr INTEGER NOT NULL, CONSTRAINT pk_normal PRIMARY KEY(HoNr, ZNr, ANr), CONSTRAINT fk_normal_1 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT fk_normal_2 FOREIGN KEY(HoNr, ZNr) REFERENCES zimmer(HoNr, ZNr)); CREATE TABLE gast ( GNr INTEGER NOT NULL, Name VARCHAR(30), Vorname VARCHAR(40), Ort VARCHAR(50), PLZ CHAR(5), Strasse VARCHAR(50), HausNr VARCHAR(5), CONSTRAINT pk_gast PRIMARY KEY(GNr)); CREATE TABLE reservierung ( RNr INTEGER NOT NULL, Datum DATE, HoNr INTEGER, GNr INTEGER, CONSTRAINT pk_reservierung PRIMARY KEY(RNr), CONSTRAINT fk_reservierung_1 FOREIGN KEY(HoNr) REFERENCES hotel(HoNr), CONSTRAINT fk_reservierung_2 FOREIGN KEY(GNr) REFERENCES gast(GNr)); CREATE TABLE rposition ( RNr INTEGER NOT NULL, RPos INTEGER NOT NULL, von DATE, bis DATE, HoNr INTEGER, ZNr INTEGER, CONSTRAINT pk_position PRIMARY KEY(RNr, RPos), CONSTRAINT fk_position_1 FOREIGN KEY(RNr) REFERENCES reservierung(RNr), CONSTRAINT fk_position_2 FOREIGN KEY(HoNr, ZNr) REFERENCES zimmer(HoNr, ZNr), CONSTRAINT check_date CHECK (von <= bis)); CREATE TABLE zusatz ( RNr INTEGER NOT NULL, RPos INTEGER NOT NULL, ANr INTEGER NOT NULL, von DATE, bis DATE, CONSTRAINT pk_zusatz PRIMARY KEY(RNr, RPos, ANr), CONSTRAINT fk_zusatz_1 FOREIGN KEY(RNr, RPos) REFERENCES rposition(RNr, RPos), CONSTRAINT fk_zusatz_2 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT check_date CHECK (von <= bis));", - }, - { - id: 2, - name: "Hotel, Daten (DDL)", - category: this.categories[0], - templateQuery: - "INSERT INTO hotel VALUES(1036, 'Ringhotel', 'Luenen', 'Kurt-Schumacher-Strasse', '1', '44534'); INSERT INTO hotel VALUES(34 ,'Haus Schmuelling','Bergkamen','Landwehrstrasse', '54', '59192'); INSERT INTO hotel VALUES(135, 'City Hotel', 'Dortmund', 'Auf dem Wall','62', '44147'); INSERT INTO hotel VALUES(843,'Maritim','Stralsund','Strandgasse','37','18435'); INSERT INTO hotel VALUES(428,'Riss','Chemnitz','An der Erzkuhle','23', '09008'); INSERT INTO hotel VALUES(522,'Bohne','Kakau b. Bitterfeld','Zur Plantage','14','06785'); INSERT INTO hotel VALUES(132,'Gruene Bogenschuetze','Geseke','An der Abtei','3','59590'); INSERT INTO hotel VALUES(625,'Hotel Adlon','Dortmund','Lilienthalstrasse','68a','44369'); INSERT INTO hotel VALUES(392,'Hotel Kempinski','Muenchen','Terminalstrasse', '20-22','85356'); INSERT INTO ausstattung VALUES(23,'Telefon', 5.67); INSERT INTO ausstattung VALUES(35,'Goldene Wascharmaturen', 45.16); INSERT INTO ausstattung VALUES(47,'Extragroße Badetuecher', 9.99); INSERT INTO ausstattung VALUES(59,'Bettwaesche', 10.32); INSERT INTO ausstattung VALUES(61,'Haekelkissenbezuege', 13.57); INSERT INTO ausstattung VALUES(73,'Kabelfernsehen', 15.66); INSERT INTO ausstattung VALUES(84,'Satellitenfernsehen', 16.55); INSERT INTO ausstattung VALUES(96,'Beamer', 23.79); INSERT INTO ausstattung VALUES(108,'Overheadprojektor', 17.43); INSERT INTO ausstattung VALUES(111,'Videorekorder', 16.89); INSERT INTO ausstattung VALUES(123,'DVD-Player', 18.52); INSERT INTO ausstattung VALUES(130,'HiFi-Multifunktionsanlage', 25.91); INSERT INTO ausstattung VALUES(142,'Stuhl', 4.31); INSERT INTO ausstattung VALUES(154,'Tisch', 5.76); INSERT INTO ausstattung VALUES(166,'Kopfkissen', 15.69); INSERT INTO ausstattung VALUES(178,'Gummibettlaken', 17.83); INSERT INTO ausstattung VALUES(62,'gehaekelte Toilettenrollendeckchen', 11.46); INSERT INTO zimmer VALUES(34, 3, 'No3', 1, 19.99); INSERT INTO zimmer VALUES(135, 312, 'Praesidentensuite', 6, 399.99); INSERT INTO zimmer VALUES(428, 222, 'Stollen Sued', 2, 24.99); INSERT INTO zimmer VALUES(843, 145, 'Seeblick', 3, 89.67); INSERT INTO zimmer VALUES(1036, 217, 'Waldblick', 2, 45.99); INSERT INTO zimmer VALUES(428, 111, 'Stollen Nord', 1, 23.99); INSERT INTO zimmer VALUES(843, 732, 'Krabbenkutter', 5, 485.00); INSERT INTO zimmer VALUES(135, 521, 'Westfalenzimmer', 4, 167.55); INSERT INTO zimmer VALUES(34, 4, 'No4', 2, 21.99); INSERT INTO zimmer VALUES(1036, 1214, 'Schwanenteich', 3, 76.99); INSERT INTO zimmer VALUES(522, 113,'Onkel Toms Huette', 2, 54.99); INSERT INTO zimmer VALUES(522, 124,'Singendes Zuckerrohr', 3, 65.35); INSERT INTO zimmer VALUES(132, 115,'Waldruh', 2, 55.34); INSERT INTO zimmer VALUES(132, 134,'Hochsitz', 4, 89.47); INSERT INTO zimmer VALUES(625, 257,'Metropolian', 2, 76.21); INSERT INTO zimmer VALUES(625, 412,'Blickpunkt', 3, 87.25); INSERT INTO zimmer VALUES(392, 233,'Waldfried', 1, 32.46); INSERT INTO zimmer VALUES(392, 513,'Flugplatz', 2, 43.62); INSERT INTO normal VALUES(1036, 217, 23); INSERT INTO normal VALUES(843, 145, 73); INSERT INTO normal VALUES(34, 3, 23); INSERT INTO normal VALUES(428, 222, 61); INSERT INTO normal VALUES(135, 312, 166); INSERT INTO normal VALUES(428, 111, 142); INSERT INTO normal VALUES(34, 4, 59); INSERT INTO normal VALUES(1036, 1214, 84); INSERT INTO normal VALUES(135, 521, 178); INSERT INTO normal VALUES(843, 732, 130); INSERT INTO normal VALUES(522, 113, 62); INSERT INTO normal VALUES(522, 124, 59); INSERT INTO normal VALUES(132, 115, 73); INSERT INTO normal VALUES(132, 134, 84); INSERT INTO normal VALUES(625, 257, 23); INSERT INTO normal VALUES(625, 412, 166); INSERT INTO normal VALUES(392, 233, 35); INSERT INTO normal VALUES(392, 513, 130); INSERT INTO normal VALUES(522, 113, 59); INSERT INTO gast VALUES(453, 'Muller', 'Jean-Paul', 'Havixbeck', '48329', 'Willi-Richter-Platz', '2b'); INSERT INTO gast VALUES(14753, 'Richter','Trude','Buxtehude','21614', 'Zwischen den Bruecken','6'); INSERT INTO gast VALUES(795, 'Stein','Flut','Herten','46599','Stan-Libuda-Strasse','1'); INSERT INTO gast VALUES(8531,'Mustermann','Martin','Musterstadt','10000','Poststrasse','13-15'); INSERT INTO gast VALUES(7184,'Postmann','Elfriede','Chemnitz','09008','Erich-Honecker-Platz','23'); INSERT INTO gast VALUES(3417,'Randzio','Katharina','Aue','08280','Goethestrasse','101a'); INSERT INTO gast VALUES(59375,'Engelke-Meise','Silke','Herne','44625','Jaegerstrasse','13'); INSERT INTO gast VALUES(58,'Ebbingmann','Adalbert','Fuessen','87629','Froschseenstrasse','33'); INSERT INTO gast VALUES(4711,'Matzke','Muximilian','Waldshut','79761','Kaiserstrasse','27'); INSERT INTO gast VALUES(8624,'Rupprecht','Knecht','Himmelstadt','97267','Kirchplatz','5'); INSERT INTO gast VALUES(2738,'Schmitz','Klaus','Dortmund','44147','Linienstrasse','7b'); INSERT INTO gast VALUES(2631,'Biene','Maja','Blumenberg','50765','Auf der Blume','24'); INSERT INTO gast VALUES(2632,'Groenemeyer','Herbert','Berlin','10435','Rheinsberger Strasse','48'); INSERT INTO gast VALUES(2635,'Baerbock','Annalena','Berlin','11011','Platz der Republik','1'); INSERT INTO Gast (gnr,name,vorname,ort,plz,strasse,hausnr) VALUES (44,'Schulz','Maja','Gießen','35390','Wiesenstr.','10'); INSERT INTO reservierung VALUES(86542, '2002-09-09', 34, 453); INSERT INTO reservierung VALUES(145863, '2002-01-02', 135, 14753); INSERT INTO reservierung VALUES(46357, '2003-04-01', 843, 795); INSERT INTO reservierung VALUES(43358, '2003-03-23', 428, 8531); INSERT INTO reservierung VALUES(135, '1995-09-19', 1036, 7184); INSERT INTO reservierung VALUES(6834, '2004-08-13', 34, 3417); INSERT INTO reservierung VALUES(115, '2003-05-27', 428, 59375); INSERT INTO reservierung VALUES(8673, '2003-05-03', 135, 58); INSERT INTO reservierung VALUES(24, '1999-08-31', 843, 4711); INSERT INTO reservierung VALUES(9999, '2003-12-12', 1036, 8624); INSERT INTO reservierung VALUES(735, '2003-03-13', 132, 4711); INSERT INTO reservierung VALUES(567, '2002-02-24', 625, 2738); INSERT INTO reservierung VALUES(818, '2004-03-01', 392, 8624); INSERT INTO reservierung VALUES(361, '1998-12-21', 34, 59375); INSERT INTO reservierung VALUES(5294, '2001-10-10', 392, 3417); INSERT INTO reservierung VALUES(2732, '1996-04-13', 132, 7184); INSERT INTO reservierung VALUES(2432, '2001-07-16', 522, 453); INSERT INTO reservierung VALUES(1953, '2001-08-23', 135, 14753); INSERT INTO reservierung VALUES(356, '2004-01-01', 1036, 2631); INSERT INTO reservierung VALUES(5646, '2005-02-05', 522, 795); INSERT INTO reservierung VALUES(6748, '2005-03-22', 522, 795); INSERT INTO reservierung VALUES(2748, '2004-02-10', 132, 4711); INSERT INTO reservierung VALUES(2349, '2004-02-10', 132, 58); INSERT INTO reservierung VALUES(4241, '2005-02-10', 132, 58); INSERT INTO reservierung VALUES(6878, '2006-02-10', 132, 58); INSERT INTO rposition VALUES(86542, 1, '2002-10-10', '2003-10-10', 34, 3); INSERT INTO rposition VALUES(145863, 1, '2003-04-11', '2003-04-22', 135, 312); INSERT INTO rposition VALUES(43358, 1, '2003-05-05', '2003-05-06', 428, 222); INSERT INTO rposition VALUES(46357, 1, '2004-04-26', '2004-05-07', 843,145); INSERT INTO rposition VALUES(135, 1, '1997-09-18', '1997-09-22', 1036, 217); INSERT INTO rposition VALUES(115, 1, '2004-05-28', '2004-05-31', 428, 111); INSERT INTO rposition VALUES(24, 1, '2001-04-08', '2001-04-25', 843, 732); INSERT INTO rposition VALUES(24, 2, '2001-04-08', '2001-04-25', 843, 145); INSERT INTO rposition VALUES(24, 3, '2001-07-31', '2001-09-01', 34, 3); INSERT INTO rposition VALUES(24, 4, '2001-07-31', '2001-09-01', 34, 4); INSERT INTO rposition VALUES(8673, 1, '2003-07-01', '2003-07-15', 135, 521); INSERT INTO rposition VALUES(6834, 1, '2004-08-15', '2004-08-27', 34, 4); INSERT INTO rposition VALUES(9999, 1, '2004-04-30', '2004-06-30', 1036, 1214); INSERT INTO rposition VALUES(9999, 2, '2004-07-01', '2004-07-31', 135, 312); INSERT INTO rposition VALUES(9999, 3, '2004-08-31', '2004-10-01', 843, 145); INSERT INTO rposition VALUES(735, 1, '2003-03-20', '2004-04-20', 392, 233); INSERT INTO rposition VALUES(567, 1, '2003-04-23', '2003-05-07', 522,113); INSERT INTO rposition VALUES(818, 1, '2004-03-24', '2004-03-31', 132, 134); INSERT INTO rposition VALUES(361, 1, '1999-12-23', '2000-01-06', 625, 257); INSERT INTO rposition VALUES(5294, 1, '2002-04-02', '2002-04-16', 428, 111); INSERT INTO rposition VALUES(2732, 1, '1996-08-17', '1996-09-04', 522, 124); INSERT INTO rposition VALUES(2432, 1, '2002-06-15', '2002-07-16', 132, 115); INSERT INTO rposition VALUES(1953, 1, '2004-08-07', '2004-08-15', 392, 513); INSERT INTO rposition VALUES(818, 2, '2004-04-01', '2004-04-12', 843, 732); INSERT INTO rposition VALUES(356, 1, '2004-01-02', '2004-04-22', 522, 113); INSERT INTO rposition VALUES(5646, 1, '2005-03-06', '2005-03-22', 843, 145); INSERT INTO rposition VALUES(6748, 1, '2006-01-01', '2006-01-08', 843, 145); INSERT INTO rposition VALUES(2748, 1, '2004-04-01', '2004-04-08', 392, 233); INSERT INTO rposition VALUES(2349, 1, '2004-07-16', '2004-07-18', 392, 233); INSERT INTO rposition VALUES(4241, 1, '2005-07-16', '2005-07-18', 392, 233); INSERT INTO rposition VALUES(6878, 1, '2006-07-16', '2006-07-18', 392, 233); INSERT INTO zusatz VALUES(735, 1, 84, '2003-03-21', '2004-03-30'); INSERT INTO zusatz VALUES(567, 1, 61, '2003-04-23', '2003-05-07'); INSERT INTO zusatz VALUES(818, 1, 111, '2004-03-24', '2004-03-28'); INSERT INTO zusatz VALUES(361, 1, 142, '1999-12-26', '2000-01-06'); INSERT INTO zusatz VALUES(43358, 1, 154, '2003-05-05', '2003-05-06'); INSERT INTO zusatz VALUES(2732, 1, 47, '1996-08-17', '1996-08-18'); INSERT INTO zusatz VALUES(2432, 1, 123, '2002-06-30', '2002-07-01'); INSERT INTO zusatz VALUES(1953, 1, 178, '2004-08-07', '2004-08-15'); INSERT INTO zusatz VALUES(818, 2, 96, '2004-04-04', '2004-04-11'); INSERT INTO zusatz VALUES(818, 2, 108, '2004-04-03', '2004-04-10'); INSERT INTO zusatz VALUES(818, 2, 111, '2004-04-03', '2004-04-11'); INSERT INTO zusatz VALUES(735, 1, 130, '2003-03-22', '2004-03-29'); INSERT INTO zusatz VALUES(145863, 1, 35, '2003-04-14', '2003-04-19'); INSERT INTO zusatz VALUES(46357, 1, 61, '2004-04-26', '2004-05-07'); INSERT INTO zusatz VALUES(46357, 1, 84, '2004-04-30', '2004-05-03'); INSERT INTO zusatz VALUES(46357, 1, 111, '2004-05-01', '2004-05-03'); INSERT INTO zusatz VALUES(46357, 1, 130, '2004-04-30', '2004-05-02'); INSERT INTO zusatz VALUES(135, 1, 96, '1997-09-19', '1997-09-20'); INSERT INTO zusatz VALUES(135, 1, 108, '1997-09-19', '1997-09-19'); INSERT INTO zusatz VALUES(135, 1, 111, '1997-09-20', '1997-09-20'); INSERT INTO zusatz VALUES(24, 1, 142, '2001-04-16', '2001-04-19'); INSERT INTO zusatz VALUES(24, 3, 178, '2001-08-01', '2001-08-27'); INSERT INTO zusatz VALUES(24, 4, 47, '2001-08-01', '2001-08-27'); INSERT INTO zusatz VALUES(8673, 1, 47, '2003-07-03', '2003-07-05'); INSERT INTO zusatz VALUES(9999, 1, 84, '2004-05-05', '2004-05-05'); INSERT INTO zusatz VALUES(9999, 1, 130, '2004-06-06', '2004-06-07'); INSERT INTO zusatz VALUES(9999, 2, 130, '2004-07-01', '2004-07-31'); INSERT INTO zusatz VALUES(9999, 3, 130, '2004-09-01', '2004-09-30'); INSERT INTO zusatz VALUES(9999, 3, 61, '2004-09-01', '2004-09-30'); INSERT INTO zusatz Values(356, 1, 35, '2004-01-02', '2004-04-22'); INSERT INTO zusatz Values(356, 1, 47, '2004-01-02', '2004-04-22'); Update reservierung set datum=datum+730; Update rposition set von=von+1095, bis=bis+1095; Update zusatz set von=von+1095, bis=bis+1095; ALTER TABLE normal ADD anzahl INTEGER DEFAULT 1; ALTER TABLE zusatz ADD anzahl INTEGER DEFAULT 1; INSERT INTO ausstattung VALUES(46,'Bademantel','5.50'); INSERT INTO ausstattung VALUES(45,'Hausschuhe','2.35'); INSERT INTO ausstattung VALUES(50,'Kinderbett','0.0'); INSERT INTO ausstattung VALUES(51,'Hochstuhl','0.0'); INSERT INTO ausstattung VALUES(52,'Safe','2.45'); INSERT INTO ausstattung VALUES(53,'Heizdecke','16.85'); INSERT INTO ausstattung VALUES(54,'Duftkerzen','12.15'); INSERT INTO ausstattung VALUES(24,'W-LAN Zugang','5.95'); INSERT INTO ausstattung VALUES(25,'DSL-Anschluss','7.69'); INSERT INTO hotel VALUES(736,'Gasthof Sybille','Bad Lippspringe','An der Jordanquelle','1','33188'); INSERT INTO hotel VALUES(758,'Kastens Hotel','Duesseldorf','Lorettostr','5','40219'); INSERT INTO hotel VALUES(761,'Am Glockenturm','Arnsberg','Soesterstr','1','59821'); INSERT INTO zimmer VALUES(34,5,'No5',2,'21.99'); INSERT INTO zimmer VALUES(132,122,'Strecke',2,'60.45'); INSERT INTO zimmer VALUES(135,412,'Rosa Raum',2,'90.35'); INSERT INTO zimmer VALUES(392,414,'Schlafwohl',2,'59.95'); INSERT INTO zimmer VALUES(428,333,'Stollen West',2,'24.99'); INSERT INTO zimmer VALUES(522,135,'Missippi',2,'52.89'); INSERT INTO zimmer VALUES(625,333,'Schoene Aussicht',2,'74.25'); INSERT INTO zimmer VALUES(843,363,'Morgenroete',2,'195.25'); INSERT INTO zimmer VALUES(1036,512,'Angeraue',2,'50.12'); INSERT INTO zimmer VALUES(736,11,'Arminiusquelle',2,'45.40'); INSERT INTO zimmer VALUES(736,12,'Jordanquelle',2,'45.40'); INSERT INTO zimmer VALUES(736,14,'Lippequelle',2,50.50); INSERT INTO zimmer VALUES(758,25,'Rheinturm',2,78.99); INSERT INTO zimmer VALUES(758,26,'Stadttor',2,78.99); INSERT INTO zimmer VALUES(758,27,'Kniebruecke',2,74.99); INSERT INTO zimmer VALUES(761,31,'Schlossberg',2,25.85); INSERT INTO zimmer VALUES(761,32,'Gambrinus',2,19.99); INSERT INTO zimmer VALUES(761,33,'Muffrika',4,48.55); INSERT INTO normal VALUES(34,5,59,2); INSERT INTO normal VALUES(132,122,59,2); INSERT INTO normal VALUES(135,412,59,2); INSERT INTO normal VALUES(392,414,59,2); INSERT INTO normal VALUES(428,333,59,2); INSERT INTO normal VALUES(522,135,59,2); INSERT INTO normal VALUES(625,333,59,2); INSERT INTO normal VALUES(843,363,59,2); INSERT INTO normal VALUES(1036,512,59,2); INSERT INTO normal VALUES(736,11,59,2); INSERT INTO normal VALUES(736,12,59,2); INSERT INTO normal VALUES(736,14,59,2); INSERT INTO normal VALUES(758,25,59,2); INSERT INTO normal VALUES(758,26,59,2); INSERT INTO normal VALUES(758,27,59,2); INSERT INTO normal VALUES(761,31,59,2); INSERT INTO normal VALUES(761,32,59,2); INSERT INTO normal VALUES(761,33,59,4); INSERT INTO normal VALUES(34,5,62,1); INSERT INTO normal VALUES(132,122,62,1); INSERT INTO normal VALUES(135,412,62,1); INSERT INTO normal VALUES(392,414,62,1); INSERT INTO normal VALUES(428,333,62,1); INSERT INTO normal VALUES(522,135,62,1); INSERT INTO normal VALUES(625,333,62,1); INSERT INTO normal VALUES(843,363,62,1); INSERT INTO normal VALUES(1036,512,62,1); INSERT INTO normal VALUES(736,11,53,1); INSERT INTO normal VALUES(736,12,53,1); INSERT INTO normal VALUES(736,14,53,1); INSERT INTO normal VALUES(758,25,142,1); INSERT INTO normal VALUES(758,26,142,1); INSERT INTO normal VALUES(758,27,142,1); INSERT INTO normal VALUES(761,31,178,2); INSERT INTO normal VALUES(761,32,178,2); INSERT INTO normal VALUES(761,33,178,4); INSERT INTO gast VALUES(25,'Binz','Gunnar','Duesseldorf','40549','Heerdter Sandberg','3'); INSERT INTO gast VALUES(26,'Haller','Karl-Heinz','Dortmund','44143','Breierspfad','134'); INSERT INTO gast VALUES(27,'Kloepping','Harald','Bamberg','96058','Eckeystr','15'); INSERT INTO gast VALUES(28,'Schlanstein','Christina','Dillenburg','35683','Carl-Schurz-Str','9'); INSERT INTO gast VALUES(29,'Gauss','Kerstin','Neuss','41453','Badstr','3'); INSERT INTO gast VALUES(30,'Hansen','Irmgard','Bamberg','96023','Neuer Weg','15'); INSERT INTO gast VALUES(31,'Rosenberg','Brigitte','Duisburg','41025','Rahmerstr','168'); INSERT INTO gast VALUES(32,'Lampe','Rosa','Vechta','49377','Schwichtelerstr','14'); INSERT INTO gast VALUES(33,'Mondo','Dolores','Hagen','58093','Dortmunder Str','15a'); INSERT INTO reservierung VALUES(221,'2009-05-15',736,25); INSERT INTO reservierung VALUES(222,'2009-01-11',758,26); INSERT INTO reservierung VALUES(223,'2008-11-05',761,27); INSERT INTO reservierung VALUES(224,'2008-10-03',761,28); INSERT INTO reservierung VALUES(225,'2007-07-18',135,27); INSERT INTO reservierung VALUES(226,'2007-11-06',522,29); INSERT INTO reservierung VALUES(227,'2007-12-13',428,30); INSERT INTO reservierung VALUES(228,'2008-02-15',843,31); INSERT INTO reservierung VALUES(229,'2008-03-25',135,32); INSERT INTO reservierung VALUES(230,'2008-04-13',758,33); INSERT INTO reservierung VALUES(231,'2008-06-07',758,33); INSERT INTO reservierung VALUES(232,'2008-08-13',522,25); INSERT INTO reservierung VALUES(233,'2009-04-13',736,29); INSERT INTO reservierung VALUES(234,'2009-02-26',522,27); INSERT INTO reservierung VALUES(235,'2008-08-13',761,26); INSERT INTO reservierung VALUES(236,'2008-09-30',761,25); INSERT INTO reservierung VALUES(237,'2009-03-11',843,33); INSERT INTO reservierung VALUES(238,'2008-04-13',843,58); INSERT INTO reservierung VALUES(239,'2008-11-11',758,58); INSERT INTO reservierung VALUES(240,'2009-02-03',135,453); INSERT INTO reservierung VALUES(241,'2007-12-28',522,795); INSERT INTO rposition VALUES(221,1,'2009-05-25','2009-06-05',736,11); INSERT INTO rposition VALUES(222,1,'2009-04-15','2009-04-18',736,12); INSERT INTO rposition VALUES(223,1,'2009-01-11','2009-01-18',736,14); INSERT INTO rposition VALUES(223,2,'2009-02-11','2009-02-18',736,11); INSERT INTO rposition VALUES(223,3,'2009-03-11','2009-03-18',736,14); INSERT INTO rposition VALUES(224,1,'2008-11-11','2008-11-15',758,25); INSERT INTO rposition VALUES(225,1,'2007-07-31','2007-08-15',758,26); INSERT INTO rposition VALUES(226,1,'2007-11-11','2007-11-13',758,27); INSERT INTO rposition VALUES(227,1,'2008-01-12','2008-01-15',761,31); INSERT INTO rposition VALUES(228,1,'2008-03-02','2008-03-08',761,32); INSERT INTO rposition VALUES(228,2,'2008-04-02','2008-04-08',761,32); INSERT INTO rposition VALUES(228,3,'2008-05-02','2008-05-08',761,32); INSERT INTO rposition VALUES(229,1,'2008-03-28','2008-04-07',761,33); INSERT INTO rposition VALUES(230,1,'2008-05-02','2008-05-13',132,122); INSERT INTO rposition VALUES(231,1,'2008-07-01','2008-07-05',34,3); INSERT INTO rposition VALUES(231,2,'2008-07-01','2008-07-05',34,4); INSERT INTO rposition VALUES(231,3,'2008-07-01','2008-07-05',34,5); INSERT INTO rposition VALUES(232,1,'2008-09-19','2008-09-21',135,412); INSERT INTO rposition VALUES(233,1,'2009-05-01','2009-05-05',392,414); INSERT INTO rposition VALUES(234,1,'2009-03-01','2009-03-05',428,333); INSERT INTO rposition VALUES(235,1,'2008-09-01','2008-09-05',522,135); INSERT INTO rposition VALUES(236,1,'2008-12-01','2008-12-10',625,333); INSERT INTO rposition VALUES(237,1,'2009-03-18','2009-03-25',843,363); INSERT INTO rposition VALUES(238,1,'2008-07-01','2008-07-05',1036,512); INSERT INTO rposition VALUES(239,1,'2008-11-11','2008-11-15',758,26); INSERT INTO rposition VALUES(240,1,'2009-02-11','2009-02-15',135,412); INSERT INTO rposition VALUES(241,1,'2008-01-02','2008-01-09',522,135); INSERT INTO zusatz VALUES(221,1,50,'2009-05-25','2009-06-05',2); INSERT INTO zusatz VALUES(221,1,51,'2009-05-25','2009-06-05',2); INSERT INTO zusatz VALUES(222,1,53,'2009-04-15','2009-04-18',2); INSERT INTO zusatz VALUES(224,1,53,'2008-11-11','2008-11-15',1); INSERT INTO zusatz VALUES(225,1,52,'2007-07-31','2007-08-15',1); INSERT INTO zusatz VALUES(226,1,52,'2007-11-11','2007-11-13',1); INSERT INTO zusatz VALUES(227,1,52,'2008-01-12','2008-01-15',2); INSERT INTO zusatz VALUES(229,1,45,'2008-03-29','2008-04-07',2); INSERT INTO zusatz VALUES(230,1,45,'2008-05-03','2008-05-13',1); INSERT INTO zusatz VALUES(230,1,46,'2008-05-03','2008-05-13',1); INSERT INTO zusatz VALUES(232,1,54,'2008-09-19','2008-09-21',1); INSERT INTO zusatz VALUES(233,1,24,'2009-05-01','2009-05-05',1); INSERT INTO zusatz VALUES(234,1,25,'2009-03-03','2009-03-05',1); INSERT INTO zusatz VALUES(235,1,142,'2008-09-03','2008-09-04',4); INSERT INTO zusatz VALUES(235,1,154,'2008-09-03','2008-09-04',1); INSERT INTO zusatz VALUES(239,1,84,'2008-11-11','2008-11-15',1); INSERT INTO zusatz VALUES(240,1,111,'2009-02-11','2009-02-15',1);", - }, - { - id: 3, - name: "Hotel, Schema + Daten", - category: this.categories[0], - templateQuery: - "CREATE TABLE hotel ( HoNr INTEGER NOT NULL, HName VARCHAR(40), Ort VARCHAR(40), Straße VARCHAR(40), HausNr VARCHAR(5), PLZ CHAR(5), CONSTRAINT pk_hotel PRIMARY KEY(HoNr)); CREATE TABLE zimmer ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ZName VARCHAR(40), Kapazitaet INTEGER, Preis DECIMAL(8,2), CONSTRAINT pk_zimmer PRIMARY KEY(HoNr, ZNr), CONSTRAINT fk_zimmer FOREIGN KEY(HoNr) REFERENCES hotel(HoNr)); CREATE TABLE ausstattung ( ANr INTEGER NOT NULL, Bezeichnung VARCHAR(40), Zusatzkosten DECIMAL(8,2), CONSTRAINT pk_ausstattung PRIMARY KEY(ANr)); CREATE TABLE normal ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ANr INTEGER NOT NULL, CONSTRAINT pk_normal PRIMARY KEY(HoNr, ZNr, ANr), CONSTRAINT fk_normal_1 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT fk_normal_2 FOREIGN KEY(HoNr, ZNr) REFERENCES zimmer(HoNr, ZNr)); CREATE TABLE gast ( GNr INTEGER NOT NULL, Name VARCHAR(30), Vorname VARCHAR(40), Ort VARCHAR(50), PLZ CHAR(5), Strasse VARCHAR(50), HausNr VARCHAR(5), CONSTRAINT pk_gast PRIMARY KEY(GNr)); CREATE TABLE reservierung ( RNr INTEGER NOT NULL, Datum DATE, HoNr INTEGER, GNr INTEGER, CONSTRAINT pk_reservierung PRIMARY KEY(RNr), CONSTRAINT fk_reservierung_1 FOREIGN KEY(HoNr) REFERENCES hotel(HoNr), CONSTRAINT fk_reservierung_2 FOREIGN KEY(GNr) REFERENCES gast(GNr)); CREATE TABLE rposition ( RNr INTEGER NOT NULL, RPos INTEGER NOT NULL, von DATE, bis DATE, HoNr INTEGER, ZNr INTEGER, CONSTRAINT pk_position PRIMARY KEY(RNr, RPos), CONSTRAINT fk_position_1 FOREIGN KEY(RNr) REFERENCES reservierung(RNr), CONSTRAINT fk_position_2 FOREIGN KEY(HoNr, ZNr) REFERENCES zimmer(HoNr, ZNr), CONSTRAINT check_date CHECK (von <= bis)); CREATE TABLE zusatz ( RNr INTEGER NOT NULL, RPos INTEGER NOT NULL, ANr INTEGER NOT NULL, von DATE, bis DATE, CONSTRAINT pk_zusatz PRIMARY KEY(RNr, RPos, ANr), CONSTRAINT fk_zusatz_1 FOREIGN KEY(RNr, RPos) REFERENCES rposition(RNr, RPos), CONSTRAINT fk_zusatz_2 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT check_date CHECK (von <= bis)); INSERT INTO hotel VALUES(1036, 'Ringhotel', 'Luenen', 'Kurt-Schumacher-Strasse', '1', '44534'); INSERT INTO hotel VALUES(34 ,'Haus Schmuelling','Bergkamen','Landwehrstrasse', '54', '59192'); INSERT INTO hotel VALUES(135, 'City Hotel', 'Dortmund', 'Auf dem Wall','62', '44147'); INSERT INTO hotel VALUES(843,'Maritim','Stralsund','Strandgasse','37','18435'); INSERT INTO hotel VALUES(428,'Riss','Chemnitz','An der Erzkuhle','23', '09008'); INSERT INTO hotel VALUES(522,'Bohne','Kakau b. Bitterfeld','Zur Plantage','14','06785'); INSERT INTO hotel VALUES(132,'Gruene Bogenschuetze','Geseke','An der Abtei','3','59590'); INSERT INTO hotel VALUES(625,'Hotel Adlon','Dortmund','Lilienthalstrasse','68a','44369'); INSERT INTO hotel VALUES(392,'Hotel Kempinski','Muenchen','Terminalstrasse', '20-22','85356'); INSERT INTO ausstattung VALUES(23,'Telefon', 5.67); INSERT INTO ausstattung VALUES(35,'Goldene Wascharmaturen', 45.16); INSERT INTO ausstattung VALUES(47,'Extragroße Badetuecher', 9.99); INSERT INTO ausstattung VALUES(59,'Bettwaesche', 10.32); INSERT INTO ausstattung VALUES(61,'Haekelkissenbezuege', 13.57); INSERT INTO ausstattung VALUES(73,'Kabelfernsehen', 15.66); INSERT INTO ausstattung VALUES(84,'Satellitenfernsehen', 16.55); INSERT INTO ausstattung VALUES(96,'Beamer', 23.79); INSERT INTO ausstattung VALUES(108,'Overheadprojektor', 17.43); INSERT INTO ausstattung VALUES(111,'Videorekorder', 16.89); INSERT INTO ausstattung VALUES(123,'DVD-Player', 18.52); INSERT INTO ausstattung VALUES(130,'HiFi-Multifunktionsanlage', 25.91); INSERT INTO ausstattung VALUES(142,'Stuhl', 4.31); INSERT INTO ausstattung VALUES(154,'Tisch', 5.76); INSERT INTO ausstattung VALUES(166,'Kopfkissen', 15.69); INSERT INTO ausstattung VALUES(178,'Gummibettlaken', 17.83); INSERT INTO ausstattung VALUES(62,'gehaekelte Toilettenrollendeckchen', 11.46); INSERT INTO zimmer VALUES(34, 3, 'No3', 1, 19.99); INSERT INTO zimmer VALUES(135, 312, 'Praesidentensuite', 6, 399.99); INSERT INTO zimmer VALUES(428, 222, 'Stollen Sued', 2, 24.99); INSERT INTO zimmer VALUES(843, 145, 'Seeblick', 3, 89.67); INSERT INTO zimmer VALUES(1036, 217, 'Waldblick', 2, 45.99); INSERT INTO zimmer VALUES(428, 111, 'Stollen Nord', 1, 23.99); INSERT INTO zimmer VALUES(843, 732, 'Krabbenkutter', 5, 485.00); INSERT INTO zimmer VALUES(135, 521, 'Westfalenzimmer', 4, 167.55); INSERT INTO zimmer VALUES(34, 4, 'No4', 2, 21.99); INSERT INTO zimmer VALUES(1036, 1214, 'Schwanenteich', 3, 76.99); INSERT INTO zimmer VALUES(522, 113,'Onkel Toms Huette', 2, 54.99); INSERT INTO zimmer VALUES(522, 124,'Singendes Zuckerrohr', 3, 65.35); INSERT INTO zimmer VALUES(132, 115,'Waldruh', 2, 55.34); INSERT INTO zimmer VALUES(132, 134,'Hochsitz', 4, 89.47); INSERT INTO zimmer VALUES(625, 257,'Metropolian', 2, 76.21); INSERT INTO zimmer VALUES(625, 412,'Blickpunkt', 3, 87.25); INSERT INTO zimmer VALUES(392, 233,'Waldfried', 1, 32.46); INSERT INTO zimmer VALUES(392, 513,'Flugplatz', 2, 43.62); INSERT INTO normal VALUES(1036, 217, 23); INSERT INTO normal VALUES(843, 145, 73); INSERT INTO normal VALUES(34, 3, 23); INSERT INTO normal VALUES(428, 222, 61); INSERT INTO normal VALUES(135, 312, 166); INSERT INTO normal VALUES(428, 111, 142); INSERT INTO normal VALUES(34, 4, 59); INSERT INTO normal VALUES(1036, 1214, 84); INSERT INTO normal VALUES(135, 521, 178); INSERT INTO normal VALUES(843, 732, 130); INSERT INTO normal VALUES(522, 113, 62); INSERT INTO normal VALUES(522, 124, 59); INSERT INTO normal VALUES(132, 115, 73); INSERT INTO normal VALUES(132, 134, 84); INSERT INTO normal VALUES(625, 257, 23); INSERT INTO normal VALUES(625, 412, 166); INSERT INTO normal VALUES(392, 233, 35); INSERT INTO normal VALUES(392, 513, 130); INSERT INTO normal VALUES(522, 113, 59); INSERT INTO gast VALUES(453, 'Muller', 'Jean-Paul', 'Havixbeck', '48329', 'Willi-Richter-Platz', '2b'); INSERT INTO gast VALUES(14753, 'Richter','Trude','Buxtehude','21614', 'Zwischen den Bruecken','6'); INSERT INTO gast VALUES(795, 'Stein','Flut','Herten','46599','Stan-Libuda-Strasse','1'); INSERT INTO gast VALUES(8531,'Mustermann','Martin','Musterstadt','10000','Poststrasse','13-15'); INSERT INTO gast VALUES(7184,'Postmann','Elfriede','Chemnitz','09008','Erich-Honecker-Platz','23'); INSERT INTO gast VALUES(3417,'Randzio','Katharina','Aue','08280','Goethestrasse','101a'); INSERT INTO gast VALUES(59375,'Engelke-Meise','Silke','Herne','44625','Jaegerstrasse','13'); INSERT INTO gast VALUES(58,'Ebbingmann','Adalbert','Fuessen','87629','Froschseenstrasse','33'); INSERT INTO gast VALUES(4711,'Matzke','Muximilian','Waldshut','79761','Kaiserstrasse','27'); INSERT INTO gast VALUES(8624,'Rupprecht','Knecht','Himmelstadt','97267','Kirchplatz','5'); INSERT INTO gast VALUES(2738,'Schmitz','Klaus','Dortmund','44147','Linienstrasse','7b'); INSERT INTO gast VALUES(2631,'Biene','Maja','Blumenberg','50765','Auf der Blume','24'); INSERT INTO gast VALUES(2632,'Groenemeyer','Herbert','Berlin','10435','Rheinsberger Strasse','48'); INSERT INTO gast VALUES(2635,'Baerbock','Annalena','Berlin','11011','Platz der Republik','1'); INSERT INTO Gast (gnr,name,vorname,ort,plz,strasse,hausnr) VALUES (44,'Schulz','Maja','Gießen','35390','Wiesenstr.','10'); INSERT INTO reservierung VALUES(86542, '2002-09-09', 34, 453); INSERT INTO reservierung VALUES(145863, '2002-01-02', 135, 14753); INSERT INTO reservierung VALUES(46357, '2003-04-01', 843, 795); INSERT INTO reservierung VALUES(43358, '2003-03-23', 428, 8531); INSERT INTO reservierung VALUES(135, '1995-09-19', 1036, 7184); INSERT INTO reservierung VALUES(6834, '2004-08-13', 34, 3417); INSERT INTO reservierung VALUES(115, '2003-05-27', 428, 59375); INSERT INTO reservierung VALUES(8673, '2003-05-03', 135, 58); INSERT INTO reservierung VALUES(24, '1999-08-31', 843, 4711); INSERT INTO reservierung VALUES(9999, '2003-12-12', 1036, 8624); INSERT INTO reservierung VALUES(735, '2003-03-13', 132, 4711); INSERT INTO reservierung VALUES(567, '2002-02-24', 625, 2738); INSERT INTO reservierung VALUES(818, '2004-03-01', 392, 8624); INSERT INTO reservierung VALUES(361, '1998-12-21', 34, 59375); INSERT INTO reservierung VALUES(5294, '2001-10-10', 392, 3417); INSERT INTO reservierung VALUES(2732, '1996-04-13', 132, 7184); INSERT INTO reservierung VALUES(2432, '2001-07-16', 522, 453); INSERT INTO reservierung VALUES(1953, '2001-08-23', 135, 14753); INSERT INTO reservierung VALUES(356, '2004-01-01', 1036, 2631); INSERT INTO reservierung VALUES(5646, '2005-02-05', 522, 795); INSERT INTO reservierung VALUES(6748, '2005-03-22', 522, 795); INSERT INTO reservierung VALUES(2748, '2004-02-10', 132, 4711); INSERT INTO reservierung VALUES(2349, '2004-02-10', 132, 58); INSERT INTO reservierung VALUES(4241, '2005-02-10', 132, 58); INSERT INTO reservierung VALUES(6878, '2006-02-10', 132, 58); INSERT INTO rposition VALUES(86542, 1, '2002-10-10', '2003-10-10', 34, 3); INSERT INTO rposition VALUES(145863, 1, '2003-04-11', '2003-04-22', 135, 312); INSERT INTO rposition VALUES(43358, 1, '2003-05-05', '2003-05-06', 428, 222); INSERT INTO rposition VALUES(46357, 1, '2004-04-26', '2004-05-07', 843,145); INSERT INTO rposition VALUES(135, 1, '1997-09-18', '1997-09-22', 1036, 217); INSERT INTO rposition VALUES(115, 1, '2004-05-28', '2004-05-31', 428, 111); INSERT INTO rposition VALUES(24, 1, '2001-04-08', '2001-04-25', 843, 732); INSERT INTO rposition VALUES(24, 2, '2001-04-08', '2001-04-25', 843, 145); INSERT INTO rposition VALUES(24, 3, '2001-07-31', '2001-09-01', 34, 3); INSERT INTO rposition VALUES(24, 4, '2001-07-31', '2001-09-01', 34, 4); INSERT INTO rposition VALUES(8673, 1, '2003-07-01', '2003-07-15', 135, 521); INSERT INTO rposition VALUES(6834, 1, '2004-08-15', '2004-08-27', 34, 4); INSERT INTO rposition VALUES(9999, 1, '2004-04-30', '2004-06-30', 1036, 1214); INSERT INTO rposition VALUES(9999, 2, '2004-07-01', '2004-07-31', 135, 312); INSERT INTO rposition VALUES(9999, 3, '2004-08-31', '2004-10-01', 843, 145); INSERT INTO rposition VALUES(735, 1, '2003-03-20', '2004-04-20', 392, 233); INSERT INTO rposition VALUES(567, 1, '2003-04-23', '2003-05-07', 522,113); INSERT INTO rposition VALUES(818, 1, '2004-03-24', '2004-03-31', 132, 134); INSERT INTO rposition VALUES(361, 1, '1999-12-23', '2000-01-06', 625, 257); INSERT INTO rposition VALUES(5294, 1, '2002-04-02', '2002-04-16', 428, 111); INSERT INTO rposition VALUES(2732, 1, '1996-08-17', '1996-09-04', 522, 124); INSERT INTO rposition VALUES(2432, 1, '2002-06-15', '2002-07-16', 132, 115); INSERT INTO rposition VALUES(1953, 1, '2004-08-07', '2004-08-15', 392, 513); INSERT INTO rposition VALUES(818, 2, '2004-04-01', '2004-04-12', 843, 732); INSERT INTO rposition VALUES(356, 1, '2004-01-02', '2004-04-22', 522, 113); INSERT INTO rposition VALUES(5646, 1, '2005-03-06', '2005-03-22', 843, 145); INSERT INTO rposition VALUES(6748, 1, '2006-01-01', '2006-01-08', 843, 145); INSERT INTO rposition VALUES(2748, 1, '2004-04-01', '2004-04-08', 392, 233); INSERT INTO rposition VALUES(2349, 1, '2004-07-16', '2004-07-18', 392, 233); INSERT INTO rposition VALUES(4241, 1, '2005-07-16', '2005-07-18', 392, 233); INSERT INTO rposition VALUES(6878, 1, '2006-07-16', '2006-07-18', 392, 233); INSERT INTO zusatz VALUES(735, 1, 84, '2003-03-21', '2004-03-30'); INSERT INTO zusatz VALUES(567, 1, 61, '2003-04-23', '2003-05-07'); INSERT INTO zusatz VALUES(818, 1, 111, '2004-03-24', '2004-03-28'); INSERT INTO zusatz VALUES(361, 1, 142, '1999-12-26', '2000-01-06'); INSERT INTO zusatz VALUES(43358, 1, 154, '2003-05-05', '2003-05-06'); INSERT INTO zusatz VALUES(2732, 1, 47, '1996-08-17', '1996-08-18'); INSERT INTO zusatz VALUES(2432, 1, 123, '2002-06-30', '2002-07-01'); INSERT INTO zusatz VALUES(1953, 1, 178, '2004-08-07', '2004-08-15'); INSERT INTO zusatz VALUES(818, 2, 96, '2004-04-04', '2004-04-11'); INSERT INTO zusatz VALUES(818, 2, 108, '2004-04-03', '2004-04-10'); INSERT INTO zusatz VALUES(818, 2, 111, '2004-04-03', '2004-04-11'); INSERT INTO zusatz VALUES(735, 1, 130, '2003-03-22', '2004-03-29'); INSERT INTO zusatz VALUES(145863, 1, 35, '2003-04-14', '2003-04-19'); INSERT INTO zusatz VALUES(46357, 1, 61, '2004-04-26', '2004-05-07'); INSERT INTO zusatz VALUES(46357, 1, 84, '2004-04-30', '2004-05-03'); INSERT INTO zusatz VALUES(46357, 1, 111, '2004-05-01', '2004-05-03'); INSERT INTO zusatz VALUES(46357, 1, 130, '2004-04-30', '2004-05-02'); INSERT INTO zusatz VALUES(135, 1, 96, '1997-09-19', '1997-09-20'); INSERT INTO zusatz VALUES(135, 1, 108, '1997-09-19', '1997-09-19'); INSERT INTO zusatz VALUES(135, 1, 111, '1997-09-20', '1997-09-20'); INSERT INTO zusatz VALUES(24, 1, 142, '2001-04-16', '2001-04-19'); INSERT INTO zusatz VALUES(24, 3, 178, '2001-08-01', '2001-08-27'); INSERT INTO zusatz VALUES(24, 4, 47, '2001-08-01', '2001-08-27'); INSERT INTO zusatz VALUES(8673, 1, 47, '2003-07-03', '2003-07-05'); INSERT INTO zusatz VALUES(9999, 1, 84, '2004-05-05', '2004-05-05'); INSERT INTO zusatz VALUES(9999, 1, 130, '2004-06-06', '2004-06-07'); INSERT INTO zusatz VALUES(9999, 2, 130, '2004-07-01', '2004-07-31'); INSERT INTO zusatz VALUES(9999, 3, 130, '2004-09-01', '2004-09-30'); INSERT INTO zusatz VALUES(9999, 3, 61, '2004-09-01', '2004-09-30'); INSERT INTO zusatz Values(356, 1, 35, '2004-01-02', '2004-04-22'); INSERT INTO zusatz Values(356, 1, 47, '2004-01-02', '2004-04-22'); Update reservierung set datum=datum+730; Update rposition set von=von+1095, bis=bis+1095; Update zusatz set von=von+1095, bis=bis+1095; ALTER TABLE normal ADD anzahl INTEGER DEFAULT 1; ALTER TABLE zusatz ADD anzahl INTEGER DEFAULT 1; INSERT INTO ausstattung VALUES(46,'Bademantel','5.50'); INSERT INTO ausstattung VALUES(45,'Hausschuhe','2.35'); INSERT INTO ausstattung VALUES(50,'Kinderbett','0.0'); INSERT INTO ausstattung VALUES(51,'Hochstuhl','0.0'); INSERT INTO ausstattung VALUES(52,'Safe','2.45'); INSERT INTO ausstattung VALUES(53,'Heizdecke','16.85'); INSERT INTO ausstattung VALUES(54,'Duftkerzen','12.15'); INSERT INTO ausstattung VALUES(24,'W-LAN Zugang','5.95'); INSERT INTO ausstattung VALUES(25,'DSL-Anschluss','7.69'); INSERT INTO hotel VALUES(736,'Gasthof Sybille','Bad Lippspringe','An der Jordanquelle','1','33188'); INSERT INTO hotel VALUES(758,'Kastens Hotel','Duesseldorf','Lorettostr','5','40219'); INSERT INTO hotel VALUES(761,'Am Glockenturm','Arnsberg','Soesterstr','1','59821'); INSERT INTO zimmer VALUES(34,5,'No5',2,'21.99'); INSERT INTO zimmer VALUES(132,122,'Strecke',2,'60.45'); INSERT INTO zimmer VALUES(135,412,'Rosa Raum',2,'90.35'); INSERT INTO zimmer VALUES(392,414,'Schlafwohl',2,'59.95'); INSERT INTO zimmer VALUES(428,333,'Stollen West',2,'24.99'); INSERT INTO zimmer VALUES(522,135,'Missippi',2,'52.89'); INSERT INTO zimmer VALUES(625,333,'Schoene Aussicht',2,'74.25'); INSERT INTO zimmer VALUES(843,363,'Morgenroete',2,'195.25'); INSERT INTO zimmer VALUES(1036,512,'Angeraue',2,'50.12'); INSERT INTO zimmer VALUES(736,11,'Arminiusquelle',2,'45.40'); INSERT INTO zimmer VALUES(736,12,'Jordanquelle',2,'45.40'); INSERT INTO zimmer VALUES(736,14,'Lippequelle',2,50.50); INSERT INTO zimmer VALUES(758,25,'Rheinturm',2,78.99); INSERT INTO zimmer VALUES(758,26,'Stadttor',2,78.99); INSERT INTO zimmer VALUES(758,27,'Kniebruecke',2,74.99); INSERT INTO zimmer VALUES(761,31,'Schlossberg',2,25.85); INSERT INTO zimmer VALUES(761,32,'Gambrinus',2,19.99); INSERT INTO zimmer VALUES(761,33,'Muffrika',4,48.55); INSERT INTO normal VALUES(34,5,59,2); INSERT INTO normal VALUES(132,122,59,2); INSERT INTO normal VALUES(135,412,59,2); INSERT INTO normal VALUES(392,414,59,2); INSERT INTO normal VALUES(428,333,59,2); INSERT INTO normal VALUES(522,135,59,2); INSERT INTO normal VALUES(625,333,59,2); INSERT INTO normal VALUES(843,363,59,2); INSERT INTO normal VALUES(1036,512,59,2); INSERT INTO normal VALUES(736,11,59,2); INSERT INTO normal VALUES(736,12,59,2); INSERT INTO normal VALUES(736,14,59,2); INSERT INTO normal VALUES(758,25,59,2); INSERT INTO normal VALUES(758,26,59,2); INSERT INTO normal VALUES(758,27,59,2); INSERT INTO normal VALUES(761,31,59,2); INSERT INTO normal VALUES(761,32,59,2); INSERT INTO normal VALUES(761,33,59,4); INSERT INTO normal VALUES(34,5,62,1); INSERT INTO normal VALUES(132,122,62,1); INSERT INTO normal VALUES(135,412,62,1); INSERT INTO normal VALUES(392,414,62,1); INSERT INTO normal VALUES(428,333,62,1); INSERT INTO normal VALUES(522,135,62,1); INSERT INTO normal VALUES(625,333,62,1); INSERT INTO normal VALUES(843,363,62,1); INSERT INTO normal VALUES(1036,512,62,1); INSERT INTO normal VALUES(736,11,53,1); INSERT INTO normal VALUES(736,12,53,1); INSERT INTO normal VALUES(736,14,53,1); INSERT INTO normal VALUES(758,25,142,1); INSERT INTO normal VALUES(758,26,142,1); INSERT INTO normal VALUES(758,27,142,1); INSERT INTO normal VALUES(761,31,178,2); INSERT INTO normal VALUES(761,32,178,2); INSERT INTO normal VALUES(761,33,178,4); INSERT INTO gast VALUES(25,'Binz','Gunnar','Duesseldorf','40549','Heerdter Sandberg','3'); INSERT INTO gast VALUES(26,'Haller','Karl-Heinz','Dortmund','44143','Breierspfad','134'); INSERT INTO gast VALUES(27,'Kloepping','Harald','Bamberg','96058','Eckeystr','15'); INSERT INTO gast VALUES(28,'Schlanstein','Christina','Dillenburg','35683','Carl-Schurz-Str','9'); INSERT INTO gast VALUES(29,'Gauss','Kerstin','Neuss','41453','Badstr','3'); INSERT INTO gast VALUES(30,'Hansen','Irmgard','Bamberg','96023','Neuer Weg','15'); INSERT INTO gast VALUES(31,'Rosenberg','Brigitte','Duisburg','41025','Rahmerstr','168'); INSERT INTO gast VALUES(32,'Lampe','Rosa','Vechta','49377','Schwichtelerstr','14'); INSERT INTO gast VALUES(33,'Mondo','Dolores','Hagen','58093','Dortmunder Str','15a'); INSERT INTO reservierung VALUES(221,'2009-05-15',736,25); INSERT INTO reservierung VALUES(222,'2009-01-11',758,26); INSERT INTO reservierung VALUES(223,'2008-11-05',761,27); INSERT INTO reservierung VALUES(224,'2008-10-03',761,28); INSERT INTO reservierung VALUES(225,'2007-07-18',135,27); INSERT INTO reservierung VALUES(226,'2007-11-06',522,29); INSERT INTO reservierung VALUES(227,'2007-12-13',428,30); INSERT INTO reservierung VALUES(228,'2008-02-15',843,31); INSERT INTO reservierung VALUES(229,'2008-03-25',135,32); INSERT INTO reservierung VALUES(230,'2008-04-13',758,33); INSERT INTO reservierung VALUES(231,'2008-06-07',758,33); INSERT INTO reservierung VALUES(232,'2008-08-13',522,25); INSERT INTO reservierung VALUES(233,'2009-04-13',736,29); INSERT INTO reservierung VALUES(234,'2009-02-26',522,27); INSERT INTO reservierung VALUES(235,'2008-08-13',761,26); INSERT INTO reservierung VALUES(236,'2008-09-30',761,25); INSERT INTO reservierung VALUES(237,'2009-03-11',843,33); INSERT INTO reservierung VALUES(238,'2008-04-13',843,58); INSERT INTO reservierung VALUES(239,'2008-11-11',758,58); INSERT INTO reservierung VALUES(240,'2009-02-03',135,453); INSERT INTO reservierung VALUES(241,'2007-12-28',522,795); INSERT INTO rposition VALUES(221,1,'2009-05-25','2009-06-05',736,11); INSERT INTO rposition VALUES(222,1,'2009-04-15','2009-04-18',736,12); INSERT INTO rposition VALUES(223,1,'2009-01-11','2009-01-18',736,14); INSERT INTO rposition VALUES(223,2,'2009-02-11','2009-02-18',736,11); INSERT INTO rposition VALUES(223,3,'2009-03-11','2009-03-18',736,14); INSERT INTO rposition VALUES(224,1,'2008-11-11','2008-11-15',758,25); INSERT INTO rposition VALUES(225,1,'2007-07-31','2007-08-15',758,26); INSERT INTO rposition VALUES(226,1,'2007-11-11','2007-11-13',758,27); INSERT INTO rposition VALUES(227,1,'2008-01-12','2008-01-15',761,31); INSERT INTO rposition VALUES(228,1,'2008-03-02','2008-03-08',761,32); INSERT INTO rposition VALUES(228,2,'2008-04-02','2008-04-08',761,32); INSERT INTO rposition VALUES(228,3,'2008-05-02','2008-05-08',761,32); INSERT INTO rposition VALUES(229,1,'2008-03-28','2008-04-07',761,33); INSERT INTO rposition VALUES(230,1,'2008-05-02','2008-05-13',132,122); INSERT INTO rposition VALUES(231,1,'2008-07-01','2008-07-05',34,3); INSERT INTO rposition VALUES(231,2,'2008-07-01','2008-07-05',34,4); INSERT INTO rposition VALUES(231,3,'2008-07-01','2008-07-05',34,5); INSERT INTO rposition VALUES(232,1,'2008-09-19','2008-09-21',135,412); INSERT INTO rposition VALUES(233,1,'2009-05-01','2009-05-05',392,414); INSERT INTO rposition VALUES(234,1,'2009-03-01','2009-03-05',428,333); INSERT INTO rposition VALUES(235,1,'2008-09-01','2008-09-05',522,135); INSERT INTO rposition VALUES(236,1,'2008-12-01','2008-12-10',625,333); INSERT INTO rposition VALUES(237,1,'2009-03-18','2009-03-25',843,363); INSERT INTO rposition VALUES(238,1,'2008-07-01','2008-07-05',1036,512); INSERT INTO rposition VALUES(239,1,'2008-11-11','2008-11-15',758,26); INSERT INTO rposition VALUES(240,1,'2009-02-11','2009-02-15',135,412); INSERT INTO rposition VALUES(241,1,'2008-01-02','2008-01-09',522,135); INSERT INTO zusatz VALUES(221,1,50,'2009-05-25','2009-06-05',2); INSERT INTO zusatz VALUES(221,1,51,'2009-05-25','2009-06-05',2); INSERT INTO zusatz VALUES(222,1,53,'2009-04-15','2009-04-18',2); INSERT INTO zusatz VALUES(224,1,53,'2008-11-11','2008-11-15',1); INSERT INTO zusatz VALUES(225,1,52,'2007-07-31','2007-08-15',1); INSERT INTO zusatz VALUES(226,1,52,'2007-11-11','2007-11-13',1); INSERT INTO zusatz VALUES(227,1,52,'2008-01-12','2008-01-15',2); INSERT INTO zusatz VALUES(229,1,45,'2008-03-29','2008-04-07',2); INSERT INTO zusatz VALUES(230,1,45,'2008-05-03','2008-05-13',1); INSERT INTO zusatz VALUES(230,1,46,'2008-05-03','2008-05-13',1); INSERT INTO zusatz VALUES(232,1,54,'2008-09-19','2008-09-21',1); INSERT INTO zusatz VALUES(233,1,24,'2009-05-01','2009-05-05',1); INSERT INTO zusatz VALUES(234,1,25,'2009-03-03','2009-03-05',1); INSERT INTO zusatz VALUES(235,1,142,'2008-09-03','2008-09-04',4); INSERT INTO zusatz VALUES(235,1,154,'2008-09-03','2008-09-04',1); INSERT INTO zusatz VALUES(239,1,84,'2008-11-11','2008-11-15',1); INSERT INTO zusatz VALUES(240,1,111,'2009-02-11','2009-02-15',1);", - }, - { - id: 4, - name: "Ebay, Schema (DML)", - category: this.categories[0], - templateQuery: - "CREATE TABLE Ebay_Kunde( Knr INTEGER, Nickname VARCHAR(255), Name VARCHAR(255), Vorname VARCHAR(255), Straße VARCHAR(255), Hnr VARCHAR(5), PLZ CHAR(5), Ort VARCHAR(255), KtoNr VARCHAR(10), BLZ VARCHAR(10), Anz_positiv INTEGER, Anz_negativ INTEGER, Gesamtstand INTEGER, CONSTRAINT pk_Kunde PRIMARY KEY (KNr) ); CREATE TABLE Ebay_Kunde_dummie( Knr INTEGER, Nickname VARCHAR(255), Name VARCHAR(255), Vorname VARCHAR(255), Straße VARCHAR(255), Hnr VARCHAR(5), PLZ CHAR(5), Ort VARCHAR(255), KtoNr VARCHAR(10), BLZ VARCHAR(10), Anz_positiv INTEGER, Anz_negativ INTEGER, Gesamtstand INTEGER, CONSTRAINT pk_Ebay_Kunde_dummie PRIMARY KEY (KNr) ); CREATE TABLE Auktionstyp( Atnr INTEGER , Bezeichnung VARCHAR(255), Beschreibung VARCHAR(255), CONSTRAINT pk_Auktionstyp PRIMARY KEY (Atnr) ); CREATE TABLE Kategorie( KatNr INTEGER, Bezeichnung VARCHAR(255), CONSTRAINT pk_Kategorie PRIMARY KEY (KatNr) ); CREATE TABLE Kategorie_dummie( KatNr INTEGER, Bezeichnung VARCHAR(255), CONSTRAINT pk_Kategorie_dummie PRIMARY KEY (KatNr) ); CREATE TABLE Struktur( UKatNr INTEGER, OKatNr INTEGER, CONSTRAINT pk_Struktur PRIMARY KEY (UKatNr), CONSTRAINT fk_Struktur1 FOREIGN KEY (UKatNr) REFERENCES Kategorie (KatNr), CONSTRAINT fk_Struktur2 FOREIGN KEY (OKatNr) REFERENCES Kategorie_dummie (KatNr) ); CREATE TABLE Auktion( AuNr INTEGER, Knr INTEGER, Startpreis NUMERIC(6,2), Beginn DATE, Ende DATE, aktGebot NUMERIC (6,2), Sofortkaufoption BOOLEAN, Sofortkaufpreis NUMERIC(6,2), CONSTRAINT pk_Auktion PRIMARY KEY (AuNr), CONSTRAINT fk_Auktion1 FOREIGN KEY (KNr) REFERENCES Ebay_Kunde (KNr) ); CREATE TABLE Zuordnung( KatNr INTEGER, AuNr INTEGER, CONSTRAINT pk_Zuordung1 PRIMARY KEY (KatNr, AuNr), CONSTRAINT fk_Zuordnung1 FOREIGN KEY (KatNr) REFERENCES Kategorie (KatNr), CONSTRAINT fk_Zuordnung2 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Auktionstypzuordnung( ATNr INTEGER, AuNr INTEGER, CONSTRAINT pk_Auktionstypzuordung PRIMARY KEY (ATNr, AuNr), CONSTRAINT fk_Auktionszuordnung1 FOREIGN KEY (ATNr) REFERENCES Auktionstyp (ATNr), CONSTRAINT fk_Auktionstypzuordnung2 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Aktuell( AuNr INTEGER, CONSTRAINT pk_Aktuell PRIMARY KEY (AuNr), CONSTRAINT fk_Aktuell FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Gebot( GNr INTEGER, Knr INTEGER, AuNr INTEGER, Datum DATE, Zeit TIME, Hoehe NUMERIC (6,2), Sofortkauf BOOLEAN, CONSTRAINT pk_Gebot PRIMARY KEY (GNr), CONSTRAINT fk_Gebot1 FOREIGN KEY (KNr) REFERENCES Ebay_Kunde (KNr), CONSTRAINT fk_Gebot2 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Beobachtung( AuNr INTEGER, KNr INTEGER, CONSTRAINT pk_Beobachtung PRIMARY KEY (AuNr, KNr), CONSTRAINT fk_Beobachtung1 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr), CONSTRAINT fk_Beobachtungg2 FOREIGN KEY (KNr) REFERENCES Ebay_Kunde (KNr) ); CREATE TABLE Abschluss( GNR INTEGER, Preis NUMERIC (6,2), CONSTRAINT pk_Abschluss PRIMARY KEY (GNr), CONSTRAINT fk_Abschluss1 FOREIGN KEY (GNr) REFERENCES Gebot (GNr) ); CREATE TABLE Kommentar_Bewertung( GNr INTEGER, VonKNr INTEGER, AnKNr INTEGER, Kommentar VARCHAR(255), Erwiderung VARCHAR(255), Kommentar2 VARCHAR(255), Bewertungsart VARCHAR(255), CONSTRAINT pk_Kommentar_Bewertung PRIMARY KEY (GNr, vonKNr), CONSTRAINT fk_Kommentar_Bewertung1 FOREIGN KEY (GNr) REFERENCES Gebot (GNr), CONSTRAINT fk_Kommentar_Bewertung2 FOREIGN KEY (VonKNr) REFERENCES Ebay_Kunde (KNr), CONSTRAINT fk_Kommentar_Bewertung3 FOREIGN KEY (AnKNr) REFERENCES Ebay_Kunde_dummie (KNr) );", - }, - { - id: 5, - name: "Ebay, Daten (DDL)", - category: this.categories[0], - templateQuery: - "INSERT INTO Ebay_Kunde VALUES(100000, 'brocklesnar', 'Müller', 'Frank', 'Königsalle', '347a', '44795', 'Bochum', '185453942', '40060119', 2, 0, 100); INSERT INTO Ebay_Kunde VALUES(100001, 'supermoppelchen', 'Mayer', 'Max', 'Universiätsstraße', '99', '44221', 'Dortmund', '294153942', '50098763', 2, 0, 100); INSERT INTO Ebay_Kunde VALUES(100002, 'jandel', 'Schröder', 'Tim', 'Königswall', '108', '44164', 'Dortmund', '194359154', '35968716', 1, 1, 50); INSERT INTO Ebay_Kunde VALUES(100003, 'vossen', 'Weber', 'Franz', 'Leopoldstraße', '34', '80264', 'München', '468125987', '24868712', 0, 2, 0); INSERT INTO Ebay_Kunde VALUES(100004, 'steinmann', 'Kaufmann', 'Annabelle', 'Sonnenstraße', '12', '23957', 'Hamburg', '168945035', '12468725', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100005, 'roadrunner', 'Schulze', 'Anna-Maria', 'Lilienallee', '3', '10555', 'Berlin', '184695354', '40069722', 0, 1, 0); INSERT INTO Ebay_Kunde VALUES(100006, 'pittkuss', 'Schäfer', 'Simone', 'Burgstraße', '47', '30678', 'Hannover', '298648148', '30057458', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100007, 'masterflash', 'Franken', 'Stefanie', 'Mauerstraße', '58', '69122', 'Heidelberg', '397125984', '21485367', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100008, 'meikelex', 'Mustermann', 'Chris', 'Lüner Hellweg', '23', '06199', 'Halle', '195698456', '40298568', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100009, 'hobbyzuechter', 'Krämer', 'Thomas', 'Baroper Weg', '11', '62333', 'Frankfurt', '123987654', '46865215', 0, 1, 0); INSERT INTO Ebay_Kunde VALUES(100010, 'maurimirko', 'Schneider', 'Bettina', 'Zepelinstraße', '80', '51698', 'Köln', '198597364', '56661166', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100011, 'thorn', 'Schulz', 'Marc', 'Kaufingerstraße', '258', '89321', 'Ulm', '284697248', '20156986', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100012, 'timslaedle', 'Thomalla', 'Heinz', 'Landgrafenallee', '54', '97011', 'Würzburg', '365795148', '24465139', 0, 1, 0); INSERT INTO Ebay_Kunde VALUES(100013, 'virgenierot', 'Hoffmann', 'Erika', 'Hauptstraße', '80', '97877', 'Wertheim', '134598264', '34436915', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100014, 'kehrtag', 'Fischer', 'Franziska', 'Schloßalle', '65', '40359', 'Düsseldorf', '123456789', '12268820', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100015, 'homie', 'Neumann', 'Martin', 'Badstraße', '1c', '47555', 'Krefeld', '132198567', '45698723', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100000, 'brocklesnar', 'Müller', 'Frank', 'Königsalle', '347a', '44795', 'Bochum', '185453942', '40060119', 2, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100001, 'supermoppelchen', 'Mayer', 'Max', 'Universiätsstraße', '99', '44221', 'Dortmund', '294153942', '50098763', 2, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100002, 'jandel', 'Schröder', 'Tim', 'Königswall', '108', '44164', 'Dortmund', '194359154', '35968716', 1, 1, 50); INSERT INTO Ebay_Kunde_Dummie VALUES(100003, 'vossen', 'Weber', 'Franz', 'Leopoldstraße', '34', '80264', 'München', '468125987', '24868712', 0, 2, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100004, 'steinmann', 'Kaufmann', 'Annabelle', 'Sonnenstraße', '12', '23957', 'Hamburg', '168945035', '12468725', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100005, 'roadrunner', 'Schulze', 'Anna-Maria', 'Lilienallee', '3', '10555', 'Berlin', '184695354', '40069722', 0, 1, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100006, 'pittkuss', 'Schäfer', 'Simone', 'Burgstraße', '47', '30678', 'Hannover', '298648148', '30057458', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100007, 'masterflash', 'Franken', 'Stefanie', 'Mauerstraße', '58', '69122', 'Heidelberg', '397125984', '21485367', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100008, 'meikelex', 'Mustermann', 'Chris', 'Lüner Hellweg', '23', '06199', 'Halle', '195698456', '40298568', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100009, 'hobbyzuechter', 'Krämer', 'Thomas', 'Baroper Weg', '11', '62333', 'Frankfurt', '123987654', '46865215', 0, 1, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100010, 'maurimirko', 'Schneider', 'Bettina', 'Zepelinstraße', '80', '51698', 'Köln', '198597364', '56661166', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100011, 'thorn', 'Schulz', 'Marc', 'Kaufingerstraße', '258', '89321', 'Ulm', '284697248', '20156986', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100012, 'timslaedle', 'Thomalla', 'Heinz', 'Landgrafenallee', '54', '97011', 'Würzburg', '365795148', '24465139', 0, 1, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100013, 'virgenierot', 'Hoffmann', 'Erika', 'Hauptstraße', '80', '97877', 'Wertheim', '134598264', '34436915', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100014, 'kehrtag', 'Fischer', 'Franziska', 'Schloßalle', '65', '40359', 'Düsseldorf', '123456789', '12268820', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100015, 'homie', 'Neumann', 'Martin', 'Badstraße', '1c', '47555', 'Krefeld', '132198567', '45698723', 0, 0, 0); INSERT INTO Auktionstyp VALUES (1, 'SofortKaufen', 'Wenn Sie neben einem Angebot das Symbol SofortKaufen sehen, können Sie diesen Artikel sofort zu einem Festpreis kaufen.'); INSERT INTO Auktionstyp VALUES (2, 'Sofort&Neu', 'Wenn Sie neben einem Angebot das Symbol Sofort&Neu sehen, können Sie diesen Artikel sofort zu einem Festpreis kaufen.'); INSERT INTO Auktionstyp VALUES (3, 'Gebot', 'Innerhalb der Auktionsdauer kann eine Gebotsabgabe für einen Artikel abgegeben werden.'); INSERT INTO Kategorie VALUES (1, 'Audio & Hifi'); INSERT INTO Kategorie VALUES (2, 'CD Player'); INSERT INTO Kategorie VALUES (3, 'DJ Equipment'); INSERT INTO Kategorie VALUES (4, 'MP3 Player'); INSERT INTO Kategorie VALUES (5, 'Verstärker'); INSERT INTO Kategorie VALUES (6, 'Zubehör'); INSERT INTO Kategorie VALUES (7, 'Bücher'); INSERT INTO Kategorie VALUES (8, 'Belletristik'); INSERT INTO Kategorie VALUES (9, 'Kinder - & Jugendbücher'); INSERT INTO Kategorie VALUES (10, 'Sachbücher & Ratgeber'); INSERT INTO Kategorie VALUES (11, 'Schule & Ausbildung'); INSERT INTO Kategorie VALUES (12, 'Englischsprachige Bücher'); INSERT INTO Kategorie VALUES (13, 'Musik'); INSERT INTO Kategorie VALUES (14, 'CDs'); INSERT INTO Kategorie VALUES (15, 'Vinyl'); INSERT INTO Kategorie VALUES (16, 'Zubehör & Aufbewahrung'); INSERT INTO Kategorie VALUES (17, 'Hörbücher & Hörspiele'); INSERT INTO Kategorie VALUES (18, 'Fanartikel & Merchandise'); INSERT INTO Kategorie VALUES (19, 'Sport'); INSERT INTO Kategorie VALUES (20, 'Fubball'); INSERT INTO Kategorie VALUES (21, 'Camping & Outdoor'); INSERT INTO Kategorie VALUES (22, 'Inlineskating'); INSERT INTO Kategorie VALUES (23, 'Skisport'); INSERT INTO Kategorie VALUES (24, 'Bootsport'); INSERT INTO Kategorie VALUES (25, 'Tv, Video & Elektronik'); INSERT INTO Kategorie VALUES (26, 'Blu-Ray-Player'); INSERT INTO Kategorie VALUES (27, 'DVD-Player'); INSERT INTO Kategorie VALUES (28, 'Fernseher'); INSERT INTO Kategorie VALUES (29, 'GPS'); INSERT INTO Kategorie VALUES (30, 'Leinwände'); INSERT INTO Kategorie_Dummie VALUES (1, 'Audio & Hifi'); INSERT INTO Kategorie_Dummie VALUES (2, 'CD Player'); INSERT INTO Kategorie_Dummie VALUES (3, 'DJ Equipment'); INSERT INTO Kategorie_Dummie VALUES (4, 'MP3 Player'); INSERT INTO Kategorie_Dummie VALUES (5, 'Verstärker'); INSERT INTO Kategorie_Dummie VALUES (6, 'Zubehör'); INSERT INTO Kategorie_Dummie VALUES (7, 'Bücher'); INSERT INTO Kategorie_Dummie VALUES (8, 'Belletristik'); INSERT INTO Kategorie_Dummie VALUES (9, 'Kinder - & Jugendbücher'); INSERT INTO Kategorie_Dummie VALUES (10, 'Sachbücher & Ratgeber'); INSERT INTO Kategorie_Dummie VALUES (11, 'Schule & Ausbildung'); INSERT INTO Kategorie_Dummie VALUES (12, 'Englischsprachige Bücher'); INSERT INTO Kategorie_Dummie VALUES (13, 'Musik'); INSERT INTO Kategorie_Dummie VALUES (14, 'CDs'); INSERT INTO Kategorie_Dummie VALUES (15, 'Vinyl'); INSERT INTO Kategorie_Dummie VALUES (16, 'Zubehör & Aufbewahrung'); INSERT INTO Kategorie_Dummie VALUES (17, 'Hörbücher & Hörspiele'); INSERT INTO Kategorie_Dummie VALUES (18, 'Fanartikel & Merchandise'); INSERT INTO Kategorie_Dummie VALUES (19, 'Sport'); INSERT INTO Kategorie_Dummie VALUES (20, 'Fubball'); INSERT INTO Kategorie_Dummie VALUES (21, 'Camping & Outdoor'); INSERT INTO Kategorie_Dummie VALUES (22, 'Inlineskating'); INSERT INTO Kategorie_Dummie VALUES (23, 'Skisport'); INSERT INTO Kategorie_Dummie VALUES (24, 'Bootsport'); INSERT INTO Kategorie_Dummie VALUES (25, 'Tv, Video & Elektronik'); INSERT INTO Kategorie_Dummie VALUES (26, 'Blu-Ray-Player'); INSERT INTO Kategorie_Dummie VALUES (27, 'DVD-Player'); INSERT INTO Kategorie_Dummie VALUES (28, 'Fernseher'); INSERT INTO Kategorie_Dummie VALUES (29, 'GPS'); INSERT INTO Kategorie_Dummie VALUES (30, 'Leinwände'); INSERT INTO Struktur VALUES (2, 1); INSERT INTO Struktur VALUES (3, 1); INSERT INTO Struktur VALUES (4, 1); INSERT INTO Struktur VALUES (5, 1); INSERT INTO Struktur VALUES (6, 1); INSERT INTO Struktur VALUES (8, 7); INSERT INTO Struktur VALUES (9, 7); INSERT INTO Struktur VALUES (10, 7); INSERT INTO Struktur VALUES (11, 7); INSERT INTO Struktur VALUES (12, 7); INSERT INTO Struktur VALUES (14, 11); INSERT INTO Struktur VALUES (15, 11); INSERT INTO Struktur VALUES (16, 11); INSERT INTO Struktur VALUES (17, 11); INSERT INTO Struktur VALUES (18, 11); INSERT INTO Struktur VALUES (20, 19); INSERT INTO Struktur VALUES (21, 19); INSERT INTO Struktur VALUES (22, 19); INSERT INTO Struktur VALUES (23, 19); INSERT INTO Struktur VALUES (24, 19); INSERT INTO Struktur VALUES (26, 25); INSERT INTO Struktur VALUES (27, 25); INSERT INTO Struktur VALUES (28, 25); INSERT INTO Struktur VALUES (29, 25); INSERT INTO Struktur VALUES (30, 25); INSERT INTO Auktion VALUES (1, 100000, 1.00, '20070101', '20070501', 6.00, true, 6.00); INSERT INTO Auktion VALUES (2, 100001, 1.50, '20070101', '20070501', 3.00, false, 6.50); INSERT INTO Auktion VALUES (3, 100002, 2.00, '20070301', '20070901', 7.00, true, 7.00); INSERT INTO Auktion VALUES (4, 100003, 3.50, '20070301', '20070901', 3.50, false, 8.50); INSERT INTO Auktion VALUES (5, 100000, 6.00, '20070301', '20070901', 11.00, true, 11.00); INSERT INTO Auktion VALUES (6, 100001, 9.99, '20070501', '20080301', 9.99, false, 14.99); INSERT INTO Auktion VALUES (7, 100002, 10.00, '20070501', '20080401', 15.00, true, 15.00); INSERT INTO Auktion VALUES (8, 100003, 15.00, '20070901', '20080501', 0.00, false, 22.50); INSERT INTO Auktion VALUES (9, 100005, 20.00, '20070901', '20080101', 0.00, true, 30.00); INSERT INTO Auktion VALUES (10, 100006, 40.00, '20070901', '20080201', 40.00, false, 60.00); INSERT INTO Auktion VALUES (11, 100007, 100.00, '20070901', '20080301', 150.00, true, 150.00); INSERT INTO Auktion VALUES (12, 100008, 250.00, '20070901', '20080401', 275.00, false, 375.00); INSERT INTO Auktion VALUES (13, 100009, 500.00, '20070901', '20080501', 750.00, true, 750.00); INSERT INTO Auktion VALUES (14, 100010, 5.00, '20070901', '20080601', 5.00, false, 7.50); INSERT INTO Auktion VALUES (15, 100011, 4.00, '20070901', '20080701', 0.00, true, 6.00); INSERT INTO Auktion VALUES (16, 100012, 50.00, '20070901', '20080801', 55.00, false, 75.00); INSERT INTO Auktion VALUES (17, 100013, 24.99, '20070901', '20080901', 0.00, true, 37.49); INSERT INTO Auktion VALUES (18, 100014, 99.99, '20080301', '20080901', 99.99, false, 149.99); INSERT INTO Auktion VALUES (19, 100003, 1.00, '20080401', '20080901', 1.50, true, 1.50); INSERT INTO Auktion VALUES (20, 100005, 35.00, '20080501', '20080901', 35.00, false, 52.50); INSERT INTO Auktion VALUES (21, 100006, 25.00, '20080901', '20080901', 37.50, true, 37.50); INSERT INTO Gebot VALUES (100, 100000, 1, '20070101', '00:00', 6.00, true); INSERT INTO Gebot VALUES (101, 100001, 2, '20070201', '01:00', 1.50, false); INSERT INTO Gebot VALUES (102, 100002, 3, '20070301', '02:00', 7.00, true); INSERT INTO Gebot VALUES (103, 100003, 4, '20070401', '03:00', 3.50, false); INSERT INTO Gebot VALUES (104, 100004, 5, '20070501', '04:00', 11.00, true); INSERT INTO Gebot VALUES (105, 100005, 6, '20070601', '05:00', 9.99, false); INSERT INTO Gebot VALUES (106, 100006, 7, '20070701', '06:00', 15.00, true); INSERT INTO Gebot VALUES (107, 100007, 2, '20070801', '07:00', 2, false); INSERT INTO Gebot VALUES (108, 100008, 2, '20070901', '08:00', 3, false); INSERT INTO Gebot VALUES (109, 100009, 10, '20071001', '09:00', 40.00, false); INSERT INTO Gebot VALUES (110, 100010, 11, '20071101', '10:00', 150.00, true); INSERT INTO Gebot VALUES (111, 100011, 12, '20071201', '11:00', 250.00, false); INSERT INTO Gebot VALUES (112, 100012, 13, '20080101', '12:00', 750.00, true); INSERT INTO Gebot VALUES (113, 100013, 14, '20080201', '13:00', 5.00, false); INSERT INTO Gebot VALUES (114, 100014, 12, '20080301', '14:00', 275, false); INSERT INTO Gebot VALUES (115, 100015, 16, '20080401', '15:00', 50, false); INSERT INTO Gebot VALUES (116, 100007, 16, '20080501', '16:00', 55, false); INSERT INTO Gebot VALUES (117, 100008, 18, '20080601', '17:00', 99.99, false); INSERT INTO Gebot VALUES (118, 100009, 19, '20080701', '18:00', 1.50, true); INSERT INTO Gebot VALUES (119, 100010, 20, '20080801', '19:00', 35.00, false); INSERT INTO Gebot VALUES (120, 100011, 21, '20080901', '20:00', 37.50, true); INSERT INTO Abschluss VALUES (100, 6.00); INSERT INTO Abschluss VALUES (102, 7.00); INSERT INTO Abschluss VALUES (103, 3.50); INSERT INTO Abschluss VALUES (104, 11.00); INSERT INTO Abschluss VALUES (105, 9.99); INSERT INTO Abschluss VALUES (106, 15.00); INSERT INTO Abschluss VALUES (108, 3); INSERT INTO Abschluss VALUES (109, 40.00); INSERT INTO Abschluss VALUES (110, 150.00); INSERT INTO Abschluss VALUES (112, 750.00); INSERT INTO Abschluss VALUES (113, 5.00); INSERT INTO Abschluss VALUES (114, 275); INSERT INTO Abschluss VALUES (116, 55); INSERT INTO Abschluss VALUES (117, 99.99); INSERT INTO Abschluss VALUES (118, 1.50); INSERT INTO Abschluss VALUES (119, 35.00); INSERT INTO Abschluss VALUES (120, 37.50); INSERT INTO Kommentar_Bewertung VALUES (100, 100011, 100000, 'Ware wie beschrieben . Versand schnell . Topp Ebayer', 'Danke', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (102, 100001, 100002, 'Super Ware!!! Immer Gerne!!!!', 'Viele Dank', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (103, 100002, 100003, 'Gibt 6,90 DHL Paket an und versendet als 3,90 Päckchen. Abzocke. Pfui. NEGATIV', '', '', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (104, 100003, 100000, 'Alles Bestens ,sehr netter ebayer', 'Sehr vielen Dank, für diese postive Bewertung', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (105, 100004, 100001, 'Übergabe gut gelaufen!', '', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (106, 100005, 100002, 'Negativ-Negativ-', 'Tolle Bewertung, gibts auch einen konkreten Grund?', '', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (108, 100007, 100001, 'sehr netter kontakt, bestens gelaufen', 'Wie darf ich denn den ersten Teil des Kommentars verstehen?', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (109, 100008, 100006, 'kam 1a+ an, gebrauchsspuren wie beschrieben', 'Soll das nun eine Kritik über Raucher sein?', '', 'neutral'); INSERT INTO Kommentar_Bewertung VALUES (110, 100009, 100007, 'turboschneller Versand!TOP Qualität!!Vielen Dank!!', 'Fantastisch, danke', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (112, 100011, 100009, 'Übt nach Auktionsende ungebührlichen Druck aus. Sehr fragwürdiges Auftreten.', 'KOMISCHER MENSCH,ERST KEINE BEWERTUNG, ABGEBEN,WENN MANN NACHFRAGT DANN SOWAS', 'Die Art der Frage macht einiges aus', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (113, 100012, 100010, 'Nicht ganz so guter Zustand ansonsten alles OK', 'BITTE DAS NÄCHSTE MAL ARTIKELBESCHREIBUNG GENAUER LESEN', 'Beschreibung war sehr interpretierbar', 'neutral'); INSERT INTO Kommentar_Bewertung VALUES (114, 100013, 100008, 'x', 'WAS IST DAS FÜR EINE BEWERTUNG??????', 'in meinen Kreisen bedeutet das auch :Alles super', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (116, 100015, 100012, 'Größenauszeichnung stimmt nicht', '', '', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (117, 100007, 100014, 'sehr schnell, alles gut,auch wenns eine nicht angegebene kleine macke gibt ;)', 'Muss dann wohl auf dem Postweg passiert sein - Sorry', 'War ja weiter auch nicht schlimm', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (118, 100008, 100003, 'Ware ok, Verpackung sehr schlecht', 'Als ich es losgeschickt habe, war die Verpackug noch in Ordnung', 'Das kann nicht alles auf dem Postweg passeiert sein, ich würde sagen eher am Verpackungsmaterial gespart', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (119, 100009, 100005, 'extrem unachtsame Ausdrucksweise/trotz Zahlung doppelter Beschwerde/Tipp:Yoga', 'Käufer hat die Ware erst nach Beschwerde u. 6 Wo. nach Kauf bezahlt. Frechheit!', 'Ich musste es halt erst testen bevor ich es bezahle, ganz ruhig', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (120, 100010, 100006, '!!! PERFEKT !!! Note 1a', 'Supi, thanks', '', 'positiv'); INSERT INTO Zuordnung VALUES (2, 1); INSERT INTO Zuordnung VALUES (3, 2); INSERT INTO Zuordnung VALUES (4, 3); INSERT INTO Zuordnung VALUES (5, 4); INSERT INTO Zuordnung VALUES (6, 5); INSERT INTO Zuordnung VALUES (8, 6); INSERT INTO Zuordnung VALUES (9, 7); INSERT INTO Zuordnung VALUES (10, 8); INSERT INTO Zuordnung VALUES (11, 9); INSERT INTO Zuordnung VALUES (12, 10); INSERT INTO Zuordnung VALUES (14, 11); INSERT INTO Zuordnung VALUES (15, 12); INSERT INTO Zuordnung VALUES (16, 13); INSERT INTO Zuordnung VALUES (17, 14); INSERT INTO Zuordnung VALUES (18, 15); INSERT INTO Zuordnung VALUES (20, 16); INSERT INTO Zuordnung VALUES (21, 17); INSERT INTO Zuordnung VALUES (22, 18); INSERT INTO Zuordnung VALUES (23, 19); INSERT INTO Zuordnung VALUES (24, 20); INSERT INTO Zuordnung VALUES (26, 21); INSERT INTO Auktionstypzuordnung VALUES (1, 1); INSERT INTO Auktionstypzuordnung VALUES (2, 2); INSERT INTO Auktionstypzuordnung VALUES (3, 3); INSERT INTO Auktionstypzuordnung VALUES (3, 4); INSERT INTO Auktionstypzuordnung VALUES (3, 5); INSERT INTO Auktionstypzuordnung VALUES (3, 6); INSERT INTO Auktionstypzuordnung VALUES (3, 7); INSERT INTO Auktionstypzuordnung VALUES (1, 8); INSERT INTO Auktionstypzuordnung VALUES (1, 9); INSERT INTO Auktionstypzuordnung VALUES (2, 10); INSERT INTO Auktionstypzuordnung VALUES (2, 11); INSERT INTO Auktionstypzuordnung VALUES (2, 12); INSERT INTO Auktionstypzuordnung VALUES (2, 13); INSERT INTO Auktionstypzuordnung VALUES (3, 14); INSERT INTO Auktionstypzuordnung VALUES (3, 15); INSERT INTO Auktionstypzuordnung VALUES (3, 16); INSERT INTO Auktionstypzuordnung VALUES (3, 17); INSERT INTO Auktionstypzuordnung VALUES (3, 18); INSERT INTO Auktionstypzuordnung VALUES (2, 19); INSERT INTO Auktionstypzuordnung VALUES (1, 20); INSERT INTO Auktionstypzuordnung VALUES (1, 21); INSERT INTO Beobachtung VALUES (1, 100011); INSERT INTO Beobachtung VALUES (2, 100000); INSERT INTO Beobachtung VALUES (3, 100001); INSERT INTO Beobachtung VALUES (4, 100002); INSERT INTO Beobachtung VALUES (5, 100003); INSERT INTO Beobachtung VALUES (6, 100004); INSERT INTO Beobachtung VALUES (7, 100005); INSERT INTO Beobachtung VALUES (2, 100006); INSERT INTO Beobachtung VALUES (2, 100007); INSERT INTO Beobachtung VALUES (10, 100008); INSERT INTO Beobachtung VALUES (11, 100009); INSERT INTO Beobachtung VALUES (12, 100010); INSERT INTO Beobachtung VALUES (13, 100011); INSERT INTO Beobachtung VALUES (14, 100012); INSERT INTO Beobachtung VALUES (12, 100013); INSERT INTO Beobachtung VALUES (16, 100014); INSERT INTO Beobachtung VALUES (16, 100015); INSERT INTO Beobachtung VALUES (18, 100007); INSERT INTO Beobachtung VALUES (19, 100008); INSERT INTO Beobachtung VALUES (20, 100009); INSERT INTO Beobachtung VALUES (21, 100010); INSERT INTO Beobachtung VALUES (10, 100002); INSERT INTO Beobachtung VALUES (4, 100014); INSERT INTO Beobachtung VALUES (8, 100011); INSERT INTO Aktuell VALUES (8); INSERT INTO Aktuell VALUES (9); INSERT INTO Aktuell VALUES (10); INSERT INTO Aktuell VALUES (11); INSERT INTO Aktuell VALUES (12); INSERT INTO Aktuell VALUES (13); INSERT INTO Aktuell VALUES (14); INSERT INTO Aktuell VALUES (15); INSERT INTO Aktuell VALUES (16); INSERT INTO Aktuell VALUES (17); INSERT INTO Aktuell VALUES (18); INSERT INTO Aktuell VALUES (19); INSERT INTO Aktuell VALUES (20); INSERT INTO Aktuell VALUES (21);", - }, - { - id: 6, - name: "Ebay, Schema + Daten", - category: this.categories[0], - templateQuery: - "CREATE TABLE Ebay_Kunde( Knr INTEGER, Nickname VARCHAR(255), Name VARCHAR(255), Vorname VARCHAR(255), Straße VARCHAR(255), Hnr VARCHAR(5), PLZ CHAR(5), Ort VARCHAR(255), KtoNr VARCHAR(10), BLZ VARCHAR(10), Anz_positiv INTEGER, Anz_negativ INTEGER, Gesamtstand INTEGER, CONSTRAINT pk_Kunde PRIMARY KEY (KNr) ); CREATE TABLE Ebay_Kunde_dummie( Knr INTEGER, Nickname VARCHAR(255), Name VARCHAR(255), Vorname VARCHAR(255), Straße VARCHAR(255), Hnr VARCHAR(5), PLZ CHAR(5), Ort VARCHAR(255), KtoNr VARCHAR(10), BLZ VARCHAR(10), Anz_positiv INTEGER, Anz_negativ INTEGER, Gesamtstand INTEGER, CONSTRAINT pk_Ebay_Kunde_dummie PRIMARY KEY (KNr) ); CREATE TABLE Auktionstyp( Atnr INTEGER , Bezeichnung VARCHAR(255), Beschreibung VARCHAR(255), CONSTRAINT pk_Auktionstyp PRIMARY KEY (Atnr) ); CREATE TABLE Kategorie( KatNr INTEGER, Bezeichnung VARCHAR(255), CONSTRAINT pk_Kategorie PRIMARY KEY (KatNr) ); CREATE TABLE Kategorie_dummie( KatNr INTEGER, Bezeichnung VARCHAR(255), CONSTRAINT pk_Kategorie_dummie PRIMARY KEY (KatNr) ); CREATE TABLE Struktur( UKatNr INTEGER, OKatNr INTEGER, CONSTRAINT pk_Struktur PRIMARY KEY (UKatNr), CONSTRAINT fk_Struktur1 FOREIGN KEY (UKatNr) REFERENCES Kategorie (KatNr), CONSTRAINT fk_Struktur2 FOREIGN KEY (OKatNr) REFERENCES Kategorie_dummie (KatNr) ); CREATE TABLE Auktion( AuNr INTEGER, Knr INTEGER, Startpreis NUMERIC(6,2), Beginn DATE, Ende DATE, aktGebot NUMERIC (6,2), Sofortkaufoption BOOLEAN, Sofortkaufpreis NUMERIC(6,2), CONSTRAINT pk_Auktion PRIMARY KEY (AuNr), CONSTRAINT fk_Auktion1 FOREIGN KEY (KNr) REFERENCES Ebay_Kunde (KNr) ); CREATE TABLE Zuordnung( KatNr INTEGER, AuNr INTEGER, CONSTRAINT pk_Zuordung1 PRIMARY KEY (KatNr, AuNr), CONSTRAINT fk_Zuordnung1 FOREIGN KEY (KatNr) REFERENCES Kategorie (KatNr), CONSTRAINT fk_Zuordnung2 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Auktionstypzuordnung( ATNr INTEGER, AuNr INTEGER, CONSTRAINT pk_Auktionstypzuordung PRIMARY KEY (ATNr, AuNr), CONSTRAINT fk_Auktionszuordnung1 FOREIGN KEY (ATNr) REFERENCES Auktionstyp (ATNr), CONSTRAINT fk_Auktionstypzuordnung2 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Aktuell( AuNr INTEGER, CONSTRAINT pk_Aktuell PRIMARY KEY (AuNr), CONSTRAINT fk_Aktuell FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Gebot( GNr INTEGER, Knr INTEGER, AuNr INTEGER, Datum DATE, Zeit TIME, Hoehe NUMERIC (6,2), Sofortkauf BOOLEAN, CONSTRAINT pk_Gebot PRIMARY KEY (GNr), CONSTRAINT fk_Gebot1 FOREIGN KEY (KNr) REFERENCES Ebay_Kunde (KNr), CONSTRAINT fk_Gebot2 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Beobachtung( AuNr INTEGER, KNr INTEGER, CONSTRAINT pk_Beobachtung PRIMARY KEY (AuNr, KNr), CONSTRAINT fk_Beobachtung1 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr), CONSTRAINT fk_Beobachtungg2 FOREIGN KEY (KNr) REFERENCES Ebay_Kunde (KNr) ); CREATE TABLE Abschluss( GNR INTEGER, Preis NUMERIC (6,2), CONSTRAINT pk_Abschluss PRIMARY KEY (GNr), CONSTRAINT fk_Abschluss1 FOREIGN KEY (GNr) REFERENCES Gebot (GNr) ); CREATE TABLE Kommentar_Bewertung( GNr INTEGER, VonKNr INTEGER, AnKNr INTEGER, Kommentar VARCHAR(255), Erwiderung VARCHAR(255), Kommentar2 VARCHAR(255), Bewertungsart VARCHAR(255), CONSTRAINT pk_Kommentar_Bewertung PRIMARY KEY (GNr, vonKNr), CONSTRAINT fk_Kommentar_Bewertung1 FOREIGN KEY (GNr) REFERENCES Gebot (GNr), CONSTRAINT fk_Kommentar_Bewertung2 FOREIGN KEY (VonKNr) REFERENCES Ebay_Kunde (KNr), CONSTRAINT fk_Kommentar_Bewertung3 FOREIGN KEY (AnKNr) REFERENCES Ebay_Kunde_dummie (KNr) ); INSERT INTO Ebay_Kunde VALUES(100000, 'brocklesnar', 'Müller', 'Frank', 'Königsalle', '347a', '44795', 'Bochum', '185453942', '40060119', 2, 0, 100); INSERT INTO Ebay_Kunde VALUES(100001, 'supermoppelchen', 'Mayer', 'Max', 'Universiätsstraße', '99', '44221', 'Dortmund', '294153942', '50098763', 2, 0, 100); INSERT INTO Ebay_Kunde VALUES(100002, 'jandel', 'Schröder', 'Tim', 'Königswall', '108', '44164', 'Dortmund', '194359154', '35968716', 1, 1, 50); INSERT INTO Ebay_Kunde VALUES(100003, 'vossen', 'Weber', 'Franz', 'Leopoldstraße', '34', '80264', 'München', '468125987', '24868712', 0, 2, 0); INSERT INTO Ebay_Kunde VALUES(100004, 'steinmann', 'Kaufmann', 'Annabelle', 'Sonnenstraße', '12', '23957', 'Hamburg', '168945035', '12468725', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100005, 'roadrunner', 'Schulze', 'Anna-Maria', 'Lilienallee', '3', '10555', 'Berlin', '184695354', '40069722', 0, 1, 0); INSERT INTO Ebay_Kunde VALUES(100006, 'pittkuss', 'Schäfer', 'Simone', 'Burgstraße', '47', '30678', 'Hannover', '298648148', '30057458', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100007, 'masterflash', 'Franken', 'Stefanie', 'Mauerstraße', '58', '69122', 'Heidelberg', '397125984', '21485367', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100008, 'meikelex', 'Mustermann', 'Chris', 'Lüner Hellweg', '23', '06199', 'Halle', '195698456', '40298568', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100009, 'hobbyzuechter', 'Krämer', 'Thomas', 'Baroper Weg', '11', '62333', 'Frankfurt', '123987654', '46865215', 0, 1, 0); INSERT INTO Ebay_Kunde VALUES(100010, 'maurimirko', 'Schneider', 'Bettina', 'Zepelinstraße', '80', '51698', 'Köln', '198597364', '56661166', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100011, 'thorn', 'Schulz', 'Marc', 'Kaufingerstraße', '258', '89321', 'Ulm', '284697248', '20156986', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100012, 'timslaedle', 'Thomalla', 'Heinz', 'Landgrafenallee', '54', '97011', 'Würzburg', '365795148', '24465139', 0, 1, 0); INSERT INTO Ebay_Kunde VALUES(100013, 'virgenierot', 'Hoffmann', 'Erika', 'Hauptstraße', '80', '97877', 'Wertheim', '134598264', '34436915', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100014, 'kehrtag', 'Fischer', 'Franziska', 'Schloßalle', '65', '40359', 'Düsseldorf', '123456789', '12268820', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100015, 'homie', 'Neumann', 'Martin', 'Badstraße', '1c', '47555', 'Krefeld', '132198567', '45698723', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100000, 'brocklesnar', 'Müller', 'Frank', 'Königsalle', '347a', '44795', 'Bochum', '185453942', '40060119', 2, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100001, 'supermoppelchen', 'Mayer', 'Max', 'Universiätsstraße', '99', '44221', 'Dortmund', '294153942', '50098763', 2, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100002, 'jandel', 'Schröder', 'Tim', 'Königswall', '108', '44164', 'Dortmund', '194359154', '35968716', 1, 1, 50); INSERT INTO Ebay_Kunde_Dummie VALUES(100003, 'vossen', 'Weber', 'Franz', 'Leopoldstraße', '34', '80264', 'München', '468125987', '24868712', 0, 2, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100004, 'steinmann', 'Kaufmann', 'Annabelle', 'Sonnenstraße', '12', '23957', 'Hamburg', '168945035', '12468725', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100005, 'roadrunner', 'Schulze', 'Anna-Maria', 'Lilienallee', '3', '10555', 'Berlin', '184695354', '40069722', 0, 1, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100006, 'pittkuss', 'Schäfer', 'Simone', 'Burgstraße', '47', '30678', 'Hannover', '298648148', '30057458', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100007, 'masterflash', 'Franken', 'Stefanie', 'Mauerstraße', '58', '69122', 'Heidelberg', '397125984', '21485367', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100008, 'meikelex', 'Mustermann', 'Chris', 'Lüner Hellweg', '23', '06199', 'Halle', '195698456', '40298568', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100009, 'hobbyzuechter', 'Krämer', 'Thomas', 'Baroper Weg', '11', '62333', 'Frankfurt', '123987654', '46865215', 0, 1, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100010, 'maurimirko', 'Schneider', 'Bettina', 'Zepelinstraße', '80', '51698', 'Köln', '198597364', '56661166', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100011, 'thorn', 'Schulz', 'Marc', 'Kaufingerstraße', '258', '89321', 'Ulm', '284697248', '20156986', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100012, 'timslaedle', 'Thomalla', 'Heinz', 'Landgrafenallee', '54', '97011', 'Würzburg', '365795148', '24465139', 0, 1, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100013, 'virgenierot', 'Hoffmann', 'Erika', 'Hauptstraße', '80', '97877', 'Wertheim', '134598264', '34436915', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100014, 'kehrtag', 'Fischer', 'Franziska', 'Schloßalle', '65', '40359', 'Düsseldorf', '123456789', '12268820', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100015, 'homie', 'Neumann', 'Martin', 'Badstraße', '1c', '47555', 'Krefeld', '132198567', '45698723', 0, 0, 0); INSERT INTO Auktionstyp VALUES (1, 'SofortKaufen', 'Wenn Sie neben einem Angebot das Symbol SofortKaufen sehen, können Sie diesen Artikel sofort zu einem Festpreis kaufen.'); INSERT INTO Auktionstyp VALUES (2, 'Sofort&Neu', 'Wenn Sie neben einem Angebot das Symbol Sofort&Neu sehen, können Sie diesen Artikel sofort zu einem Festpreis kaufen.'); INSERT INTO Auktionstyp VALUES (3, 'Gebot', 'Innerhalb der Auktionsdauer kann eine Gebotsabgabe für einen Artikel abgegeben werden.'); INSERT INTO Kategorie VALUES (1, 'Audio & Hifi'); INSERT INTO Kategorie VALUES (2, 'CD Player'); INSERT INTO Kategorie VALUES (3, 'DJ Equipment'); INSERT INTO Kategorie VALUES (4, 'MP3 Player'); INSERT INTO Kategorie VALUES (5, 'Verstärker'); INSERT INTO Kategorie VALUES (6, 'Zubehör'); INSERT INTO Kategorie VALUES (7, 'Bücher'); INSERT INTO Kategorie VALUES (8, 'Belletristik'); INSERT INTO Kategorie VALUES (9, 'Kinder - & Jugendbücher'); INSERT INTO Kategorie VALUES (10, 'Sachbücher & Ratgeber'); INSERT INTO Kategorie VALUES (11, 'Schule & Ausbildung'); INSERT INTO Kategorie VALUES (12, 'Englischsprachige Bücher'); INSERT INTO Kategorie VALUES (13, 'Musik'); INSERT INTO Kategorie VALUES (14, 'CDs'); INSERT INTO Kategorie VALUES (15, 'Vinyl'); INSERT INTO Kategorie VALUES (16, 'Zubehör & Aufbewahrung'); INSERT INTO Kategorie VALUES (17, 'Hörbücher & Hörspiele'); INSERT INTO Kategorie VALUES (18, 'Fanartikel & Merchandise'); INSERT INTO Kategorie VALUES (19, 'Sport'); INSERT INTO Kategorie VALUES (20, 'Fubball'); INSERT INTO Kategorie VALUES (21, 'Camping & Outdoor'); INSERT INTO Kategorie VALUES (22, 'Inlineskating'); INSERT INTO Kategorie VALUES (23, 'Skisport'); INSERT INTO Kategorie VALUES (24, 'Bootsport'); INSERT INTO Kategorie VALUES (25, 'Tv, Video & Elektronik'); INSERT INTO Kategorie VALUES (26, 'Blu-Ray-Player'); INSERT INTO Kategorie VALUES (27, 'DVD-Player'); INSERT INTO Kategorie VALUES (28, 'Fernseher'); INSERT INTO Kategorie VALUES (29, 'GPS'); INSERT INTO Kategorie VALUES (30, 'Leinwände'); INSERT INTO Kategorie_Dummie VALUES (1, 'Audio & Hifi'); INSERT INTO Kategorie_Dummie VALUES (2, 'CD Player'); INSERT INTO Kategorie_Dummie VALUES (3, 'DJ Equipment'); INSERT INTO Kategorie_Dummie VALUES (4, 'MP3 Player'); INSERT INTO Kategorie_Dummie VALUES (5, 'Verstärker'); INSERT INTO Kategorie_Dummie VALUES (6, 'Zubehör'); INSERT INTO Kategorie_Dummie VALUES (7, 'Bücher'); INSERT INTO Kategorie_Dummie VALUES (8, 'Belletristik'); INSERT INTO Kategorie_Dummie VALUES (9, 'Kinder - & Jugendbücher'); INSERT INTO Kategorie_Dummie VALUES (10, 'Sachbücher & Ratgeber'); INSERT INTO Kategorie_Dummie VALUES (11, 'Schule & Ausbildung'); INSERT INTO Kategorie_Dummie VALUES (12, 'Englischsprachige Bücher'); INSERT INTO Kategorie_Dummie VALUES (13, 'Musik'); INSERT INTO Kategorie_Dummie VALUES (14, 'CDs'); INSERT INTO Kategorie_Dummie VALUES (15, 'Vinyl'); INSERT INTO Kategorie_Dummie VALUES (16, 'Zubehör & Aufbewahrung'); INSERT INTO Kategorie_Dummie VALUES (17, 'Hörbücher & Hörspiele'); INSERT INTO Kategorie_Dummie VALUES (18, 'Fanartikel & Merchandise'); INSERT INTO Kategorie_Dummie VALUES (19, 'Sport'); INSERT INTO Kategorie_Dummie VALUES (20, 'Fubball'); INSERT INTO Kategorie_Dummie VALUES (21, 'Camping & Outdoor'); INSERT INTO Kategorie_Dummie VALUES (22, 'Inlineskating'); INSERT INTO Kategorie_Dummie VALUES (23, 'Skisport'); INSERT INTO Kategorie_Dummie VALUES (24, 'Bootsport'); INSERT INTO Kategorie_Dummie VALUES (25, 'Tv, Video & Elektronik'); INSERT INTO Kategorie_Dummie VALUES (26, 'Blu-Ray-Player'); INSERT INTO Kategorie_Dummie VALUES (27, 'DVD-Player'); INSERT INTO Kategorie_Dummie VALUES (28, 'Fernseher'); INSERT INTO Kategorie_Dummie VALUES (29, 'GPS'); INSERT INTO Kategorie_Dummie VALUES (30, 'Leinwände'); INSERT INTO Struktur VALUES (2, 1); INSERT INTO Struktur VALUES (3, 1); INSERT INTO Struktur VALUES (4, 1); INSERT INTO Struktur VALUES (5, 1); INSERT INTO Struktur VALUES (6, 1); INSERT INTO Struktur VALUES (8, 7); INSERT INTO Struktur VALUES (9, 7); INSERT INTO Struktur VALUES (10, 7); INSERT INTO Struktur VALUES (11, 7); INSERT INTO Struktur VALUES (12, 7); INSERT INTO Struktur VALUES (14, 11); INSERT INTO Struktur VALUES (15, 11); INSERT INTO Struktur VALUES (16, 11); INSERT INTO Struktur VALUES (17, 11); INSERT INTO Struktur VALUES (18, 11); INSERT INTO Struktur VALUES (20, 19); INSERT INTO Struktur VALUES (21, 19); INSERT INTO Struktur VALUES (22, 19); INSERT INTO Struktur VALUES (23, 19); INSERT INTO Struktur VALUES (24, 19); INSERT INTO Struktur VALUES (26, 25); INSERT INTO Struktur VALUES (27, 25); INSERT INTO Struktur VALUES (28, 25); INSERT INTO Struktur VALUES (29, 25); INSERT INTO Struktur VALUES (30, 25); INSERT INTO Auktion VALUES (1, 100000, 1.00, '20070101', '20070501', 6.00, true, 6.00); INSERT INTO Auktion VALUES (2, 100001, 1.50, '20070101', '20070501', 3.00, false, 6.50); INSERT INTO Auktion VALUES (3, 100002, 2.00, '20070301', '20070901', 7.00, true, 7.00); INSERT INTO Auktion VALUES (4, 100003, 3.50, '20070301', '20070901', 3.50, false, 8.50); INSERT INTO Auktion VALUES (5, 100000, 6.00, '20070301', '20070901', 11.00, true, 11.00); INSERT INTO Auktion VALUES (6, 100001, 9.99, '20070501', '20080301', 9.99, false, 14.99); INSERT INTO Auktion VALUES (7, 100002, 10.00, '20070501', '20080401', 15.00, true, 15.00); INSERT INTO Auktion VALUES (8, 100003, 15.00, '20070901', '20080501', 0.00, false, 22.50); INSERT INTO Auktion VALUES (9, 100005, 20.00, '20070901', '20080101', 0.00, true, 30.00); INSERT INTO Auktion VALUES (10, 100006, 40.00, '20070901', '20080201', 40.00, false, 60.00); INSERT INTO Auktion VALUES (11, 100007, 100.00, '20070901', '20080301', 150.00, true, 150.00); INSERT INTO Auktion VALUES (12, 100008, 250.00, '20070901', '20080401', 275.00, false, 375.00); INSERT INTO Auktion VALUES (13, 100009, 500.00, '20070901', '20080501', 750.00, true, 750.00); INSERT INTO Auktion VALUES (14, 100010, 5.00, '20070901', '20080601', 5.00, false, 7.50); INSERT INTO Auktion VALUES (15, 100011, 4.00, '20070901', '20080701', 0.00, true, 6.00); INSERT INTO Auktion VALUES (16, 100012, 50.00, '20070901', '20080801', 55.00, false, 75.00); INSERT INTO Auktion VALUES (17, 100013, 24.99, '20070901', '20080901', 0.00, true, 37.49); INSERT INTO Auktion VALUES (18, 100014, 99.99, '20080301', '20080901', 99.99, false, 149.99); INSERT INTO Auktion VALUES (19, 100003, 1.00, '20080401', '20080901', 1.50, true, 1.50); INSERT INTO Auktion VALUES (20, 100005, 35.00, '20080501', '20080901', 35.00, false, 52.50); INSERT INTO Auktion VALUES (21, 100006, 25.00, '20080901', '20080901', 37.50, true, 37.50); INSERT INTO Gebot VALUES (100, 100000, 1, '20070101', '00:00', 6.00, true); INSERT INTO Gebot VALUES (101, 100001, 2, '20070201', '01:00', 1.50, false); INSERT INTO Gebot VALUES (102, 100002, 3, '20070301', '02:00', 7.00, true); INSERT INTO Gebot VALUES (103, 100003, 4, '20070401', '03:00', 3.50, false); INSERT INTO Gebot VALUES (104, 100004, 5, '20070501', '04:00', 11.00, true); INSERT INTO Gebot VALUES (105, 100005, 6, '20070601', '05:00', 9.99, false); INSERT INTO Gebot VALUES (106, 100006, 7, '20070701', '06:00', 15.00, true); INSERT INTO Gebot VALUES (107, 100007, 2, '20070801', '07:00', 2, false); INSERT INTO Gebot VALUES (108, 100008, 2, '20070901', '08:00', 3, false); INSERT INTO Gebot VALUES (109, 100009, 10, '20071001', '09:00', 40.00, false); INSERT INTO Gebot VALUES (110, 100010, 11, '20071101', '10:00', 150.00, true); INSERT INTO Gebot VALUES (111, 100011, 12, '20071201', '11:00', 250.00, false); INSERT INTO Gebot VALUES (112, 100012, 13, '20080101', '12:00', 750.00, true); INSERT INTO Gebot VALUES (113, 100013, 14, '20080201', '13:00', 5.00, false); INSERT INTO Gebot VALUES (114, 100014, 12, '20080301', '14:00', 275, false); INSERT INTO Gebot VALUES (115, 100015, 16, '20080401', '15:00', 50, false); INSERT INTO Gebot VALUES (116, 100007, 16, '20080501', '16:00', 55, false); INSERT INTO Gebot VALUES (117, 100008, 18, '20080601', '17:00', 99.99, false); INSERT INTO Gebot VALUES (118, 100009, 19, '20080701', '18:00', 1.50, true); INSERT INTO Gebot VALUES (119, 100010, 20, '20080801', '19:00', 35.00, false); INSERT INTO Gebot VALUES (120, 100011, 21, '20080901', '20:00', 37.50, true); INSERT INTO Abschluss VALUES (100, 6.00); INSERT INTO Abschluss VALUES (102, 7.00); INSERT INTO Abschluss VALUES (103, 3.50); INSERT INTO Abschluss VALUES (104, 11.00); INSERT INTO Abschluss VALUES (105, 9.99); INSERT INTO Abschluss VALUES (106, 15.00); INSERT INTO Abschluss VALUES (108, 3); INSERT INTO Abschluss VALUES (109, 40.00); INSERT INTO Abschluss VALUES (110, 150.00); INSERT INTO Abschluss VALUES (112, 750.00); INSERT INTO Abschluss VALUES (113, 5.00); INSERT INTO Abschluss VALUES (114, 275); INSERT INTO Abschluss VALUES (116, 55); INSERT INTO Abschluss VALUES (117, 99.99); INSERT INTO Abschluss VALUES (118, 1.50); INSERT INTO Abschluss VALUES (119, 35.00); INSERT INTO Abschluss VALUES (120, 37.50); INSERT INTO Kommentar_Bewertung VALUES (100, 100011, 100000, 'Ware wie beschrieben . Versand schnell . Topp Ebayer', 'Danke', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (102, 100001, 100002, 'Super Ware!!! Immer Gerne!!!!', 'Viele Dank', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (103, 100002, 100003, 'Gibt 6,90 DHL Paket an und versendet als 3,90 Päckchen. Abzocke. Pfui. NEGATIV', '', '', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (104, 100003, 100000, 'Alles Bestens ,sehr netter ebayer', 'Sehr vielen Dank, für diese postive Bewertung', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (105, 100004, 100001, 'Übergabe gut gelaufen!', '', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (106, 100005, 100002, 'Negativ-Negativ-', 'Tolle Bewertung, gibts auch einen konkreten Grund?', '', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (108, 100007, 100001, 'sehr netter kontakt, bestens gelaufen', 'Wie darf ich denn den ersten Teil des Kommentars verstehen?', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (109, 100008, 100006, 'kam 1a+ an, gebrauchsspuren wie beschrieben', 'Soll das nun eine Kritik über Raucher sein?', '', 'neutral'); INSERT INTO Kommentar_Bewertung VALUES (110, 100009, 100007, 'turboschneller Versand!TOP Qualität!!Vielen Dank!!', 'Fantastisch, danke', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (112, 100011, 100009, 'Übt nach Auktionsende ungebührlichen Druck aus. Sehr fragwürdiges Auftreten.', 'KOMISCHER MENSCH,ERST KEINE BEWERTUNG, ABGEBEN,WENN MANN NACHFRAGT DANN SOWAS', 'Die Art der Frage macht einiges aus', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (113, 100012, 100010, 'Nicht ganz so guter Zustand ansonsten alles OK', 'BITTE DAS NÄCHSTE MAL ARTIKELBESCHREIBUNG GENAUER LESEN', 'Beschreibung war sehr interpretierbar', 'neutral'); INSERT INTO Kommentar_Bewertung VALUES (114, 100013, 100008, 'x', 'WAS IST DAS FÜR EINE BEWERTUNG??????', 'in meinen Kreisen bedeutet das auch :Alles super', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (116, 100015, 100012, 'Größenauszeichnung stimmt nicht', '', '', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (117, 100007, 100014, 'sehr schnell, alles gut,auch wenns eine nicht angegebene kleine macke gibt ;)', 'Muss dann wohl auf dem Postweg passiert sein - Sorry', 'War ja weiter auch nicht schlimm', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (118, 100008, 100003, 'Ware ok, Verpackung sehr schlecht', 'Als ich es losgeschickt habe, war die Verpackug noch in Ordnung', 'Das kann nicht alles auf dem Postweg passeiert sein, ich würde sagen eher am Verpackungsmaterial gespart', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (119, 100009, 100005, 'extrem unachtsame Ausdrucksweise/trotz Zahlung doppelter Beschwerde/Tipp:Yoga', 'Käufer hat die Ware erst nach Beschwerde u. 6 Wo. nach Kauf bezahlt. Frechheit!', 'Ich musste es halt erst testen bevor ich es bezahle, ganz ruhig', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (120, 100010, 100006, '!!! PERFEKT !!! Note 1a', 'Supi, thanks', '', 'positiv'); INSERT INTO Zuordnung VALUES (2, 1); INSERT INTO Zuordnung VALUES (3, 2); INSERT INTO Zuordnung VALUES (4, 3); INSERT INTO Zuordnung VALUES (5, 4); INSERT INTO Zuordnung VALUES (6, 5); INSERT INTO Zuordnung VALUES (8, 6); INSERT INTO Zuordnung VALUES (9, 7); INSERT INTO Zuordnung VALUES (10, 8); INSERT INTO Zuordnung VALUES (11, 9); INSERT INTO Zuordnung VALUES (12, 10); INSERT INTO Zuordnung VALUES (14, 11); INSERT INTO Zuordnung VALUES (15, 12); INSERT INTO Zuordnung VALUES (16, 13); INSERT INTO Zuordnung VALUES (17, 14); INSERT INTO Zuordnung VALUES (18, 15); INSERT INTO Zuordnung VALUES (20, 16); INSERT INTO Zuordnung VALUES (21, 17); INSERT INTO Zuordnung VALUES (22, 18); INSERT INTO Zuordnung VALUES (23, 19); INSERT INTO Zuordnung VALUES (24, 20); INSERT INTO Zuordnung VALUES (26, 21); INSERT INTO Auktionstypzuordnung VALUES (1, 1); INSERT INTO Auktionstypzuordnung VALUES (2, 2); INSERT INTO Auktionstypzuordnung VALUES (3, 3); INSERT INTO Auktionstypzuordnung VALUES (3, 4); INSERT INTO Auktionstypzuordnung VALUES (3, 5); INSERT INTO Auktionstypzuordnung VALUES (3, 6); INSERT INTO Auktionstypzuordnung VALUES (3, 7); INSERT INTO Auktionstypzuordnung VALUES (1, 8); INSERT INTO Auktionstypzuordnung VALUES (1, 9); INSERT INTO Auktionstypzuordnung VALUES (2, 10); INSERT INTO Auktionstypzuordnung VALUES (2, 11); INSERT INTO Auktionstypzuordnung VALUES (2, 12); INSERT INTO Auktionstypzuordnung VALUES (2, 13); INSERT INTO Auktionstypzuordnung VALUES (3, 14); INSERT INTO Auktionstypzuordnung VALUES (3, 15); INSERT INTO Auktionstypzuordnung VALUES (3, 16); INSERT INTO Auktionstypzuordnung VALUES (3, 17); INSERT INTO Auktionstypzuordnung VALUES (3, 18); INSERT INTO Auktionstypzuordnung VALUES (2, 19); INSERT INTO Auktionstypzuordnung VALUES (1, 20); INSERT INTO Auktionstypzuordnung VALUES (1, 21); INSERT INTO Beobachtung VALUES (1, 100011); INSERT INTO Beobachtung VALUES (2, 100000); INSERT INTO Beobachtung VALUES (3, 100001); INSERT INTO Beobachtung VALUES (4, 100002); INSERT INTO Beobachtung VALUES (5, 100003); INSERT INTO Beobachtung VALUES (6, 100004); INSERT INTO Beobachtung VALUES (7, 100005); INSERT INTO Beobachtung VALUES (2, 100006); INSERT INTO Beobachtung VALUES (2, 100007); INSERT INTO Beobachtung VALUES (10, 100008); INSERT INTO Beobachtung VALUES (11, 100009); INSERT INTO Beobachtung VALUES (12, 100010); INSERT INTO Beobachtung VALUES (13, 100011); INSERT INTO Beobachtung VALUES (14, 100012); INSERT INTO Beobachtung VALUES (12, 100013); INSERT INTO Beobachtung VALUES (16, 100014); INSERT INTO Beobachtung VALUES (16, 100015); INSERT INTO Beobachtung VALUES (18, 100007); INSERT INTO Beobachtung VALUES (19, 100008); INSERT INTO Beobachtung VALUES (20, 100009); INSERT INTO Beobachtung VALUES (21, 100010); INSERT INTO Beobachtung VALUES (10, 100002); INSERT INTO Beobachtung VALUES (4, 100014); INSERT INTO Beobachtung VALUES (8, 100011); INSERT INTO Aktuell VALUES (8); INSERT INTO Aktuell VALUES (9); INSERT INTO Aktuell VALUES (10); INSERT INTO Aktuell VALUES (11); INSERT INTO Aktuell VALUES (12); INSERT INTO Aktuell VALUES (13); INSERT INTO Aktuell VALUES (14); INSERT INTO Aktuell VALUES (15); INSERT INTO Aktuell VALUES (16); INSERT INTO Aktuell VALUES (17); INSERT INTO Aktuell VALUES (18); INSERT INTO Aktuell VALUES (19); INSERT INTO Aktuell VALUES (20); INSERT INTO Aktuell VALUES (21);", - }, - { - id: 7, - name: "ÜB1: Hotelbeispiel", - category: this.categories[1], - templateQuery: - "CREATE TABLE hotel ( HoNr INTEGER NOT NULL, HName VARCHAR(40), Ort VARCHAR(40), Straße VARCHAR(40), HausNr VARCHAR(5), PLZ CHAR(5), CONSTRAINT pk_hotel PRIMARY KEY(HoNr)); CREATE TABLE zimmer ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ZName VARCHAR(40), Kapazitaet INTEGER, Preis DECIMAL(8, 2), CONSTRAINT pk_zimmer PRIMARY KEY(HoNr, ZNr), CONSTRAINT fk_zimmer FOREIGN KEY(HoNr) REFERENCES hotel(HoNr)); CREATE TABLE ausstattung ( ANr INTEGER NOT NULL, Bezeichnung VARCHAR(40), Zusatzkosten DECIMAL(8, 2), CONSTRAINT pk_ausstattung PRIMARY KEY(ANr)); CREATE TABLE normal ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ANr INTEGER NOT NULL, CONSTRAINT pk_normal PRIMARY KEY(HoNr, ZNr, ANr), CONSTRAINT fk_normal_1 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT fk_normal_2 FOREIGN KEY(HoNr, ZNr) REFERENCES zimmer(HoNr, ZNr)); CREATE TABLE gast ( GNr INTEGER NOT NULL, Name VARCHAR(30), Vorname VARCHAR(40), Ort VARCHAR(50), PLZ CHAR(5), Strasse VARCHAR(50), HausNr VARCHAR(5), CONSTRAINT pk_gast PRIMARY KEY(GNr)); INSERT INTO hotel VALUES(132,'Gruene Bogenschuetze','Geseke','An der Abtei','3','59590'); INSERT INTO zimmer VALUES(132, 115,'Waldruh', 2, 55.34); INSERT INTO zimmer VALUES(132, 134,'Hochsitz', 4, 89.47); INSERT INTO gast VALUES(95792,'Müller','Martin','Musterstadt','10000','Poststrasse','13-15'); INSERT INTO ausstattung VALUES(1,'Großleinwand mit Beamer','24.50'); INSERT INTO ausstattung VALUES(2,'Film Titanic','2.35'); INSERT INTO ausstattung VALUES(3,'DVD-Player', 18.52); INSERT INTO hotel VALUES(625,'Hotel Adlon','Dortmund','Lilienthalstrasse','68a','44369'); INSERT INTO hotel VALUES(392,'Hotel Kempinski','Muenchen','Terminalstrasse', '20-22','85356'); INSERT INTO hotel VALUES(393,'Sternwirt','Weigendorf','Wellnesstraße', '12','91249'); INSERT INTO hotel VALUES(394,'Landhaus Sponsel-Regus','Heiligenstadt i. Ofr.','Landhausstr', '12','91332'); INSERT INTO gast VALUES(59375,'Engelke-Meise','Silke','Herne','44625','Jaegerstrasse','13'); INSERT INTO gast VALUES(58,'Ebbingmann','Adalbert','Fuessen','87629','Froschseenstrasse','33'); INSERT INTO gast VALUES(4711,'Matzke','Muximilian','Waldshut','79761','Kaiserstrasse','27'); INSERT INTO gast VALUES(30,'Hansen','Irmgard','Bamberg','96023','Neuer Weg','15'); INSERT INTO gast VALUES(31,'Rosenberg','Brigitte','Duisburg','41025','Rahmerstr','168'); INSERT INTO zimmer VALUES(625,5,'No5',2,'21.99'); INSERT INTO zimmer VALUES(625,412,'Rosa Raum',2,'90.35'); INSERT INTO zimmer VALUES(625,414,'Schlafwohl',4,'59.95'); INSERT INTO zimmer VALUES(392,333,'Stollen West',2,'24.99'); INSERT INTO zimmer VALUES(392,135,'Missippi',6,'52.89'); INSERT INTO zimmer VALUES(392,334,'Schoene Aussicht',2,'74.25'); INSERT INTO zimmer VALUES(393,363,'Morgenroete',5,'195.25'); INSERT INTO zimmer VALUES(393,512,'Angeraue',2,'50.12'); INSERT INTO zimmer VALUES(394,12,'Jordanquelle',2,'45.40'); INSERT INTO zimmer VALUES(394,14,'Lippequelle',2,50.50); INSERT INTO zimmer VALUES(394,26,'Stadttor',2,78.99); INSERT INTO zimmer VALUES(394,27,'Kniebruecke',4,74.99);", - }, - { - id: 8, - name: "ÜB2: Hotelbeispiel", - category: this.categories[1], - templateQuery: - "CREATE TABLE hotel ( HoNr INTEGER NOT NULL, HName VARCHAR(40), Ort VARCHAR(40), Straße VARCHAR(40), HausNr VARCHAR(5), PLZ CHAR(5), CONSTRAINT pk_hotel PRIMARY KEY(HoNr)); CREATE TABLE zimmer ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ZName VARCHAR(40), Kapazitaet INTEGER, Preis DECIMAL(8,2), CONSTRAINT pk_zimmer PRIMARY KEY(HoNr,ZNr), CONSTRAINT fk_zimmer FOREIGN KEY(HoNr) REFERENCES hotel(HoNr)); CREATE TABLE ausstattung ( ANr INTEGER NOT NULL, Bezeichnung VARCHAR(40), Zusatzkosten DECIMAL(8,2), CONSTRAINT pk_ausstattung PRIMARY KEY(ANr)); CREATE TABLE normal ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ANr INTEGER NOT NULL, anzahl INTEGER DEFAULT 1, CONSTRAINT pk_normal PRIMARY KEY(HoNr,ZNr,ANr), CONSTRAINT fk_normal_1 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT fk_normal_2 FOREIGN KEY(HoNr,ZNr) REFERENCES zimmer(HoNr,ZNr)); CREATE TABLE gast ( GNr INTEGER NOT NULL, Name VARCHAR(30), Vorname VARCHAR(40), Ort VARCHAR(50), PLZ CHAR(5), Strasse VARCHAR(50), HausNr VARCHAR(5), CONSTRAINT pk_gast PRIMARY KEY(GNr)); CREATE TABLE reservierung ( RNr INTEGER NOT NULL, Datum DATE, HoNr INTEGER, GNr INTEGER, CONSTRAINT pk_reservierung PRIMARY KEY(RNr), CONSTRAINT fk_reservierung_1 FOREIGN KEY(HoNr) REFERENCES hotel(HoNr), CONSTRAINT fk_reservierung_2 FOREIGN KEY(GNr) REFERENCES gast(GNr)); CREATE TABLE rposition ( RNr INTEGER NOT NULL, RPos INTEGER NOT NULL, von DATE, bis DATE, HoNr INTEGER, ZNr INTEGER, CONSTRAINT pk_position PRIMARY KEY(RNr,RPos), CONSTRAINT fk_position_1 FOREIGN KEY(RNr) REFERENCES reservierung(RNr), CONSTRAINT fk_position_2 FOREIGN KEY(HoNr,ZNr) REFERENCES zimmer(HoNr,ZNr), CONSTRAINT check_date CHECK (von <= bis)); CREATE TABLE zusatz ( RNr INTEGER NOT NULL, RPos INTEGER NOT NULL, ANr INTEGER NOT NULL, von DATE, bis DATE, anzahl INTEGER DEFAULT 1, CONSTRAINT pk_zusatz PRIMARY KEY(RNr,RPos,ANr), CONSTRAINT fk_zusatz_1 FOREIGN KEY(RNr,RPos) REFERENCES rposition(RNr,RPos), CONSTRAINT fk_zusatz_2 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT check_date CHECK (von <= bis)); INSERT INTO hotel VALUES(1036,'Ringhotel','Luenen','Kurt-Schumacher-Strasse','1','44534'); INSERT INTO hotel VALUES(34 ,'Haus Schmuelling','Bergkamen','Landwehrstrasse','54','59192'); INSERT INTO hotel VALUES(135,'City Hotel','Dortmund','Auf dem Wall','62','44147'); INSERT INTO hotel VALUES(843,'Maritim','Stralsund','Strandgasse','37','18435'); INSERT INTO hotel VALUES(428,'Riss','Chemnitz','An der Erzkuhle','23','09008'); INSERT INTO hotel VALUES(522,'Bohne','Kakau b. Bitterfeld','Zur Plantage','14','06785'); INSERT INTO hotel VALUES(132,'Gruene Bogenschuetze','Geseke','An der Abtei','3','59590'); INSERT INTO hotel VALUES(625,'Hotel Adlon','Dortmund','Lilienthalstrasse','68a','44369'); INSERT INTO hotel VALUES(392,'Hotel Kempinski','Muenchen','Terminalstrasse','20-22','85356'); INSERT INTO hotel VALUES(736,'Gasthof Sybille','Bad Lippspringe','An der Jordanquelle','1','33188'); INSERT INTO hotel VALUES(758,'Kastens Hotel','Duesseldorf','Lorettostr','5','40219'); INSERT INTO hotel VALUES(761,'Am Glockenturm','Arnsberg','Soesterstr','1','59821'); INSERT INTO ausstattung VALUES(23,'Telefon',5.67); INSERT INTO ausstattung VALUES(35,'Goldene Wascharmaturen',45.16); INSERT INTO ausstattung VALUES(47,'Extragroße Badetuecher',9.99); INSERT INTO ausstattung VALUES(59,'Bettwaesche',10.32); INSERT INTO ausstattung VALUES(61,'Haekelkissenbezuege',13.57); INSERT INTO ausstattung VALUES(73,'Kabelfernsehen',15.66); INSERT INTO ausstattung VALUES(84,'Satellitenfernsehen',16.55); INSERT INTO ausstattung VALUES(96,'Beamer',23.79); INSERT INTO ausstattung VALUES(108,'Overheadprojektor',17.43); INSERT INTO ausstattung VALUES(111,'Videorekorder',16.89); INSERT INTO ausstattung VALUES(123,'DVD-Player',18.52); INSERT INTO ausstattung VALUES(130,'HiFi-Multifunktionsanlage',25.91); INSERT INTO ausstattung VALUES(142,'Stuhl',4.31); INSERT INTO ausstattung VALUES(154,'Tisch',5.76); INSERT INTO ausstattung VALUES(166,'Kopfkissen',15.69); INSERT INTO ausstattung VALUES(178,'Gummibettlaken',17.83); INSERT INTO ausstattung VALUES(62,'gehaekelte Toilettenrollendeckchen',11.46); INSERT INTO ausstattung VALUES(46,'Bademantel','5.50'); INSERT INTO ausstattung VALUES(45,'Hausschuhe','2.35'); INSERT INTO ausstattung VALUES(50,'Kinderbett','0.0'); INSERT INTO ausstattung VALUES(51,'Hochstuhl','0.0'); INSERT INTO ausstattung VALUES(52,'Safe','2.45'); INSERT INTO ausstattung VALUES(53,'Heizdecke','16.85'); INSERT INTO ausstattung VALUES(54,'Duftkerzen','12.15'); INSERT INTO ausstattung VALUES(24,'W-LAN Zugang','5.95'); INSERT INTO ausstattung VALUES(25,'DSL-Anschluss','7.69'); INSERT INTO zimmer VALUES(34,3,'No3',1,19.99); INSERT INTO zimmer VALUES(135,312,'Praesidentensuite',6,399.99); INSERT INTO zimmer VALUES(135,313,'Bernsteinzimmer',6,600.00); INSERT INTO zimmer VALUES(428,222,'Stollen Sued',2,24.99); INSERT INTO zimmer VALUES(843,145,'Seeblick',3,89.67); INSERT INTO zimmer VALUES(1036,217,'Waldblick',2,45.99); INSERT INTO zimmer VALUES(428,111,'Stollen Nord',1,23.99); INSERT INTO zimmer VALUES(843,732,'Krabbenkutter',5,485.00); INSERT INTO zimmer VALUES(135,521,'Westfalenzimmer',4,167.55); INSERT INTO zimmer VALUES(34,4,'No4',2,21.99); INSERT INTO zimmer VALUES(1036,1214,'Schwanenteich',3,76.99); INSERT INTO zimmer VALUES(522,113,'Onkel Toms Huette',2,54.99); INSERT INTO zimmer VALUES(522,124,'Singendes Zuckerrohr',3,65.35); INSERT INTO zimmer VALUES(132,115,'Waldruh',2,55.34); INSERT INTO zimmer VALUES(132,134,'Hochsitz',4,89.47); INSERT INTO zimmer VALUES(625,257,'Metropolian',2,76.21); INSERT INTO zimmer VALUES(625,412,'Blickpunkt',3,87.25); INSERT INTO zimmer VALUES(392,233,'Waldfried',1,32.46); INSERT INTO zimmer VALUES(392,513,'Flugplatz',2,43.62); INSERT INTO zimmer VALUES(34,5,'No5',2,'21.99'); INSERT INTO zimmer VALUES(132,122,'Strecke',2,'60.45'); INSERT INTO zimmer VALUES(135,412,'Rosa Raum',2,'90.35'); INSERT INTO zimmer VALUES(392,414,'Schlafwohl',2,'59.95'); INSERT INTO zimmer VALUES(428,333,'Stollen West',2,'24.99'); INSERT INTO zimmer VALUES(522,135,'Missippi',2,'52.89'); INSERT INTO zimmer VALUES(625,333,'Schoene Aussicht',2,'74.25'); INSERT INTO zimmer VALUES(843,363,'Morgenroete',2,'195.25'); INSERT INTO zimmer VALUES(1036,512,'Angeraue',2,'50.12'); INSERT INTO zimmer VALUES(736,11,'Arminiusquelle',2,'45.40'); INSERT INTO zimmer VALUES(736,12,'Jordanquelle',2,'45.40'); INSERT INTO zimmer VALUES(736,14,'Lippequelle',2,50.50); INSERT INTO zimmer VALUES(758,25,'Rheinturm',2,78.99); INSERT INTO zimmer VALUES(758,26,'Stadttor',2,78.99); INSERT INTO zimmer VALUES(758,27,'Kniebruecke',2,74.99); INSERT INTO zimmer VALUES(761,31,'Schlossberg',2,25.85); INSERT INTO zimmer VALUES(761,32,'Gambrinus',2,19.99); INSERT INTO zimmer VALUES(761,33,'Muffrika',4,48.55); INSERT INTO normal VALUES(1036,217,23); INSERT INTO normal VALUES(843,145,73); INSERT INTO normal VALUES(34,3,23); INSERT INTO normal VALUES(428,222,61); INSERT INTO normal VALUES(135,312,166); INSERT INTO normal VALUES(428,111,142); INSERT INTO normal VALUES(34,4,59); INSERT INTO normal VALUES(1036,1214,84); INSERT INTO normal VALUES(135,521,178); INSERT INTO normal VALUES(843,732,130); INSERT INTO normal VALUES(522,113,62); INSERT INTO normal VALUES(522,124,59); INSERT INTO normal VALUES(132,115,73); INSERT INTO normal VALUES(132,134,84); INSERT INTO normal VALUES(625,257,23); INSERT INTO normal VALUES(625,412,166); INSERT INTO normal VALUES(392,233,35); INSERT INTO normal VALUES(392,513,130); INSERT INTO normal VALUES(522,113,59); INSERT INTO normal VALUES(34,5,59,2); INSERT INTO normal VALUES(132,122,59,2); INSERT INTO normal VALUES(135,412,59,2); INSERT INTO normal VALUES(392,414,59,2); INSERT INTO normal VALUES(428,333,59,2); INSERT INTO normal VALUES(522,135,59,2); INSERT INTO normal VALUES(625,333,59,2); INSERT INTO normal VALUES(843,363,59,2); INSERT INTO normal VALUES(1036,512,59,2); INSERT INTO normal VALUES(736,11,59,2); INSERT INTO normal VALUES(736,12,59,2); INSERT INTO normal VALUES(736,14,59,2); INSERT INTO normal VALUES(758,25,59,2); INSERT INTO normal VALUES(758,26,59,2); INSERT INTO normal VALUES(758,27,59,2); INSERT INTO normal VALUES(761,31,59,2); INSERT INTO normal VALUES(761,32,59,2); INSERT INTO normal VALUES(761,33,59,4); INSERT INTO normal VALUES(34,5,62,1); INSERT INTO normal VALUES(132,122,62,1); INSERT INTO normal VALUES(135,412,62,1); INSERT INTO normal VALUES(392,414,62,1); INSERT INTO normal VALUES(428,333,62,1); INSERT INTO normal VALUES(522,135,62,1); INSERT INTO normal VALUES(625,333,62,1); INSERT INTO normal VALUES(843,363,62,1); INSERT INTO normal VALUES(1036,512,62,1); INSERT INTO normal VALUES(736,11,53,1); INSERT INTO normal VALUES(736,12,53,1); INSERT INTO normal VALUES(736,14,53,1); INSERT INTO normal VALUES(758,25,142,1); INSERT INTO normal VALUES(758,26,142,1); INSERT INTO normal VALUES(758,27,142,1); INSERT INTO normal VALUES(761,31,178,2); INSERT INTO normal VALUES(761,32,178,2); INSERT INTO normal VALUES(761,33,178,4); INSERT INTO gast VALUES(453,'Muller','Jean-Paul','Havixbeck','48329','Willi-Richter-Platz','2b'); INSERT INTO gast VALUES(14753,'Richter','Trude','Buxtehude','21614','Zwischen den Bruecken','6'); INSERT INTO gast VALUES(795,'Stein','Flut','Herten','46599','Stan-Libuda-Strasse','1'); INSERT INTO gast VALUES(8531,'Mustermann','Martin','Musterstadt','10000','Poststrasse','13-15'); INSERT INTO gast VALUES(7184,'Postmann','Elfriede','Chemnitz','09008','Erich-Honecker-Platz','23'); INSERT INTO gast VALUES(3417,'Randzio','Katharina','Aue','08280','Goethestrasse','101a'); INSERT INTO gast VALUES(59375,'Engelke-Meise','Silke','Herne','44625','Jaegerstrasse','13'); INSERT INTO gast VALUES(58,'Ebbingmann','Adalbert','Fuessen','87629','Froschseenstrasse','33'); INSERT INTO gast VALUES(4711,'Matzke','Muximilian','Waldshut','79761','Kaiserstrasse','27'); INSERT INTO gast VALUES(8624,'Rupprecht','Knecht','Himmelstadt','97267','Kirchplatz','5'); INSERT INTO gast VALUES(2738,'Schmitz','Klaus','Dortmund','44147','Linienstrasse','7b'); INSERT INTO gast VALUES(2631,'Biene','Maja','Blumenberg','50765','Auf der Blume','24'); INSERT INTO gast VALUES(25,'Binz','Gunnar','Duesseldorf','40549','Heerdter Sandberg','3'); INSERT INTO gast VALUES(26,'Haller','Karl-Heinz','Dortmund','44143','Breierspfad','134'); INSERT INTO gast VALUES(27,'Kloepping','Harald','Bamberg','96058','Eckeystr','15'); INSERT INTO gast VALUES(28,'Schlanstein','Christina','Dillenburg','35683','Carl-Schurz-Str','9'); INSERT INTO gast VALUES(29,'Gauss','Kerstin','Neuss','41453','Badstr','3'); INSERT INTO gast VALUES(30,'Hansen','Irmgard','Bamberg','96023','Neuer Weg','15'); INSERT INTO gast VALUES(31,'Rosenberg','Brigitte','Duisburg','41025','Rahmerstr','168'); INSERT INTO gast VALUES(32,'Lampe','Rosa','Vechta','49377','Schwichtelerstr','14'); INSERT INTO gast VALUES(33,'Mondo','Dolores','Hagen','58093','Dortmunder Str','15a'); INSERT INTO reservierung VALUES(86542,'2022-09-09',34,453); INSERT INTO reservierung VALUES(145863,'2022-01-02',135,14753); INSERT INTO reservierung VALUES(46357,'2023-04-01',843,795); INSERT INTO reservierung VALUES(43358,'2023-03-23',428,8531); INSERT INTO reservierung VALUES(135,'2015-09-19',1036,7184); INSERT INTO reservierung VALUES(6834,'2024-08-13',34,3417); INSERT INTO reservierung VALUES(115,'2023-05-27',428,59375); INSERT INTO reservierung VALUES(8673,'2023-05-03',135,58); INSERT INTO reservierung VALUES(24,'2019-08-31',843,4711); INSERT INTO reservierung VALUES(9999,'2023-12-12',1036,8624); INSERT INTO reservierung VALUES(735,'2023-03-13',132,4711); INSERT INTO reservierung VALUES(567,'2022-02-24',625,2738); INSERT INTO reservierung VALUES(568,'2023-02-24',135,2738); INSERT INTO reservierung VALUES(818,'2024-03-01',392,8624); INSERT INTO reservierung VALUES(361,'2018-12-21',34,59375); INSERT INTO reservierung VALUES(5294,'2021-10-10',392,3417); INSERT INTO reservierung VALUES(2732,'2016-04-13',132,7184); INSERT INTO reservierung VALUES(2432,'2021-07-16',522,453); INSERT INTO reservierung VALUES(1953,'2021-08-23',135,14753); INSERT INTO reservierung VALUES(356,'2024-01-01',1036,2631); INSERT INTO reservierung VALUES(5646,'2025-02-05',522,795); INSERT INTO reservierung VALUES(6748,'2025-03-22',522,795); INSERT INTO reservierung VALUES(2748,'2024-02-10',132,4711); INSERT INTO reservierung VALUES(2349,'2024-02-10',132,58); INSERT INTO reservierung VALUES(4241,'2025-02-10',132,58); INSERT INTO reservierung VALUES(6878,'2026-02-10',132,58); INSERT INTO reservierung VALUES(221,'2022-05-15',736,25); INSERT INTO reservierung VALUES(222,'2022-01-11',758,26); INSERT INTO reservierung VALUES(223,'2021-11-05',761,27); INSERT INTO reservierung VALUES(224,'2021-10-03',761,28); INSERT INTO reservierung VALUES(225,'2020-07-18',135,27); INSERT INTO reservierung VALUES(226,'2020-11-06',522,29); INSERT INTO reservierung VALUES(227,'2020-12-13',428,30); INSERT INTO reservierung VALUES(228,'2021-02-15',843,31); INSERT INTO reservierung VALUES(229,'2021-03-25',135,32); INSERT INTO reservierung VALUES(230,'2021-04-13',758,33); INSERT INTO reservierung VALUES(231,'2021-06-07',758,33); INSERT INTO reservierung VALUES(232,'2021-08-13',522,25); INSERT INTO reservierung VALUES(233,'2022-04-13',736,29); INSERT INTO reservierung VALUES(234,'2022-02-26',522,27); INSERT INTO reservierung VALUES(235,'2022-08-13',761,26); INSERT INTO reservierung VALUES(236,'2022-09-30',761,25); INSERT INTO reservierung VALUES(237,'2022-03-11',843,33); INSERT INTO reservierung VALUES(238,'2022-04-13',843,58); INSERT INTO reservierung VALUES(239,'2021-11-11',758,58); INSERT INTO reservierung VALUES(240,'2022-02-03',135,453); INSERT INTO reservierung VALUES(241,'2020-12-28',522,795); INSERT INTO rposition VALUES(86542,1,'2022-10-10','2023-10-10',34,3); INSERT INTO rposition VALUES(145863,1,'2023-04-11','2023-04-22',135,312); INSERT INTO rposition VALUES(145863,2,'2023-04-11','2023-04-22',135,313); INSERT INTO rposition VALUES(43358,1,'2023-05-05','2023-05-06',428,222); INSERT INTO rposition VALUES(46357,1,'2024-04-26','2024-05-07',843,145); INSERT INTO rposition VALUES(135,1,'2017-09-18','2017-09-22',1036,217); INSERT INTO rposition VALUES(115,1,'2024-05-28','2024-05-31',428,111); INSERT INTO rposition VALUES(24,1,'2021-04-08','2021-04-25',843,732); INSERT INTO rposition VALUES(24,2,'2021-04-08','2021-04-25',843,145); INSERT INTO rposition VALUES(24,3,'2021-07-31','2021-09-01',34,3); INSERT INTO rposition VALUES(24,4,'2021-07-31','2021-09-01',34,4); INSERT INTO rposition VALUES(8673,1,'2023-07-01','2023-07-15',135,521); INSERT INTO rposition VALUES(6834,1,'2024-08-15','2024-08-27',34,4); INSERT INTO rposition VALUES(9999,1,'2024-04-30','2024-06-30',1036,1214); INSERT INTO rposition VALUES(9999,2,'2024-07-01','2024-07-31',135,312); INSERT INTO rposition VALUES(9999,3,'2024-08-31','2024-10-01',843,145); INSERT INTO rposition VALUES(9999,4,'2024-07-01','2024-07-31',135,313); INSERT INTO rposition VALUES(735,1,'2023-03-20','2024-04-20',392,233); INSERT INTO rposition VALUES(567,1,'2023-04-23','2023-05-07',522,113); INSERT INTO rposition VALUES(568,1,'2023-02-23','2023-03-07',135,412); INSERT INTO rposition VALUES(818,1,'2024-03-24','2024-03-31',132,134); INSERT INTO rposition VALUES(361,1,'2019-12-23','2020-01-06',625,257); INSERT INTO rposition VALUES(5294,1,'2022-04-02','2022-04-16',428,111); INSERT INTO rposition VALUES(2732,1,'2016-08-17','2016-09-04',522,124); INSERT INTO rposition VALUES(2432,1,'2022-06-15','2022-07-16',132,115); INSERT INTO rposition VALUES(1953,1,'2024-08-07','2024-08-15',392,513); INSERT INTO rposition VALUES(818,2,'2024-04-01','2024-04-12',843,732); INSERT INTO rposition VALUES(356,1,'2024-01-02','2024-04-22',522,113); INSERT INTO rposition VALUES(5646,1,'2025-03-06','2025-03-22',843,145); INSERT INTO rposition VALUES(6748,1,'2026-01-01','2026-01-08',843,145); INSERT INTO rposition VALUES(2748,1,'2024-04-01','2024-04-08',392,233); INSERT INTO rposition VALUES(2349,1,'2024-07-16','2024-07-18',392,233); INSERT INTO rposition VALUES(4241,1,'2025-07-16','2025-07-18',392,233); INSERT INTO rposition VALUES(6878,1,'2026-07-16','2026-07-18',392,233); INSERT INTO rposition VALUES(221,1,'2022-05-25','2022-06-05',736,11); INSERT INTO rposition VALUES(222,1,'2022-04-15','2022-04-18',736,12); INSERT INTO rposition VALUES(223,1,'2022-01-11','2022-01-18',736,14); INSERT INTO rposition VALUES(223,2,'2022-02-11','2022-02-18',736,11); INSERT INTO rposition VALUES(223,3,'2022-03-11','2022-03-18',736,14); INSERT INTO rposition VALUES(224,1,'2021-11-11','2021-11-15',758,25); INSERT INTO rposition VALUES(225,1,'2020-07-31','2020-08-15',758,26); INSERT INTO rposition VALUES(226,1,'2020-11-11','2020-11-13',758,27); INSERT INTO rposition VALUES(227,1,'2021-01-12','2021-01-15',761,31); INSERT INTO rposition VALUES(228,1,'2021-03-02','2021-03-08',761,32); INSERT INTO rposition VALUES(228,2,'2021-04-02','2021-04-08',761,32); INSERT INTO rposition VALUES(228,3,'2021-05-02','2021-05-08',761,32); INSERT INTO rposition VALUES(229,1,'2021-03-28','2021-04-07',761,33); INSERT INTO rposition VALUES(230,1,'2021-05-02','2021-05-13',132,122); INSERT INTO rposition VALUES(231,1,'2021-07-01','2021-07-05',34,3); INSERT INTO rposition VALUES(231,2,'2021-07-01','2021-07-05',34,4); INSERT INTO rposition VALUES(231,3,'2021-07-01','2021-07-05',34,5); INSERT INTO rposition VALUES(232,1,'2021-09-19','2021-09-21',135,412); INSERT INTO rposition VALUES(233,1,'2022-05-01','2022-05-05',392,414); INSERT INTO rposition VALUES(234,1,'2022-03-01','2022-03-05',428,333); INSERT INTO rposition VALUES(235,1,'2021-09-01','2021-09-05',522,135); INSERT INTO rposition VALUES(236,1,'2021-12-01','2021-12-10',625,333); INSERT INTO rposition VALUES(237,1,'2022-03-18','2022-03-25',843,363); INSERT INTO rposition VALUES(238,1,'2021-07-01','2021-07-05',1036,512); INSERT INTO rposition VALUES(239,1,'2021-11-11','2021-11-15',758,26); INSERT INTO rposition VALUES(240,1,'2022-02-11','2022-02-15',135,412); INSERT INTO rposition VALUES(241,1,'2021-01-02','2021-01-09',522,135); INSERT INTO zusatz VALUES(735,1,84,'2023-03-21','2024-03-30'); INSERT INTO zusatz VALUES(567,1,61,'2023-04-23','2023-05-07'); INSERT INTO zusatz VALUES(818,1,111,'2024-03-24','2024-03-28'); INSERT INTO zusatz VALUES(361,1,142,'2019-12-26','2020-01-06'); INSERT INTO zusatz VALUES(43358,1,154,'2023-05-05','2023-05-06'); INSERT INTO zusatz VALUES(2732,1,47,'2016-08-17','2016-08-18'); INSERT INTO zusatz VALUES(2432,1,123,'2022-06-30','2022-07-01'); INSERT INTO zusatz VALUES(1953,1,178,'2024-08-07','2024-08-15'); INSERT INTO zusatz VALUES(818,2,96,'2024-04-04','2024-04-11'); INSERT INTO zusatz VALUES(818,2,108,'2024-04-03','2024-04-10'); INSERT INTO zusatz VALUES(818,2,111,'2024-04-03','2024-04-11'); INSERT INTO zusatz VALUES(735,1,130,'2023-03-22','2024-03-29'); INSERT INTO zusatz VALUES(145863,1,35,'2023-04-14','2023-04-19'); INSERT INTO zusatz VALUES(46357,1,61,'2024-04-26','2024-05-07'); INSERT INTO zusatz VALUES(46357,1,84,'2024-04-30','2024-05-03'); INSERT INTO zusatz VALUES(46357,1,111,'2024-05-01','2024-05-03'); INSERT INTO zusatz VALUES(46357,1,130,'2024-04-30','2024-05-02'); INSERT INTO zusatz VALUES(135,1,96,'2017-09-19','2017-09-20'); INSERT INTO zusatz VALUES(135,1,108,'2017-09-19','2017-09-19'); INSERT INTO zusatz VALUES(135,1,111,'2017-09-20','2017-09-20'); INSERT INTO zusatz VALUES(24,1,142,'2021-04-16','2021-04-19'); INSERT INTO zusatz VALUES(24,3,178,'2021-08-01','2021-08-27'); INSERT INTO zusatz VALUES(24,4,47,'2021-08-01','2021-08-27'); INSERT INTO zusatz VALUES(8673,1,47,'2023-07-03','2023-07-05'); INSERT INTO zusatz VALUES(9999,1,84,'2024-05-05','2024-05-05'); INSERT INTO zusatz VALUES(9999,1,130,'2024-06-06','2024-06-07'); INSERT INTO zusatz VALUES(9999,2,130,'2024-07-01','2024-07-31'); INSERT INTO zusatz VALUES(9999,3,130,'2024-09-01','2024-09-30'); INSERT INTO zusatz VALUES(9999,3,61,'2024-09-01','2024-09-30'); INSERT INTO zusatz Values(356,1,35,'2024-01-02','2024-04-22'); INSERT INTO zusatz Values(356,1,47,'2024-01-02','2024-04-22'); INSERT INTO zusatz VALUES(221,1,50,'2022-05-25','2022-06-05',2); INSERT INTO zusatz VALUES(221,1,51,'2022-05-25','2022-06-05',2); INSERT INTO zusatz VALUES(222,1,53,'2022-04-15','2022-04-18',2); INSERT INTO zusatz VALUES(224,1,53,'2021-11-11','2021-11-15',1); INSERT INTO zusatz VALUES(225,1,52,'2020-07-31','2020-08-15',1); INSERT INTO zusatz VALUES(226,1,52,'2020-11-11','2020-11-13',1); INSERT INTO zusatz VALUES(227,1,52,'2021-01-12','2021-01-15',2); INSERT INTO zusatz VALUES(229,1,45,'2021-03-29','2021-04-07',2); INSERT INTO zusatz VALUES(230,1,45,'2021-05-03','2021-05-13',1); INSERT INTO zusatz VALUES(230,1,46,'2021-05-03','2021-05-13',1); INSERT INTO zusatz VALUES(232,1,54,'2021-09-19','2021-09-21',1); INSERT INTO zusatz VALUES(233,1,24,'2022-05-01','2022-05-05',1); INSERT INTO zusatz VALUES(234,1,25,'2022-03-03','2022-03-05',1); INSERT INTO zusatz VALUES(235,1,142,'2021-09-03','2021-09-04',4); INSERT INTO zusatz VALUES(235,1,154,'2021-09-03','2021-09-04',1); INSERT INTO zusatz VALUES(239,1,84,'2021-11-11','2021-11-15',1); INSERT INTO zusatz VALUES(240,1,111,'2022-02-11','2022-02-15',1);", - }, - { - id: 9, - name: "Use-Case Firma", - category: this.categories[0], - templateQuery: - "CREATE TABLE Abteilung (Abteilungsnr INT PRIMARY KEY,Abteilungsname VARCHAR(255)); CREATE TABLE Person (PersonalNr INT PRIMARY KEY,Name VARCHAR(255),Gehalt DECIMAL(10, 2),Ort VARCHAR(255),Abteilung INT,FOREIGN KEY (Abteilung) REFERENCES abteilung (abteilungsnr)); INSERT INTO Abteilung (Abteilungsnr, Abteilungsname) VALUES (1, 'EDV'),(2, 'Produktion'),(3, 'Vertrieb'),(4, 'Verwaltung'),(5, 'Entwicklung'); INSERT INTO Person (PersonalNr, Name, Gehalt, Ort, Abteilung) VALUES (100, 'Maier', 3800.00, 'Künzelsau', 1),(101, 'Müller', 4100.00, 'Künzelsau', 2),(102, 'Schmidt', 3500.00, 'Öhringen', 1),(103, 'Schulze', 4600.00, 'Heilbronn', 3),(104, 'Hinz', 4200.00, 'Heilbronn', 3),(105, 'Kunz', 4000.00, 'Schwäbisch Hall', 5);", - }, - { - id: 10, - name: "Use-Case Fussballverband", - category: this.categories[0], - templateQuery: - "CREATE TABLE Verein (V_Nr INT PRIMARY KEY,Name VARCHAR(255),Ort VARCHAR(255)); CREATE TABLE Spieler (Pass_Nr INT PRIMARY KEY,Name VARCHAR(255),Geburtsjahr INT); CREATE TABLE Meldung (Spieler INT,Saison VARCHAR(5),Verein INT,Einsaetze INT,Tore INT,FOREIGN KEY (Spieler) REFERENCES Spieler(Pass_Nr),FOREIGN KEY (Verein) REFERENCES Verein(V_Nr)); INSERT INTO Verein (V_Nr,Name,Ort) VALUES (1,'Schlappen-Kicker 05','Heilbronn'),(2,'Knochen-Knacker 09','Künzelsau'),(3,'Ballermann 1955','Heilbronn'),(4,'Alte Herren 1880','Schwäbisch Hall'); INSERT INTO Spieler (Pass_Nr,Name,Geburtsjahr) VALUES (1,'Peter Maier',1960),(2,'Klaus Müller',1980),(3,'Karl Hinz',1987),(4,'Thomas Kunze',1975); INSERT INTO Meldung (Spieler,Saison,Verein,Einsaetze,Tore) VALUES (1,'00/01',1,6,3),(2,'00/01',3,12,1),(3,'00/01',2,1,0),(1,'99/00',2,6,4),(4,'00/01',1,2,1);", - }, - { - id: 11, - name: "Rezepte", - category: this.categories[0], - templateQuery: - "CREATE TABLE benutzer (id_benutzer INT,benutzername VARCHAR(40),email VARCHAR(60),PRIMARY KEY (id_benutzer));CREATE TABLE zutat (id_zutat INT,bezeichnung VARCHAR(40),PRIMARY KEY (id_zutat));CREATE TABLE rezept (id_rezept INT,id_benutzer INT,titel VARCHAR(40),portionen INT,dauer TIME,PRIMARY KEY (id_rezept),FOREIGN KEY (id_benutzer) REFERENCES benutzer(id_benutzer));CREATE TABLE rezept_schritt (id_rezept INT,nr_schritt INT,titel VARCHAR(40),anweisung VARCHAR(200),PRIMARY KEY (id_rezept, nr_schritt),FOREIGN KEY (id_rezept) REFERENCES rezept(id_rezept));CREATE TYPE einheit AS ENUM ('ml', 'l', 'tl', 'el', 'cups', 'gr', 'kg', 'Stück');CREATE TABLE schritt_zutat (id_rezept INT,nr_schritt INT,zutat INT,menge INT,einheit einheit,PRIMARY KEY (id_rezept, nr_schritt, zutat),FOREIGN KEY (id_rezept, nr_schritt) REFERENCES rezept_schritt(id_rezept, nr_schritt),FOREIGN KEY (zutat) REFERENCES zutat(id_zutat));CREATE TABLE bewertung (id_rezept INT,id_benutzer INT,anz_sterne INT,datum DATE,PRIMARY KEY (id_rezept, id_benutzer),FOREIGN KEY (id_rezept) REFERENCES rezept(id_rezept),FOREIGN KEY (id_benutzer) REFERENCES benutzer(id_benutzer));INSERT INTO benutzer (id_benutzer, benutzername, email) VALUES (1, 'KlausMeier', 'klaus.meier@example.de'),(2, 'AnnaSchmidt', 'anna.schmidt@example.de'),(3, 'JohannesBauer', 'johannes.bauer@example.de');INSERT INTO zutat (id_zutat, bezeichnung) VALUES (1, 'Mehl'),(2, 'Zucker'),(3, 'Eier'),(4, 'Milch'),(5, 'Backpulver'),(6, 'Butter');INSERT INTO rezept (id_rezept, id_benutzer, titel, portionen, dauer) VALUES (1, 1, 'Apfelkuchen', 8, '01:30:00'),(2, 2, 'Linseneintopf', 4, '00:45:00');INSERT INTO rezept_schritt (id_rezept, nr_schritt, titel, anweisung) VALUES (1, 1, 'Vorbereitung', 'Mischen Sie Mehl und Backpulver.'),(1, 2, 'Teig kneten', 'Fügen Sie Butter und Zucker hinzu und kneten Sie den Teig.'),(1, 3, 'Backen', 'Teig in einer Form verteilen und im Ofen backen.'),(2, 1, 'Zwiebeln schneiden', 'Zwiebeln und Knoblauch fein würfeln.'),(2, 2, 'Kochen', 'Alle Zutaten in einem Topf mit Wasser aufkochen.');INSERT INTO schritt_zutat (id_rezept, nr_schritt, zutat, menge, einheit) VALUES (1, 1, 1, 200, 'gr'),(1, 1, 5, 10, 'gr'),(1, 2, 2, 150, 'gr'),(1, 2, 6, 100, 'gr'),(2, 1, 3, 2, 'Stück'),(2, 2, 4, 500, 'ml');INSERT INTO bewertung (id_rezept, id_benutzer, anz_sterne, datum) VALUES (1, 2, 4, '2023-03-21'),(2, 3, 5, '2023-03-22'),(1, 3, 3, '2023-03-23');", - }, - { - id: 12, - name: "Online-Marktplatzsystem", - category: this.categories[1], - templateQuery: - "CREATE TABLE Kunde (KNr SERIAL PRIMARY KEY,Vorname VARCHAR(50) NOT NULL,Nachname VARCHAR(50) NOT NULL,PLZ VARCHAR(10) NOT NULL,Registriert_am DATE NOT NULL ); CREATE TABLE Kategorie (KatNr SERIAL PRIMARY KEY,Bezeichnung VARCHAR(50) NOT NULL ); CREATE TABLE Auktion (ANr SERIAL PRIMARY KEY,Titel VARCHAR(100) NOT NULL,Beschreibung TEXT NOT NULL,Startpreis DECIMAL(10, 2) NOT NULL,Eingestellt_am DATE NOT NULL,KNr INT NOT NULL,Kategorie INT NOT NULL,FOREIGN KEY (KNr) REFERENCES Kunde(KNr),FOREIGN KEY (Kategorie) REFERENCES Kategorie(KatNr) ); CREATE TABLE Gebot (Auktion INT NOT NULL,Bieter INT NOT NULL,Geboten_am TIMESTAMP NOT NULL,Gebotspreis DECIMAL(10, 2) NOT NULL,PRIMARY KEY (Auktion, Bieter, Geboten_am),FOREIGN KEY (Auktion) REFERENCES Auktion(ANr),FOREIGN KEY (Bieter) REFERENCES Kunde(KNr) ); INSERT INTO Kunde (KNr, Vorname, Nachname, PLZ, Registriert_am) VALUES (1, 'Max', 'Mustermann', '12345', '2020-01-15'), (2, 'Anna', 'Müller', '54321', '2021-06-10'), (3, 'Peter', 'Schmidt', '98765', '2020-12-04'), (4, 'Julia', 'Meier', '67890', '2020-08-21'), (5, 'Lena', 'Fischer', '12346', '2020-02-20'), (6, 'Jonas', 'Weber', '54322', '2019-06-16'), (7, 'Emma', 'Schneider', '98764', '2019-06-17'), (8, 'Paul', 'Koch', '67891', '2020-12-02'), (9, 'Marie', 'Bauer', '12347', '2020-03-05'), (10, 'Leon', 'Hoffmann', '54323', '2021-08-25'), (11, 'Sophie', 'Schulz', '98763', '2021-05-15'), (12, 'Finn', 'Zimmermann', '67892', '2022-08-01'), (13, 'Mia', 'Lehmann', '12348', '2020-04-10'), (14, 'Noah', 'Schmid', '54324', '2019-06-28'), (15, 'Leonie', 'Hartmann', '98762', '2022-06-25'), (16, 'Elias', 'König', '67893', '2020-10-05'), (17, 'Clara', 'Winkler', '12349', '2020-05-15'), (18, 'Ben', 'Maier', '54325', '2019-10-20'), (19, 'Hanna', 'Schmitt', '98761', '2019-07-20'), (20, 'Luca', 'Walter', '67894', '2021-11-01'), (21, 'Laura', 'Lang', '12350', '2020-06-10'), (22, 'Felix', 'Klein', '54326', '2021-11-15'), (23, 'Nina', 'Peters', '98760', '2022-08-05'), (24, 'Lara', 'Hermann', '67895', '2021-12-10'), (25, 'Tim', 'Becker', '12351', '2020-07-25'), (26, 'Amelie', 'Graf', '54327', '2019-12-20'), (27, 'Oskar', 'Krüger', '98759', '2022-09-10'), (28, 'Lilly', 'Lorenz', '67896', '2022-11-20'), (29, 'Matteo', 'Fuchs', '12352', '2020-08-30'), (30, 'Johanna', 'Weiß', '54328', '2021-11-01'); INSERT INTO Kategorie (Bezeichnung) VALUES ('Elektronik'), ('Möbel'), ('Kleidung'), ('Bücher'), ('Spielzeug'), ('Haushaltsgeräte'), ('Sport & Freizeit'), ('Autos & Motorräder'), ('Immobilien'), ('Sammelobjekte'), ('Schmuck & Uhren'), ('Kosmetik'), ('Garten'), ('Tierbedarf'), ('Musikinstrumente'); INSERT INTO Auktion (ANr, Titel, Beschreibung, Startpreis, Eingestellt_am, KNr, Kategorie) VALUES (1, 'Apple iPhone 12', 'Apple iPhone 12 in gutem Zustand.', 400.00, '2022-05-15 08:20:00', 1, 1), (2, 'Wohnzimmertisch', 'Moderner Tisch aus Holz.', 80.00, '2021-08-20 12:20:00', 2, 2), (3, 'Winterjacke', 'Wasserdichte Jacke, Größe L.', 60.00, '2023-01-10 05:20:00', 3, 3), (4, 'Lego Set', 'Komplettes Set mit Figuren.', 50.00, '2022-11-05 16:20:00', 5, 5), (5, 'Mikrowelle', 'Funktioniert einwandfrei.', 30.00, '2020-06-15 12:20:00', 6, 6), (6, 'Mountainbike', 'Gut erhaltenes Fahrrad.', 200.00, '2023-04-01 01:20:00', 7, 7), (7, 'BMW 3er', 'Gebrauchtwagen, Baujahr 2015.', 5000.00, '2021-12-01 23:20:00', 8, 8), (8, 'Eigentumswohnung', 'Wohnung mit 3 Zimmern.', 200000.00, '2023-07-20 22:20:00', 9, 9), (9, 'Briefmarkensammlung', 'Raritäten aus den 80ern.', 300.00, '2020-10-10 19:20:00', 10, 10), (10, 'Goldkette', '18 Karat, neuwertig.', 150.00, '2022-03-15 18:20:00', 11, 11), (11, 'Parfüm', 'Originalflasche, 50ml.', 40.00, '2021-09-30 21:20:00', 12, 12), (12, 'Gartenmöbel', 'Set aus Tisch und 4 Stühlen.', 120.00, '2023-02-15 08:20:00', 13, 13), (13, 'Hundekörbchen', 'Großes Körbchen, neuwertig.', 25.00, '2022-08-10 09:20:00', 14, 14), (14, 'Akustikgitarre', 'Yamaha-Modell, kaum genutzt.', 180.00, '2023-05-05 08:20:00', 15, 15), (15, 'Laptop', 'HP Laptop, guter Zustand.', 350.00, '2023-10-15 12:50:00', 16, 1), (16, 'Gaming-Stuhl', 'Ergonomischer Gaming-Stuhl.', 120.00, '2023-03-10 15:50:00', 17, 2), (17, 'Designer-Schuhe', 'Schuhe von Marke X, Größe 42.', 70.00, '2021-11-05 20:50:00', 18, 3), (18, 'iPhone 10', 'Apple iPhone 10 in schlechtem Zustand.', 300.00, '2022-05-15 11:30:00', 1, 1), (19, 'iPHONE X', 'iPhone X in gutem Zustand.', 300.00, '2023-11-15 02:20:00', 2, 1), (20, 'iphone Cover', 'Schutzhülle für iPhone 12.', 20.00, '2023-11-16 03:20:28', 3, 1), (21, 'iPhones verkaufen', 'Sammlung von iPhones.', 1000.00, '2023-11-17 04:34:00', 4, 1), (22, 'iPHONE X', 'iPhone X in gutem Zustand.', 300.00, '2023-11-15 05:45:00', 2, 1), (23, 'iphone Cover', 'Schutzhülle für iPhone 12.', 20.00, '2023-11-16 06:34:00', 3, 1), (24, 'iPhones verkaufen', 'Sammlung von iPhones.', 1000.00, '2023-11-17 07:14:00', 4, 1), (25, '[iPhone 13]', 'Neues iPhone 13 in OVP.', 800.00, '2023-11-18 14:21:00', 5, 1), (26, ' iPhone 14 ', 'Brandneues iPhone 14.', 1200.00, '2023-11-19 15:01:00', 6, 1); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (1, 24, '2022-05-15 10:00:00', 410.00), (1, 2, '2022-05-16 12:00:00', 420.00), (1, 8, '2022-05-17 14:00:00', 430.00), (1, 6, '2022-05-18 16:00:00', 440.00), (1, 9, '2022-05-19 18:00:00', 450.00), (1, 29, '2022-05-20 20:00:00', 460.00), (1, 1, '2022-06-25 22:54:00', 522.03); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (2, 1, '2021-08-22 12:00:00', 90.00), (2, 5, '2021-08-23 14:00:00', 95.00), (2, 16, '2021-08-24 16:00:00', 100.00), (2, 4, '2021-08-21 10:00:00', 85.00), (2, 2, '2021-06-25 18:00:00', 120.00); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (3, 2, '2023-01-11 08:00:00', 65.00), (3, 2, '2023-01-11 08:44:00', 60.00); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (4, 1, '2022-11-06 09:20:00', 55.00), (4, 6, '2022-11-07 10:30:00', 60.00), (4, 5, '2022-11-08 11:40:00', 59.00); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (5, 6, '2020-06-16 14:00:00', 35.00), (5, 7, '2020-06-17 15:30:00', 40.00), (5, 13, '2022-11-18 20:16:00', 79.82), (5, 27, '2022-11-13 23:18:00', 127.42); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (6, 5, '2023-04-02 09:00:00', 210.00), (6, 9, '2023-04-03 11:30:00', 220.00),(6, 14, '2020-06-28 01:48:00', 55.08); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (7, 8, '2021-12-02 09:00:00', 5100.00), (7, 9, '2021-12-03 11:30:00', 5200.00), (7, 3, '2021-12-04 13:00:00', 5300.00), (7, 4, '2021-12-05 15:00:00', 5400.00), (7, 5, '2021-12-06 17:30:00', 5500.00), (7, 6, '2021-12-07 20:00:00', 5600.00), (7, 30, '2021-12-15 14:00:00', 5500.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (8, 14, '2023-07-21 10:00:00', 201000.00), (8, 15, '2023-07-22 12:30:00', 202000.00), (8, 9, '2023-07-23 15:00:00', 203000.00), (8, 12, '2023-08-01 11:30:00', 201000.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (9, 18, '2020-10-11 14:00:00', 350.00), (9, 19, '2020-10-12 16:30:00', 400.00), (9, 12, '2023-08-01 11:30:00', 201000.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (10, 10, '2022-03-16 14:00:00', 160.00), (10, 11, '2022-03-17 15:30:00', 170.00), (10, 17, '2022-03-18 17:00:00', 180.00), (10, 29, '2020-10-20 10:45:00', 500.00); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (11, 25, '2021-10-01 11:10:00', 45.00), (11, 26, '2021-10-02 12:30:00', 50.00), (11, 8, '2022-03-27 13:00:00', 230.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (12, 27, '2023-02-16 14:10:00', 125.00), (12, 28, '2023-02-17 15:20:00', 130.00), (12, 7, '2021-10-15 12:45:00', 55.0), (12, 7, '2023-10-15 12:45:00', 999999.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (13, 20, '2022-08-11 15:30:00', 30.00), (13, 21, '2022-08-12 18:45:00', 35.00), (13, 12, '2023-08-01 11:30:00', 201000.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (14, 22, '2023-05-06 10:10:00', 185.00), (14, 23, '2023-05-07 13:00:00', 190.00), (14, 24, '2023-05-08 15:30:00', 195.00), (14, 12, '2023-08-01 11:30:00', 201000.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (15, 12, '2023-10-16 13:00:00', 360.00), (15, 13, '2023-10-17 15:45:00', 370.00), (15, 12, '2023-08-01 11:30:00', 201000.0);", - }, - ]; - - templatesByCategory: any[] = this.getTemplatesByCategory(); + ngOnInit(): void { + const categories: TemplateCategory[] = [ + { + id: 1, + name: "Allgemein", + }, + { + id: 2, + name: "Übungsaufgaben", + }, + ]; + this.store.dispatch(addCategories({ categories })); + this.store.dispatch( + addTemplates({ + templates: [ + { + id: 1, + name: "Hotel, Schema (DML)", + category: categories[0], + templateQuery: + "CREATE TABLE hotel ( HoNr INTEGER NOT NULL, HName VARCHAR(40), Ort VARCHAR(40), Straße VARCHAR(40), HausNr VARCHAR(5), PLZ CHAR(5), CONSTRAINT pk_hotel PRIMARY KEY(HoNr)); CREATE TABLE zimmer ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ZName VARCHAR(40), Kapazitaet INTEGER, Preis DECIMAL(8,2), CONSTRAINT pk_zimmer PRIMARY KEY(HoNr, ZNr), CONSTRAINT fk_zimmer FOREIGN KEY(HoNr) REFERENCES hotel(HoNr)); CREATE TABLE ausstattung ( ANr INTEGER NOT NULL, Bezeichnung VARCHAR(40), Zusatzkosten DECIMAL(8,2), CONSTRAINT pk_ausstattung PRIMARY KEY(ANr)); CREATE TABLE normal ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ANr INTEGER NOT NULL, CONSTRAINT pk_normal PRIMARY KEY(HoNr, ZNr, ANr), CONSTRAINT fk_normal_1 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT fk_normal_2 FOREIGN KEY(HoNr, ZNr) REFERENCES zimmer(HoNr, ZNr)); CREATE TABLE gast ( GNr INTEGER NOT NULL, Name VARCHAR(30), Vorname VARCHAR(40), Ort VARCHAR(50), PLZ CHAR(5), Strasse VARCHAR(50), HausNr VARCHAR(5), CONSTRAINT pk_gast PRIMARY KEY(GNr)); CREATE TABLE reservierung ( RNr INTEGER NOT NULL, Datum DATE, HoNr INTEGER, GNr INTEGER, CONSTRAINT pk_reservierung PRIMARY KEY(RNr), CONSTRAINT fk_reservierung_1 FOREIGN KEY(HoNr) REFERENCES hotel(HoNr), CONSTRAINT fk_reservierung_2 FOREIGN KEY(GNr) REFERENCES gast(GNr)); CREATE TABLE rposition ( RNr INTEGER NOT NULL, RPos INTEGER NOT NULL, von DATE, bis DATE, HoNr INTEGER, ZNr INTEGER, CONSTRAINT pk_position PRIMARY KEY(RNr, RPos), CONSTRAINT fk_position_1 FOREIGN KEY(RNr) REFERENCES reservierung(RNr), CONSTRAINT fk_position_2 FOREIGN KEY(HoNr, ZNr) REFERENCES zimmer(HoNr, ZNr), CONSTRAINT check_date CHECK (von <= bis)); CREATE TABLE zusatz ( RNr INTEGER NOT NULL, RPos INTEGER NOT NULL, ANr INTEGER NOT NULL, von DATE, bis DATE, CONSTRAINT pk_zusatz PRIMARY KEY(RNr, RPos, ANr), CONSTRAINT fk_zusatz_1 FOREIGN KEY(RNr, RPos) REFERENCES rposition(RNr, RPos), CONSTRAINT fk_zusatz_2 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT check_date CHECK (von <= bis));", + }, + { + id: 2, + name: "Hotel, Daten (DDL)", + category: categories[0], + templateQuery: + "INSERT INTO hotel VALUES(1036, 'Ringhotel', 'Luenen', 'Kurt-Schumacher-Strasse', '1', '44534'); INSERT INTO hotel VALUES(34 ,'Haus Schmuelling','Bergkamen','Landwehrstrasse', '54', '59192'); INSERT INTO hotel VALUES(135, 'City Hotel', 'Dortmund', 'Auf dem Wall','62', '44147'); INSERT INTO hotel VALUES(843,'Maritim','Stralsund','Strandgasse','37','18435'); INSERT INTO hotel VALUES(428,'Riss','Chemnitz','An der Erzkuhle','23', '09008'); INSERT INTO hotel VALUES(522,'Bohne','Kakau b. Bitterfeld','Zur Plantage','14','06785'); INSERT INTO hotel VALUES(132,'Gruene Bogenschuetze','Geseke','An der Abtei','3','59590'); INSERT INTO hotel VALUES(625,'Hotel Adlon','Dortmund','Lilienthalstrasse','68a','44369'); INSERT INTO hotel VALUES(392,'Hotel Kempinski','Muenchen','Terminalstrasse', '20-22','85356'); INSERT INTO ausstattung VALUES(23,'Telefon', 5.67); INSERT INTO ausstattung VALUES(35,'Goldene Wascharmaturen', 45.16); INSERT INTO ausstattung VALUES(47,'Extragroße Badetuecher', 9.99); INSERT INTO ausstattung VALUES(59,'Bettwaesche', 10.32); INSERT INTO ausstattung VALUES(61,'Haekelkissenbezuege', 13.57); INSERT INTO ausstattung VALUES(73,'Kabelfernsehen', 15.66); INSERT INTO ausstattung VALUES(84,'Satellitenfernsehen', 16.55); INSERT INTO ausstattung VALUES(96,'Beamer', 23.79); INSERT INTO ausstattung VALUES(108,'Overheadprojektor', 17.43); INSERT INTO ausstattung VALUES(111,'Videorekorder', 16.89); INSERT INTO ausstattung VALUES(123,'DVD-Player', 18.52); INSERT INTO ausstattung VALUES(130,'HiFi-Multifunktionsanlage', 25.91); INSERT INTO ausstattung VALUES(142,'Stuhl', 4.31); INSERT INTO ausstattung VALUES(154,'Tisch', 5.76); INSERT INTO ausstattung VALUES(166,'Kopfkissen', 15.69); INSERT INTO ausstattung VALUES(178,'Gummibettlaken', 17.83); INSERT INTO ausstattung VALUES(62,'gehaekelte Toilettenrollendeckchen', 11.46); INSERT INTO zimmer VALUES(34, 3, 'No3', 1, 19.99); INSERT INTO zimmer VALUES(135, 312, 'Praesidentensuite', 6, 399.99); INSERT INTO zimmer VALUES(428, 222, 'Stollen Sued', 2, 24.99); INSERT INTO zimmer VALUES(843, 145, 'Seeblick', 3, 89.67); INSERT INTO zimmer VALUES(1036, 217, 'Waldblick', 2, 45.99); INSERT INTO zimmer VALUES(428, 111, 'Stollen Nord', 1, 23.99); INSERT INTO zimmer VALUES(843, 732, 'Krabbenkutter', 5, 485.00); INSERT INTO zimmer VALUES(135, 521, 'Westfalenzimmer', 4, 167.55); INSERT INTO zimmer VALUES(34, 4, 'No4', 2, 21.99); INSERT INTO zimmer VALUES(1036, 1214, 'Schwanenteich', 3, 76.99); INSERT INTO zimmer VALUES(522, 113,'Onkel Toms Huette', 2, 54.99); INSERT INTO zimmer VALUES(522, 124,'Singendes Zuckerrohr', 3, 65.35); INSERT INTO zimmer VALUES(132, 115,'Waldruh', 2, 55.34); INSERT INTO zimmer VALUES(132, 134,'Hochsitz', 4, 89.47); INSERT INTO zimmer VALUES(625, 257,'Metropolian', 2, 76.21); INSERT INTO zimmer VALUES(625, 412,'Blickpunkt', 3, 87.25); INSERT INTO zimmer VALUES(392, 233,'Waldfried', 1, 32.46); INSERT INTO zimmer VALUES(392, 513,'Flugplatz', 2, 43.62); INSERT INTO normal VALUES(1036, 217, 23); INSERT INTO normal VALUES(843, 145, 73); INSERT INTO normal VALUES(34, 3, 23); INSERT INTO normal VALUES(428, 222, 61); INSERT INTO normal VALUES(135, 312, 166); INSERT INTO normal VALUES(428, 111, 142); INSERT INTO normal VALUES(34, 4, 59); INSERT INTO normal VALUES(1036, 1214, 84); INSERT INTO normal VALUES(135, 521, 178); INSERT INTO normal VALUES(843, 732, 130); INSERT INTO normal VALUES(522, 113, 62); INSERT INTO normal VALUES(522, 124, 59); INSERT INTO normal VALUES(132, 115, 73); INSERT INTO normal VALUES(132, 134, 84); INSERT INTO normal VALUES(625, 257, 23); INSERT INTO normal VALUES(625, 412, 166); INSERT INTO normal VALUES(392, 233, 35); INSERT INTO normal VALUES(392, 513, 130); INSERT INTO normal VALUES(522, 113, 59); INSERT INTO gast VALUES(453, 'Muller', 'Jean-Paul', 'Havixbeck', '48329', 'Willi-Richter-Platz', '2b'); INSERT INTO gast VALUES(14753, 'Richter','Trude','Buxtehude','21614', 'Zwischen den Bruecken','6'); INSERT INTO gast VALUES(795, 'Stein','Flut','Herten','46599','Stan-Libuda-Strasse','1'); INSERT INTO gast VALUES(8531,'Mustermann','Martin','Musterstadt','10000','Poststrasse','13-15'); INSERT INTO gast VALUES(7184,'Postmann','Elfriede','Chemnitz','09008','Erich-Honecker-Platz','23'); INSERT INTO gast VALUES(3417,'Randzio','Katharina','Aue','08280','Goethestrasse','101a'); INSERT INTO gast VALUES(59375,'Engelke-Meise','Silke','Herne','44625','Jaegerstrasse','13'); INSERT INTO gast VALUES(58,'Ebbingmann','Adalbert','Fuessen','87629','Froschseenstrasse','33'); INSERT INTO gast VALUES(4711,'Matzke','Muximilian','Waldshut','79761','Kaiserstrasse','27'); INSERT INTO gast VALUES(8624,'Rupprecht','Knecht','Himmelstadt','97267','Kirchplatz','5'); INSERT INTO gast VALUES(2738,'Schmitz','Klaus','Dortmund','44147','Linienstrasse','7b'); INSERT INTO gast VALUES(2631,'Biene','Maja','Blumenberg','50765','Auf der Blume','24'); INSERT INTO gast VALUES(2632,'Groenemeyer','Herbert','Berlin','10435','Rheinsberger Strasse','48'); INSERT INTO gast VALUES(2635,'Baerbock','Annalena','Berlin','11011','Platz der Republik','1'); INSERT INTO Gast (gnr,name,vorname,ort,plz,strasse,hausnr) VALUES (44,'Schulz','Maja','Gießen','35390','Wiesenstr.','10'); INSERT INTO reservierung VALUES(86542, '2002-09-09', 34, 453); INSERT INTO reservierung VALUES(145863, '2002-01-02', 135, 14753); INSERT INTO reservierung VALUES(46357, '2003-04-01', 843, 795); INSERT INTO reservierung VALUES(43358, '2003-03-23', 428, 8531); INSERT INTO reservierung VALUES(135, '1995-09-19', 1036, 7184); INSERT INTO reservierung VALUES(6834, '2004-08-13', 34, 3417); INSERT INTO reservierung VALUES(115, '2003-05-27', 428, 59375); INSERT INTO reservierung VALUES(8673, '2003-05-03', 135, 58); INSERT INTO reservierung VALUES(24, '1999-08-31', 843, 4711); INSERT INTO reservierung VALUES(9999, '2003-12-12', 1036, 8624); INSERT INTO reservierung VALUES(735, '2003-03-13', 132, 4711); INSERT INTO reservierung VALUES(567, '2002-02-24', 625, 2738); INSERT INTO reservierung VALUES(818, '2004-03-01', 392, 8624); INSERT INTO reservierung VALUES(361, '1998-12-21', 34, 59375); INSERT INTO reservierung VALUES(5294, '2001-10-10', 392, 3417); INSERT INTO reservierung VALUES(2732, '1996-04-13', 132, 7184); INSERT INTO reservierung VALUES(2432, '2001-07-16', 522, 453); INSERT INTO reservierung VALUES(1953, '2001-08-23', 135, 14753); INSERT INTO reservierung VALUES(356, '2004-01-01', 1036, 2631); INSERT INTO reservierung VALUES(5646, '2005-02-05', 522, 795); INSERT INTO reservierung VALUES(6748, '2005-03-22', 522, 795); INSERT INTO reservierung VALUES(2748, '2004-02-10', 132, 4711); INSERT INTO reservierung VALUES(2349, '2004-02-10', 132, 58); INSERT INTO reservierung VALUES(4241, '2005-02-10', 132, 58); INSERT INTO reservierung VALUES(6878, '2006-02-10', 132, 58); INSERT INTO rposition VALUES(86542, 1, '2002-10-10', '2003-10-10', 34, 3); INSERT INTO rposition VALUES(145863, 1, '2003-04-11', '2003-04-22', 135, 312); INSERT INTO rposition VALUES(43358, 1, '2003-05-05', '2003-05-06', 428, 222); INSERT INTO rposition VALUES(46357, 1, '2004-04-26', '2004-05-07', 843,145); INSERT INTO rposition VALUES(135, 1, '1997-09-18', '1997-09-22', 1036, 217); INSERT INTO rposition VALUES(115, 1, '2004-05-28', '2004-05-31', 428, 111); INSERT INTO rposition VALUES(24, 1, '2001-04-08', '2001-04-25', 843, 732); INSERT INTO rposition VALUES(24, 2, '2001-04-08', '2001-04-25', 843, 145); INSERT INTO rposition VALUES(24, 3, '2001-07-31', '2001-09-01', 34, 3); INSERT INTO rposition VALUES(24, 4, '2001-07-31', '2001-09-01', 34, 4); INSERT INTO rposition VALUES(8673, 1, '2003-07-01', '2003-07-15', 135, 521); INSERT INTO rposition VALUES(6834, 1, '2004-08-15', '2004-08-27', 34, 4); INSERT INTO rposition VALUES(9999, 1, '2004-04-30', '2004-06-30', 1036, 1214); INSERT INTO rposition VALUES(9999, 2, '2004-07-01', '2004-07-31', 135, 312); INSERT INTO rposition VALUES(9999, 3, '2004-08-31', '2004-10-01', 843, 145); INSERT INTO rposition VALUES(735, 1, '2003-03-20', '2004-04-20', 392, 233); INSERT INTO rposition VALUES(567, 1, '2003-04-23', '2003-05-07', 522,113); INSERT INTO rposition VALUES(818, 1, '2004-03-24', '2004-03-31', 132, 134); INSERT INTO rposition VALUES(361, 1, '1999-12-23', '2000-01-06', 625, 257); INSERT INTO rposition VALUES(5294, 1, '2002-04-02', '2002-04-16', 428, 111); INSERT INTO rposition VALUES(2732, 1, '1996-08-17', '1996-09-04', 522, 124); INSERT INTO rposition VALUES(2432, 1, '2002-06-15', '2002-07-16', 132, 115); INSERT INTO rposition VALUES(1953, 1, '2004-08-07', '2004-08-15', 392, 513); INSERT INTO rposition VALUES(818, 2, '2004-04-01', '2004-04-12', 843, 732); INSERT INTO rposition VALUES(356, 1, '2004-01-02', '2004-04-22', 522, 113); INSERT INTO rposition VALUES(5646, 1, '2005-03-06', '2005-03-22', 843, 145); INSERT INTO rposition VALUES(6748, 1, '2006-01-01', '2006-01-08', 843, 145); INSERT INTO rposition VALUES(2748, 1, '2004-04-01', '2004-04-08', 392, 233); INSERT INTO rposition VALUES(2349, 1, '2004-07-16', '2004-07-18', 392, 233); INSERT INTO rposition VALUES(4241, 1, '2005-07-16', '2005-07-18', 392, 233); INSERT INTO rposition VALUES(6878, 1, '2006-07-16', '2006-07-18', 392, 233); INSERT INTO zusatz VALUES(735, 1, 84, '2003-03-21', '2004-03-30'); INSERT INTO zusatz VALUES(567, 1, 61, '2003-04-23', '2003-05-07'); INSERT INTO zusatz VALUES(818, 1, 111, '2004-03-24', '2004-03-28'); INSERT INTO zusatz VALUES(361, 1, 142, '1999-12-26', '2000-01-06'); INSERT INTO zusatz VALUES(43358, 1, 154, '2003-05-05', '2003-05-06'); INSERT INTO zusatz VALUES(2732, 1, 47, '1996-08-17', '1996-08-18'); INSERT INTO zusatz VALUES(2432, 1, 123, '2002-06-30', '2002-07-01'); INSERT INTO zusatz VALUES(1953, 1, 178, '2004-08-07', '2004-08-15'); INSERT INTO zusatz VALUES(818, 2, 96, '2004-04-04', '2004-04-11'); INSERT INTO zusatz VALUES(818, 2, 108, '2004-04-03', '2004-04-10'); INSERT INTO zusatz VALUES(818, 2, 111, '2004-04-03', '2004-04-11'); INSERT INTO zusatz VALUES(735, 1, 130, '2003-03-22', '2004-03-29'); INSERT INTO zusatz VALUES(145863, 1, 35, '2003-04-14', '2003-04-19'); INSERT INTO zusatz VALUES(46357, 1, 61, '2004-04-26', '2004-05-07'); INSERT INTO zusatz VALUES(46357, 1, 84, '2004-04-30', '2004-05-03'); INSERT INTO zusatz VALUES(46357, 1, 111, '2004-05-01', '2004-05-03'); INSERT INTO zusatz VALUES(46357, 1, 130, '2004-04-30', '2004-05-02'); INSERT INTO zusatz VALUES(135, 1, 96, '1997-09-19', '1997-09-20'); INSERT INTO zusatz VALUES(135, 1, 108, '1997-09-19', '1997-09-19'); INSERT INTO zusatz VALUES(135, 1, 111, '1997-09-20', '1997-09-20'); INSERT INTO zusatz VALUES(24, 1, 142, '2001-04-16', '2001-04-19'); INSERT INTO zusatz VALUES(24, 3, 178, '2001-08-01', '2001-08-27'); INSERT INTO zusatz VALUES(24, 4, 47, '2001-08-01', '2001-08-27'); INSERT INTO zusatz VALUES(8673, 1, 47, '2003-07-03', '2003-07-05'); INSERT INTO zusatz VALUES(9999, 1, 84, '2004-05-05', '2004-05-05'); INSERT INTO zusatz VALUES(9999, 1, 130, '2004-06-06', '2004-06-07'); INSERT INTO zusatz VALUES(9999, 2, 130, '2004-07-01', '2004-07-31'); INSERT INTO zusatz VALUES(9999, 3, 130, '2004-09-01', '2004-09-30'); INSERT INTO zusatz VALUES(9999, 3, 61, '2004-09-01', '2004-09-30'); INSERT INTO zusatz Values(356, 1, 35, '2004-01-02', '2004-04-22'); INSERT INTO zusatz Values(356, 1, 47, '2004-01-02', '2004-04-22'); Update reservierung set datum=datum+730; Update rposition set von=von+1095, bis=bis+1095; Update zusatz set von=von+1095, bis=bis+1095; ALTER TABLE normal ADD anzahl INTEGER DEFAULT 1; ALTER TABLE zusatz ADD anzahl INTEGER DEFAULT 1; INSERT INTO ausstattung VALUES(46,'Bademantel','5.50'); INSERT INTO ausstattung VALUES(45,'Hausschuhe','2.35'); INSERT INTO ausstattung VALUES(50,'Kinderbett','0.0'); INSERT INTO ausstattung VALUES(51,'Hochstuhl','0.0'); INSERT INTO ausstattung VALUES(52,'Safe','2.45'); INSERT INTO ausstattung VALUES(53,'Heizdecke','16.85'); INSERT INTO ausstattung VALUES(54,'Duftkerzen','12.15'); INSERT INTO ausstattung VALUES(24,'W-LAN Zugang','5.95'); INSERT INTO ausstattung VALUES(25,'DSL-Anschluss','7.69'); INSERT INTO hotel VALUES(736,'Gasthof Sybille','Bad Lippspringe','An der Jordanquelle','1','33188'); INSERT INTO hotel VALUES(758,'Kastens Hotel','Duesseldorf','Lorettostr','5','40219'); INSERT INTO hotel VALUES(761,'Am Glockenturm','Arnsberg','Soesterstr','1','59821'); INSERT INTO zimmer VALUES(34,5,'No5',2,'21.99'); INSERT INTO zimmer VALUES(132,122,'Strecke',2,'60.45'); INSERT INTO zimmer VALUES(135,412,'Rosa Raum',2,'90.35'); INSERT INTO zimmer VALUES(392,414,'Schlafwohl',2,'59.95'); INSERT INTO zimmer VALUES(428,333,'Stollen West',2,'24.99'); INSERT INTO zimmer VALUES(522,135,'Missippi',2,'52.89'); INSERT INTO zimmer VALUES(625,333,'Schoene Aussicht',2,'74.25'); INSERT INTO zimmer VALUES(843,363,'Morgenroete',2,'195.25'); INSERT INTO zimmer VALUES(1036,512,'Angeraue',2,'50.12'); INSERT INTO zimmer VALUES(736,11,'Arminiusquelle',2,'45.40'); INSERT INTO zimmer VALUES(736,12,'Jordanquelle',2,'45.40'); INSERT INTO zimmer VALUES(736,14,'Lippequelle',2,50.50); INSERT INTO zimmer VALUES(758,25,'Rheinturm',2,78.99); INSERT INTO zimmer VALUES(758,26,'Stadttor',2,78.99); INSERT INTO zimmer VALUES(758,27,'Kniebruecke',2,74.99); INSERT INTO zimmer VALUES(761,31,'Schlossberg',2,25.85); INSERT INTO zimmer VALUES(761,32,'Gambrinus',2,19.99); INSERT INTO zimmer VALUES(761,33,'Muffrika',4,48.55); INSERT INTO normal VALUES(34,5,59,2); INSERT INTO normal VALUES(132,122,59,2); INSERT INTO normal VALUES(135,412,59,2); INSERT INTO normal VALUES(392,414,59,2); INSERT INTO normal VALUES(428,333,59,2); INSERT INTO normal VALUES(522,135,59,2); INSERT INTO normal VALUES(625,333,59,2); INSERT INTO normal VALUES(843,363,59,2); INSERT INTO normal VALUES(1036,512,59,2); INSERT INTO normal VALUES(736,11,59,2); INSERT INTO normal VALUES(736,12,59,2); INSERT INTO normal VALUES(736,14,59,2); INSERT INTO normal VALUES(758,25,59,2); INSERT INTO normal VALUES(758,26,59,2); INSERT INTO normal VALUES(758,27,59,2); INSERT INTO normal VALUES(761,31,59,2); INSERT INTO normal VALUES(761,32,59,2); INSERT INTO normal VALUES(761,33,59,4); INSERT INTO normal VALUES(34,5,62,1); INSERT INTO normal VALUES(132,122,62,1); INSERT INTO normal VALUES(135,412,62,1); INSERT INTO normal VALUES(392,414,62,1); INSERT INTO normal VALUES(428,333,62,1); INSERT INTO normal VALUES(522,135,62,1); INSERT INTO normal VALUES(625,333,62,1); INSERT INTO normal VALUES(843,363,62,1); INSERT INTO normal VALUES(1036,512,62,1); INSERT INTO normal VALUES(736,11,53,1); INSERT INTO normal VALUES(736,12,53,1); INSERT INTO normal VALUES(736,14,53,1); INSERT INTO normal VALUES(758,25,142,1); INSERT INTO normal VALUES(758,26,142,1); INSERT INTO normal VALUES(758,27,142,1); INSERT INTO normal VALUES(761,31,178,2); INSERT INTO normal VALUES(761,32,178,2); INSERT INTO normal VALUES(761,33,178,4); INSERT INTO gast VALUES(25,'Binz','Gunnar','Duesseldorf','40549','Heerdter Sandberg','3'); INSERT INTO gast VALUES(26,'Haller','Karl-Heinz','Dortmund','44143','Breierspfad','134'); INSERT INTO gast VALUES(27,'Kloepping','Harald','Bamberg','96058','Eckeystr','15'); INSERT INTO gast VALUES(28,'Schlanstein','Christina','Dillenburg','35683','Carl-Schurz-Str','9'); INSERT INTO gast VALUES(29,'Gauss','Kerstin','Neuss','41453','Badstr','3'); INSERT INTO gast VALUES(30,'Hansen','Irmgard','Bamberg','96023','Neuer Weg','15'); INSERT INTO gast VALUES(31,'Rosenberg','Brigitte','Duisburg','41025','Rahmerstr','168'); INSERT INTO gast VALUES(32,'Lampe','Rosa','Vechta','49377','Schwichtelerstr','14'); INSERT INTO gast VALUES(33,'Mondo','Dolores','Hagen','58093','Dortmunder Str','15a'); INSERT INTO reservierung VALUES(221,'2009-05-15',736,25); INSERT INTO reservierung VALUES(222,'2009-01-11',758,26); INSERT INTO reservierung VALUES(223,'2008-11-05',761,27); INSERT INTO reservierung VALUES(224,'2008-10-03',761,28); INSERT INTO reservierung VALUES(225,'2007-07-18',135,27); INSERT INTO reservierung VALUES(226,'2007-11-06',522,29); INSERT INTO reservierung VALUES(227,'2007-12-13',428,30); INSERT INTO reservierung VALUES(228,'2008-02-15',843,31); INSERT INTO reservierung VALUES(229,'2008-03-25',135,32); INSERT INTO reservierung VALUES(230,'2008-04-13',758,33); INSERT INTO reservierung VALUES(231,'2008-06-07',758,33); INSERT INTO reservierung VALUES(232,'2008-08-13',522,25); INSERT INTO reservierung VALUES(233,'2009-04-13',736,29); INSERT INTO reservierung VALUES(234,'2009-02-26',522,27); INSERT INTO reservierung VALUES(235,'2008-08-13',761,26); INSERT INTO reservierung VALUES(236,'2008-09-30',761,25); INSERT INTO reservierung VALUES(237,'2009-03-11',843,33); INSERT INTO reservierung VALUES(238,'2008-04-13',843,58); INSERT INTO reservierung VALUES(239,'2008-11-11',758,58); INSERT INTO reservierung VALUES(240,'2009-02-03',135,453); INSERT INTO reservierung VALUES(241,'2007-12-28',522,795); INSERT INTO rposition VALUES(221,1,'2009-05-25','2009-06-05',736,11); INSERT INTO rposition VALUES(222,1,'2009-04-15','2009-04-18',736,12); INSERT INTO rposition VALUES(223,1,'2009-01-11','2009-01-18',736,14); INSERT INTO rposition VALUES(223,2,'2009-02-11','2009-02-18',736,11); INSERT INTO rposition VALUES(223,3,'2009-03-11','2009-03-18',736,14); INSERT INTO rposition VALUES(224,1,'2008-11-11','2008-11-15',758,25); INSERT INTO rposition VALUES(225,1,'2007-07-31','2007-08-15',758,26); INSERT INTO rposition VALUES(226,1,'2007-11-11','2007-11-13',758,27); INSERT INTO rposition VALUES(227,1,'2008-01-12','2008-01-15',761,31); INSERT INTO rposition VALUES(228,1,'2008-03-02','2008-03-08',761,32); INSERT INTO rposition VALUES(228,2,'2008-04-02','2008-04-08',761,32); INSERT INTO rposition VALUES(228,3,'2008-05-02','2008-05-08',761,32); INSERT INTO rposition VALUES(229,1,'2008-03-28','2008-04-07',761,33); INSERT INTO rposition VALUES(230,1,'2008-05-02','2008-05-13',132,122); INSERT INTO rposition VALUES(231,1,'2008-07-01','2008-07-05',34,3); INSERT INTO rposition VALUES(231,2,'2008-07-01','2008-07-05',34,4); INSERT INTO rposition VALUES(231,3,'2008-07-01','2008-07-05',34,5); INSERT INTO rposition VALUES(232,1,'2008-09-19','2008-09-21',135,412); INSERT INTO rposition VALUES(233,1,'2009-05-01','2009-05-05',392,414); INSERT INTO rposition VALUES(234,1,'2009-03-01','2009-03-05',428,333); INSERT INTO rposition VALUES(235,1,'2008-09-01','2008-09-05',522,135); INSERT INTO rposition VALUES(236,1,'2008-12-01','2008-12-10',625,333); INSERT INTO rposition VALUES(237,1,'2009-03-18','2009-03-25',843,363); INSERT INTO rposition VALUES(238,1,'2008-07-01','2008-07-05',1036,512); INSERT INTO rposition VALUES(239,1,'2008-11-11','2008-11-15',758,26); INSERT INTO rposition VALUES(240,1,'2009-02-11','2009-02-15',135,412); INSERT INTO rposition VALUES(241,1,'2008-01-02','2008-01-09',522,135); INSERT INTO zusatz VALUES(221,1,50,'2009-05-25','2009-06-05',2); INSERT INTO zusatz VALUES(221,1,51,'2009-05-25','2009-06-05',2); INSERT INTO zusatz VALUES(222,1,53,'2009-04-15','2009-04-18',2); INSERT INTO zusatz VALUES(224,1,53,'2008-11-11','2008-11-15',1); INSERT INTO zusatz VALUES(225,1,52,'2007-07-31','2007-08-15',1); INSERT INTO zusatz VALUES(226,1,52,'2007-11-11','2007-11-13',1); INSERT INTO zusatz VALUES(227,1,52,'2008-01-12','2008-01-15',2); INSERT INTO zusatz VALUES(229,1,45,'2008-03-29','2008-04-07',2); INSERT INTO zusatz VALUES(230,1,45,'2008-05-03','2008-05-13',1); INSERT INTO zusatz VALUES(230,1,46,'2008-05-03','2008-05-13',1); INSERT INTO zusatz VALUES(232,1,54,'2008-09-19','2008-09-21',1); INSERT INTO zusatz VALUES(233,1,24,'2009-05-01','2009-05-05',1); INSERT INTO zusatz VALUES(234,1,25,'2009-03-03','2009-03-05',1); INSERT INTO zusatz VALUES(235,1,142,'2008-09-03','2008-09-04',4); INSERT INTO zusatz VALUES(235,1,154,'2008-09-03','2008-09-04',1); INSERT INTO zusatz VALUES(239,1,84,'2008-11-11','2008-11-15',1); INSERT INTO zusatz VALUES(240,1,111,'2009-02-11','2009-02-15',1);", + }, + { + id: 3, + name: "Hotel, Schema + Daten", + category: categories[0], + templateQuery: + "CREATE TABLE hotel ( HoNr INTEGER NOT NULL, HName VARCHAR(40), Ort VARCHAR(40), Straße VARCHAR(40), HausNr VARCHAR(5), PLZ CHAR(5), CONSTRAINT pk_hotel PRIMARY KEY(HoNr)); CREATE TABLE zimmer ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ZName VARCHAR(40), Kapazitaet INTEGER, Preis DECIMAL(8,2), CONSTRAINT pk_zimmer PRIMARY KEY(HoNr, ZNr), CONSTRAINT fk_zimmer FOREIGN KEY(HoNr) REFERENCES hotel(HoNr)); CREATE TABLE ausstattung ( ANr INTEGER NOT NULL, Bezeichnung VARCHAR(40), Zusatzkosten DECIMAL(8,2), CONSTRAINT pk_ausstattung PRIMARY KEY(ANr)); CREATE TABLE normal ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ANr INTEGER NOT NULL, CONSTRAINT pk_normal PRIMARY KEY(HoNr, ZNr, ANr), CONSTRAINT fk_normal_1 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT fk_normal_2 FOREIGN KEY(HoNr, ZNr) REFERENCES zimmer(HoNr, ZNr)); CREATE TABLE gast ( GNr INTEGER NOT NULL, Name VARCHAR(30), Vorname VARCHAR(40), Ort VARCHAR(50), PLZ CHAR(5), Strasse VARCHAR(50), HausNr VARCHAR(5), CONSTRAINT pk_gast PRIMARY KEY(GNr)); CREATE TABLE reservierung ( RNr INTEGER NOT NULL, Datum DATE, HoNr INTEGER, GNr INTEGER, CONSTRAINT pk_reservierung PRIMARY KEY(RNr), CONSTRAINT fk_reservierung_1 FOREIGN KEY(HoNr) REFERENCES hotel(HoNr), CONSTRAINT fk_reservierung_2 FOREIGN KEY(GNr) REFERENCES gast(GNr)); CREATE TABLE rposition ( RNr INTEGER NOT NULL, RPos INTEGER NOT NULL, von DATE, bis DATE, HoNr INTEGER, ZNr INTEGER, CONSTRAINT pk_position PRIMARY KEY(RNr, RPos), CONSTRAINT fk_position_1 FOREIGN KEY(RNr) REFERENCES reservierung(RNr), CONSTRAINT fk_position_2 FOREIGN KEY(HoNr, ZNr) REFERENCES zimmer(HoNr, ZNr), CONSTRAINT check_date CHECK (von <= bis)); CREATE TABLE zusatz ( RNr INTEGER NOT NULL, RPos INTEGER NOT NULL, ANr INTEGER NOT NULL, von DATE, bis DATE, CONSTRAINT pk_zusatz PRIMARY KEY(RNr, RPos, ANr), CONSTRAINT fk_zusatz_1 FOREIGN KEY(RNr, RPos) REFERENCES rposition(RNr, RPos), CONSTRAINT fk_zusatz_2 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT check_date CHECK (von <= bis)); INSERT INTO hotel VALUES(1036, 'Ringhotel', 'Luenen', 'Kurt-Schumacher-Strasse', '1', '44534'); INSERT INTO hotel VALUES(34 ,'Haus Schmuelling','Bergkamen','Landwehrstrasse', '54', '59192'); INSERT INTO hotel VALUES(135, 'City Hotel', 'Dortmund', 'Auf dem Wall','62', '44147'); INSERT INTO hotel VALUES(843,'Maritim','Stralsund','Strandgasse','37','18435'); INSERT INTO hotel VALUES(428,'Riss','Chemnitz','An der Erzkuhle','23', '09008'); INSERT INTO hotel VALUES(522,'Bohne','Kakau b. Bitterfeld','Zur Plantage','14','06785'); INSERT INTO hotel VALUES(132,'Gruene Bogenschuetze','Geseke','An der Abtei','3','59590'); INSERT INTO hotel VALUES(625,'Hotel Adlon','Dortmund','Lilienthalstrasse','68a','44369'); INSERT INTO hotel VALUES(392,'Hotel Kempinski','Muenchen','Terminalstrasse', '20-22','85356'); INSERT INTO ausstattung VALUES(23,'Telefon', 5.67); INSERT INTO ausstattung VALUES(35,'Goldene Wascharmaturen', 45.16); INSERT INTO ausstattung VALUES(47,'Extragroße Badetuecher', 9.99); INSERT INTO ausstattung VALUES(59,'Bettwaesche', 10.32); INSERT INTO ausstattung VALUES(61,'Haekelkissenbezuege', 13.57); INSERT INTO ausstattung VALUES(73,'Kabelfernsehen', 15.66); INSERT INTO ausstattung VALUES(84,'Satellitenfernsehen', 16.55); INSERT INTO ausstattung VALUES(96,'Beamer', 23.79); INSERT INTO ausstattung VALUES(108,'Overheadprojektor', 17.43); INSERT INTO ausstattung VALUES(111,'Videorekorder', 16.89); INSERT INTO ausstattung VALUES(123,'DVD-Player', 18.52); INSERT INTO ausstattung VALUES(130,'HiFi-Multifunktionsanlage', 25.91); INSERT INTO ausstattung VALUES(142,'Stuhl', 4.31); INSERT INTO ausstattung VALUES(154,'Tisch', 5.76); INSERT INTO ausstattung VALUES(166,'Kopfkissen', 15.69); INSERT INTO ausstattung VALUES(178,'Gummibettlaken', 17.83); INSERT INTO ausstattung VALUES(62,'gehaekelte Toilettenrollendeckchen', 11.46); INSERT INTO zimmer VALUES(34, 3, 'No3', 1, 19.99); INSERT INTO zimmer VALUES(135, 312, 'Praesidentensuite', 6, 399.99); INSERT INTO zimmer VALUES(428, 222, 'Stollen Sued', 2, 24.99); INSERT INTO zimmer VALUES(843, 145, 'Seeblick', 3, 89.67); INSERT INTO zimmer VALUES(1036, 217, 'Waldblick', 2, 45.99); INSERT INTO zimmer VALUES(428, 111, 'Stollen Nord', 1, 23.99); INSERT INTO zimmer VALUES(843, 732, 'Krabbenkutter', 5, 485.00); INSERT INTO zimmer VALUES(135, 521, 'Westfalenzimmer', 4, 167.55); INSERT INTO zimmer VALUES(34, 4, 'No4', 2, 21.99); INSERT INTO zimmer VALUES(1036, 1214, 'Schwanenteich', 3, 76.99); INSERT INTO zimmer VALUES(522, 113,'Onkel Toms Huette', 2, 54.99); INSERT INTO zimmer VALUES(522, 124,'Singendes Zuckerrohr', 3, 65.35); INSERT INTO zimmer VALUES(132, 115,'Waldruh', 2, 55.34); INSERT INTO zimmer VALUES(132, 134,'Hochsitz', 4, 89.47); INSERT INTO zimmer VALUES(625, 257,'Metropolian', 2, 76.21); INSERT INTO zimmer VALUES(625, 412,'Blickpunkt', 3, 87.25); INSERT INTO zimmer VALUES(392, 233,'Waldfried', 1, 32.46); INSERT INTO zimmer VALUES(392, 513,'Flugplatz', 2, 43.62); INSERT INTO normal VALUES(1036, 217, 23); INSERT INTO normal VALUES(843, 145, 73); INSERT INTO normal VALUES(34, 3, 23); INSERT INTO normal VALUES(428, 222, 61); INSERT INTO normal VALUES(135, 312, 166); INSERT INTO normal VALUES(428, 111, 142); INSERT INTO normal VALUES(34, 4, 59); INSERT INTO normal VALUES(1036, 1214, 84); INSERT INTO normal VALUES(135, 521, 178); INSERT INTO normal VALUES(843, 732, 130); INSERT INTO normal VALUES(522, 113, 62); INSERT INTO normal VALUES(522, 124, 59); INSERT INTO normal VALUES(132, 115, 73); INSERT INTO normal VALUES(132, 134, 84); INSERT INTO normal VALUES(625, 257, 23); INSERT INTO normal VALUES(625, 412, 166); INSERT INTO normal VALUES(392, 233, 35); INSERT INTO normal VALUES(392, 513, 130); INSERT INTO normal VALUES(522, 113, 59); INSERT INTO gast VALUES(453, 'Muller', 'Jean-Paul', 'Havixbeck', '48329', 'Willi-Richter-Platz', '2b'); INSERT INTO gast VALUES(14753, 'Richter','Trude','Buxtehude','21614', 'Zwischen den Bruecken','6'); INSERT INTO gast VALUES(795, 'Stein','Flut','Herten','46599','Stan-Libuda-Strasse','1'); INSERT INTO gast VALUES(8531,'Mustermann','Martin','Musterstadt','10000','Poststrasse','13-15'); INSERT INTO gast VALUES(7184,'Postmann','Elfriede','Chemnitz','09008','Erich-Honecker-Platz','23'); INSERT INTO gast VALUES(3417,'Randzio','Katharina','Aue','08280','Goethestrasse','101a'); INSERT INTO gast VALUES(59375,'Engelke-Meise','Silke','Herne','44625','Jaegerstrasse','13'); INSERT INTO gast VALUES(58,'Ebbingmann','Adalbert','Fuessen','87629','Froschseenstrasse','33'); INSERT INTO gast VALUES(4711,'Matzke','Muximilian','Waldshut','79761','Kaiserstrasse','27'); INSERT INTO gast VALUES(8624,'Rupprecht','Knecht','Himmelstadt','97267','Kirchplatz','5'); INSERT INTO gast VALUES(2738,'Schmitz','Klaus','Dortmund','44147','Linienstrasse','7b'); INSERT INTO gast VALUES(2631,'Biene','Maja','Blumenberg','50765','Auf der Blume','24'); INSERT INTO gast VALUES(2632,'Groenemeyer','Herbert','Berlin','10435','Rheinsberger Strasse','48'); INSERT INTO gast VALUES(2635,'Baerbock','Annalena','Berlin','11011','Platz der Republik','1'); INSERT INTO Gast (gnr,name,vorname,ort,plz,strasse,hausnr) VALUES (44,'Schulz','Maja','Gießen','35390','Wiesenstr.','10'); INSERT INTO reservierung VALUES(86542, '2002-09-09', 34, 453); INSERT INTO reservierung VALUES(145863, '2002-01-02', 135, 14753); INSERT INTO reservierung VALUES(46357, '2003-04-01', 843, 795); INSERT INTO reservierung VALUES(43358, '2003-03-23', 428, 8531); INSERT INTO reservierung VALUES(135, '1995-09-19', 1036, 7184); INSERT INTO reservierung VALUES(6834, '2004-08-13', 34, 3417); INSERT INTO reservierung VALUES(115, '2003-05-27', 428, 59375); INSERT INTO reservierung VALUES(8673, '2003-05-03', 135, 58); INSERT INTO reservierung VALUES(24, '1999-08-31', 843, 4711); INSERT INTO reservierung VALUES(9999, '2003-12-12', 1036, 8624); INSERT INTO reservierung VALUES(735, '2003-03-13', 132, 4711); INSERT INTO reservierung VALUES(567, '2002-02-24', 625, 2738); INSERT INTO reservierung VALUES(818, '2004-03-01', 392, 8624); INSERT INTO reservierung VALUES(361, '1998-12-21', 34, 59375); INSERT INTO reservierung VALUES(5294, '2001-10-10', 392, 3417); INSERT INTO reservierung VALUES(2732, '1996-04-13', 132, 7184); INSERT INTO reservierung VALUES(2432, '2001-07-16', 522, 453); INSERT INTO reservierung VALUES(1953, '2001-08-23', 135, 14753); INSERT INTO reservierung VALUES(356, '2004-01-01', 1036, 2631); INSERT INTO reservierung VALUES(5646, '2005-02-05', 522, 795); INSERT INTO reservierung VALUES(6748, '2005-03-22', 522, 795); INSERT INTO reservierung VALUES(2748, '2004-02-10', 132, 4711); INSERT INTO reservierung VALUES(2349, '2004-02-10', 132, 58); INSERT INTO reservierung VALUES(4241, '2005-02-10', 132, 58); INSERT INTO reservierung VALUES(6878, '2006-02-10', 132, 58); INSERT INTO rposition VALUES(86542, 1, '2002-10-10', '2003-10-10', 34, 3); INSERT INTO rposition VALUES(145863, 1, '2003-04-11', '2003-04-22', 135, 312); INSERT INTO rposition VALUES(43358, 1, '2003-05-05', '2003-05-06', 428, 222); INSERT INTO rposition VALUES(46357, 1, '2004-04-26', '2004-05-07', 843,145); INSERT INTO rposition VALUES(135, 1, '1997-09-18', '1997-09-22', 1036, 217); INSERT INTO rposition VALUES(115, 1, '2004-05-28', '2004-05-31', 428, 111); INSERT INTO rposition VALUES(24, 1, '2001-04-08', '2001-04-25', 843, 732); INSERT INTO rposition VALUES(24, 2, '2001-04-08', '2001-04-25', 843, 145); INSERT INTO rposition VALUES(24, 3, '2001-07-31', '2001-09-01', 34, 3); INSERT INTO rposition VALUES(24, 4, '2001-07-31', '2001-09-01', 34, 4); INSERT INTO rposition VALUES(8673, 1, '2003-07-01', '2003-07-15', 135, 521); INSERT INTO rposition VALUES(6834, 1, '2004-08-15', '2004-08-27', 34, 4); INSERT INTO rposition VALUES(9999, 1, '2004-04-30', '2004-06-30', 1036, 1214); INSERT INTO rposition VALUES(9999, 2, '2004-07-01', '2004-07-31', 135, 312); INSERT INTO rposition VALUES(9999, 3, '2004-08-31', '2004-10-01', 843, 145); INSERT INTO rposition VALUES(735, 1, '2003-03-20', '2004-04-20', 392, 233); INSERT INTO rposition VALUES(567, 1, '2003-04-23', '2003-05-07', 522,113); INSERT INTO rposition VALUES(818, 1, '2004-03-24', '2004-03-31', 132, 134); INSERT INTO rposition VALUES(361, 1, '1999-12-23', '2000-01-06', 625, 257); INSERT INTO rposition VALUES(5294, 1, '2002-04-02', '2002-04-16', 428, 111); INSERT INTO rposition VALUES(2732, 1, '1996-08-17', '1996-09-04', 522, 124); INSERT INTO rposition VALUES(2432, 1, '2002-06-15', '2002-07-16', 132, 115); INSERT INTO rposition VALUES(1953, 1, '2004-08-07', '2004-08-15', 392, 513); INSERT INTO rposition VALUES(818, 2, '2004-04-01', '2004-04-12', 843, 732); INSERT INTO rposition VALUES(356, 1, '2004-01-02', '2004-04-22', 522, 113); INSERT INTO rposition VALUES(5646, 1, '2005-03-06', '2005-03-22', 843, 145); INSERT INTO rposition VALUES(6748, 1, '2006-01-01', '2006-01-08', 843, 145); INSERT INTO rposition VALUES(2748, 1, '2004-04-01', '2004-04-08', 392, 233); INSERT INTO rposition VALUES(2349, 1, '2004-07-16', '2004-07-18', 392, 233); INSERT INTO rposition VALUES(4241, 1, '2005-07-16', '2005-07-18', 392, 233); INSERT INTO rposition VALUES(6878, 1, '2006-07-16', '2006-07-18', 392, 233); INSERT INTO zusatz VALUES(735, 1, 84, '2003-03-21', '2004-03-30'); INSERT INTO zusatz VALUES(567, 1, 61, '2003-04-23', '2003-05-07'); INSERT INTO zusatz VALUES(818, 1, 111, '2004-03-24', '2004-03-28'); INSERT INTO zusatz VALUES(361, 1, 142, '1999-12-26', '2000-01-06'); INSERT INTO zusatz VALUES(43358, 1, 154, '2003-05-05', '2003-05-06'); INSERT INTO zusatz VALUES(2732, 1, 47, '1996-08-17', '1996-08-18'); INSERT INTO zusatz VALUES(2432, 1, 123, '2002-06-30', '2002-07-01'); INSERT INTO zusatz VALUES(1953, 1, 178, '2004-08-07', '2004-08-15'); INSERT INTO zusatz VALUES(818, 2, 96, '2004-04-04', '2004-04-11'); INSERT INTO zusatz VALUES(818, 2, 108, '2004-04-03', '2004-04-10'); INSERT INTO zusatz VALUES(818, 2, 111, '2004-04-03', '2004-04-11'); INSERT INTO zusatz VALUES(735, 1, 130, '2003-03-22', '2004-03-29'); INSERT INTO zusatz VALUES(145863, 1, 35, '2003-04-14', '2003-04-19'); INSERT INTO zusatz VALUES(46357, 1, 61, '2004-04-26', '2004-05-07'); INSERT INTO zusatz VALUES(46357, 1, 84, '2004-04-30', '2004-05-03'); INSERT INTO zusatz VALUES(46357, 1, 111, '2004-05-01', '2004-05-03'); INSERT INTO zusatz VALUES(46357, 1, 130, '2004-04-30', '2004-05-02'); INSERT INTO zusatz VALUES(135, 1, 96, '1997-09-19', '1997-09-20'); INSERT INTO zusatz VALUES(135, 1, 108, '1997-09-19', '1997-09-19'); INSERT INTO zusatz VALUES(135, 1, 111, '1997-09-20', '1997-09-20'); INSERT INTO zusatz VALUES(24, 1, 142, '2001-04-16', '2001-04-19'); INSERT INTO zusatz VALUES(24, 3, 178, '2001-08-01', '2001-08-27'); INSERT INTO zusatz VALUES(24, 4, 47, '2001-08-01', '2001-08-27'); INSERT INTO zusatz VALUES(8673, 1, 47, '2003-07-03', '2003-07-05'); INSERT INTO zusatz VALUES(9999, 1, 84, '2004-05-05', '2004-05-05'); INSERT INTO zusatz VALUES(9999, 1, 130, '2004-06-06', '2004-06-07'); INSERT INTO zusatz VALUES(9999, 2, 130, '2004-07-01', '2004-07-31'); INSERT INTO zusatz VALUES(9999, 3, 130, '2004-09-01', '2004-09-30'); INSERT INTO zusatz VALUES(9999, 3, 61, '2004-09-01', '2004-09-30'); INSERT INTO zusatz Values(356, 1, 35, '2004-01-02', '2004-04-22'); INSERT INTO zusatz Values(356, 1, 47, '2004-01-02', '2004-04-22'); Update reservierung set datum=datum+730; Update rposition set von=von+1095, bis=bis+1095; Update zusatz set von=von+1095, bis=bis+1095; ALTER TABLE normal ADD anzahl INTEGER DEFAULT 1; ALTER TABLE zusatz ADD anzahl INTEGER DEFAULT 1; INSERT INTO ausstattung VALUES(46,'Bademantel','5.50'); INSERT INTO ausstattung VALUES(45,'Hausschuhe','2.35'); INSERT INTO ausstattung VALUES(50,'Kinderbett','0.0'); INSERT INTO ausstattung VALUES(51,'Hochstuhl','0.0'); INSERT INTO ausstattung VALUES(52,'Safe','2.45'); INSERT INTO ausstattung VALUES(53,'Heizdecke','16.85'); INSERT INTO ausstattung VALUES(54,'Duftkerzen','12.15'); INSERT INTO ausstattung VALUES(24,'W-LAN Zugang','5.95'); INSERT INTO ausstattung VALUES(25,'DSL-Anschluss','7.69'); INSERT INTO hotel VALUES(736,'Gasthof Sybille','Bad Lippspringe','An der Jordanquelle','1','33188'); INSERT INTO hotel VALUES(758,'Kastens Hotel','Duesseldorf','Lorettostr','5','40219'); INSERT INTO hotel VALUES(761,'Am Glockenturm','Arnsberg','Soesterstr','1','59821'); INSERT INTO zimmer VALUES(34,5,'No5',2,'21.99'); INSERT INTO zimmer VALUES(132,122,'Strecke',2,'60.45'); INSERT INTO zimmer VALUES(135,412,'Rosa Raum',2,'90.35'); INSERT INTO zimmer VALUES(392,414,'Schlafwohl',2,'59.95'); INSERT INTO zimmer VALUES(428,333,'Stollen West',2,'24.99'); INSERT INTO zimmer VALUES(522,135,'Missippi',2,'52.89'); INSERT INTO zimmer VALUES(625,333,'Schoene Aussicht',2,'74.25'); INSERT INTO zimmer VALUES(843,363,'Morgenroete',2,'195.25'); INSERT INTO zimmer VALUES(1036,512,'Angeraue',2,'50.12'); INSERT INTO zimmer VALUES(736,11,'Arminiusquelle',2,'45.40'); INSERT INTO zimmer VALUES(736,12,'Jordanquelle',2,'45.40'); INSERT INTO zimmer VALUES(736,14,'Lippequelle',2,50.50); INSERT INTO zimmer VALUES(758,25,'Rheinturm',2,78.99); INSERT INTO zimmer VALUES(758,26,'Stadttor',2,78.99); INSERT INTO zimmer VALUES(758,27,'Kniebruecke',2,74.99); INSERT INTO zimmer VALUES(761,31,'Schlossberg',2,25.85); INSERT INTO zimmer VALUES(761,32,'Gambrinus',2,19.99); INSERT INTO zimmer VALUES(761,33,'Muffrika',4,48.55); INSERT INTO normal VALUES(34,5,59,2); INSERT INTO normal VALUES(132,122,59,2); INSERT INTO normal VALUES(135,412,59,2); INSERT INTO normal VALUES(392,414,59,2); INSERT INTO normal VALUES(428,333,59,2); INSERT INTO normal VALUES(522,135,59,2); INSERT INTO normal VALUES(625,333,59,2); INSERT INTO normal VALUES(843,363,59,2); INSERT INTO normal VALUES(1036,512,59,2); INSERT INTO normal VALUES(736,11,59,2); INSERT INTO normal VALUES(736,12,59,2); INSERT INTO normal VALUES(736,14,59,2); INSERT INTO normal VALUES(758,25,59,2); INSERT INTO normal VALUES(758,26,59,2); INSERT INTO normal VALUES(758,27,59,2); INSERT INTO normal VALUES(761,31,59,2); INSERT INTO normal VALUES(761,32,59,2); INSERT INTO normal VALUES(761,33,59,4); INSERT INTO normal VALUES(34,5,62,1); INSERT INTO normal VALUES(132,122,62,1); INSERT INTO normal VALUES(135,412,62,1); INSERT INTO normal VALUES(392,414,62,1); INSERT INTO normal VALUES(428,333,62,1); INSERT INTO normal VALUES(522,135,62,1); INSERT INTO normal VALUES(625,333,62,1); INSERT INTO normal VALUES(843,363,62,1); INSERT INTO normal VALUES(1036,512,62,1); INSERT INTO normal VALUES(736,11,53,1); INSERT INTO normal VALUES(736,12,53,1); INSERT INTO normal VALUES(736,14,53,1); INSERT INTO normal VALUES(758,25,142,1); INSERT INTO normal VALUES(758,26,142,1); INSERT INTO normal VALUES(758,27,142,1); INSERT INTO normal VALUES(761,31,178,2); INSERT INTO normal VALUES(761,32,178,2); INSERT INTO normal VALUES(761,33,178,4); INSERT INTO gast VALUES(25,'Binz','Gunnar','Duesseldorf','40549','Heerdter Sandberg','3'); INSERT INTO gast VALUES(26,'Haller','Karl-Heinz','Dortmund','44143','Breierspfad','134'); INSERT INTO gast VALUES(27,'Kloepping','Harald','Bamberg','96058','Eckeystr','15'); INSERT INTO gast VALUES(28,'Schlanstein','Christina','Dillenburg','35683','Carl-Schurz-Str','9'); INSERT INTO gast VALUES(29,'Gauss','Kerstin','Neuss','41453','Badstr','3'); INSERT INTO gast VALUES(30,'Hansen','Irmgard','Bamberg','96023','Neuer Weg','15'); INSERT INTO gast VALUES(31,'Rosenberg','Brigitte','Duisburg','41025','Rahmerstr','168'); INSERT INTO gast VALUES(32,'Lampe','Rosa','Vechta','49377','Schwichtelerstr','14'); INSERT INTO gast VALUES(33,'Mondo','Dolores','Hagen','58093','Dortmunder Str','15a'); INSERT INTO reservierung VALUES(221,'2009-05-15',736,25); INSERT INTO reservierung VALUES(222,'2009-01-11',758,26); INSERT INTO reservierung VALUES(223,'2008-11-05',761,27); INSERT INTO reservierung VALUES(224,'2008-10-03',761,28); INSERT INTO reservierung VALUES(225,'2007-07-18',135,27); INSERT INTO reservierung VALUES(226,'2007-11-06',522,29); INSERT INTO reservierung VALUES(227,'2007-12-13',428,30); INSERT INTO reservierung VALUES(228,'2008-02-15',843,31); INSERT INTO reservierung VALUES(229,'2008-03-25',135,32); INSERT INTO reservierung VALUES(230,'2008-04-13',758,33); INSERT INTO reservierung VALUES(231,'2008-06-07',758,33); INSERT INTO reservierung VALUES(232,'2008-08-13',522,25); INSERT INTO reservierung VALUES(233,'2009-04-13',736,29); INSERT INTO reservierung VALUES(234,'2009-02-26',522,27); INSERT INTO reservierung VALUES(235,'2008-08-13',761,26); INSERT INTO reservierung VALUES(236,'2008-09-30',761,25); INSERT INTO reservierung VALUES(237,'2009-03-11',843,33); INSERT INTO reservierung VALUES(238,'2008-04-13',843,58); INSERT INTO reservierung VALUES(239,'2008-11-11',758,58); INSERT INTO reservierung VALUES(240,'2009-02-03',135,453); INSERT INTO reservierung VALUES(241,'2007-12-28',522,795); INSERT INTO rposition VALUES(221,1,'2009-05-25','2009-06-05',736,11); INSERT INTO rposition VALUES(222,1,'2009-04-15','2009-04-18',736,12); INSERT INTO rposition VALUES(223,1,'2009-01-11','2009-01-18',736,14); INSERT INTO rposition VALUES(223,2,'2009-02-11','2009-02-18',736,11); INSERT INTO rposition VALUES(223,3,'2009-03-11','2009-03-18',736,14); INSERT INTO rposition VALUES(224,1,'2008-11-11','2008-11-15',758,25); INSERT INTO rposition VALUES(225,1,'2007-07-31','2007-08-15',758,26); INSERT INTO rposition VALUES(226,1,'2007-11-11','2007-11-13',758,27); INSERT INTO rposition VALUES(227,1,'2008-01-12','2008-01-15',761,31); INSERT INTO rposition VALUES(228,1,'2008-03-02','2008-03-08',761,32); INSERT INTO rposition VALUES(228,2,'2008-04-02','2008-04-08',761,32); INSERT INTO rposition VALUES(228,3,'2008-05-02','2008-05-08',761,32); INSERT INTO rposition VALUES(229,1,'2008-03-28','2008-04-07',761,33); INSERT INTO rposition VALUES(230,1,'2008-05-02','2008-05-13',132,122); INSERT INTO rposition VALUES(231,1,'2008-07-01','2008-07-05',34,3); INSERT INTO rposition VALUES(231,2,'2008-07-01','2008-07-05',34,4); INSERT INTO rposition VALUES(231,3,'2008-07-01','2008-07-05',34,5); INSERT INTO rposition VALUES(232,1,'2008-09-19','2008-09-21',135,412); INSERT INTO rposition VALUES(233,1,'2009-05-01','2009-05-05',392,414); INSERT INTO rposition VALUES(234,1,'2009-03-01','2009-03-05',428,333); INSERT INTO rposition VALUES(235,1,'2008-09-01','2008-09-05',522,135); INSERT INTO rposition VALUES(236,1,'2008-12-01','2008-12-10',625,333); INSERT INTO rposition VALUES(237,1,'2009-03-18','2009-03-25',843,363); INSERT INTO rposition VALUES(238,1,'2008-07-01','2008-07-05',1036,512); INSERT INTO rposition VALUES(239,1,'2008-11-11','2008-11-15',758,26); INSERT INTO rposition VALUES(240,1,'2009-02-11','2009-02-15',135,412); INSERT INTO rposition VALUES(241,1,'2008-01-02','2008-01-09',522,135); INSERT INTO zusatz VALUES(221,1,50,'2009-05-25','2009-06-05',2); INSERT INTO zusatz VALUES(221,1,51,'2009-05-25','2009-06-05',2); INSERT INTO zusatz VALUES(222,1,53,'2009-04-15','2009-04-18',2); INSERT INTO zusatz VALUES(224,1,53,'2008-11-11','2008-11-15',1); INSERT INTO zusatz VALUES(225,1,52,'2007-07-31','2007-08-15',1); INSERT INTO zusatz VALUES(226,1,52,'2007-11-11','2007-11-13',1); INSERT INTO zusatz VALUES(227,1,52,'2008-01-12','2008-01-15',2); INSERT INTO zusatz VALUES(229,1,45,'2008-03-29','2008-04-07',2); INSERT INTO zusatz VALUES(230,1,45,'2008-05-03','2008-05-13',1); INSERT INTO zusatz VALUES(230,1,46,'2008-05-03','2008-05-13',1); INSERT INTO zusatz VALUES(232,1,54,'2008-09-19','2008-09-21',1); INSERT INTO zusatz VALUES(233,1,24,'2009-05-01','2009-05-05',1); INSERT INTO zusatz VALUES(234,1,25,'2009-03-03','2009-03-05',1); INSERT INTO zusatz VALUES(235,1,142,'2008-09-03','2008-09-04',4); INSERT INTO zusatz VALUES(235,1,154,'2008-09-03','2008-09-04',1); INSERT INTO zusatz VALUES(239,1,84,'2008-11-11','2008-11-15',1); INSERT INTO zusatz VALUES(240,1,111,'2009-02-11','2009-02-15',1);", + }, + { + id: 4, + name: "Ebay, Schema (DML)", + category: categories[0], + templateQuery: + "CREATE TABLE Ebay_Kunde( Knr INTEGER, Nickname VARCHAR(255), Name VARCHAR(255), Vorname VARCHAR(255), Straße VARCHAR(255), Hnr VARCHAR(5), PLZ CHAR(5), Ort VARCHAR(255), KtoNr VARCHAR(10), BLZ VARCHAR(10), Anz_positiv INTEGER, Anz_negativ INTEGER, Gesamtstand INTEGER, CONSTRAINT pk_Kunde PRIMARY KEY (KNr) ); CREATE TABLE Ebay_Kunde_dummie( Knr INTEGER, Nickname VARCHAR(255), Name VARCHAR(255), Vorname VARCHAR(255), Straße VARCHAR(255), Hnr VARCHAR(5), PLZ CHAR(5), Ort VARCHAR(255), KtoNr VARCHAR(10), BLZ VARCHAR(10), Anz_positiv INTEGER, Anz_negativ INTEGER, Gesamtstand INTEGER, CONSTRAINT pk_Ebay_Kunde_dummie PRIMARY KEY (KNr) ); CREATE TABLE Auktionstyp( Atnr INTEGER , Bezeichnung VARCHAR(255), Beschreibung VARCHAR(255), CONSTRAINT pk_Auktionstyp PRIMARY KEY (Atnr) ); CREATE TABLE Kategorie( KatNr INTEGER, Bezeichnung VARCHAR(255), CONSTRAINT pk_Kategorie PRIMARY KEY (KatNr) ); CREATE TABLE Kategorie_dummie( KatNr INTEGER, Bezeichnung VARCHAR(255), CONSTRAINT pk_Kategorie_dummie PRIMARY KEY (KatNr) ); CREATE TABLE Struktur( UKatNr INTEGER, OKatNr INTEGER, CONSTRAINT pk_Struktur PRIMARY KEY (UKatNr), CONSTRAINT fk_Struktur1 FOREIGN KEY (UKatNr) REFERENCES Kategorie (KatNr), CONSTRAINT fk_Struktur2 FOREIGN KEY (OKatNr) REFERENCES Kategorie_dummie (KatNr) ); CREATE TABLE Auktion( AuNr INTEGER, Knr INTEGER, Startpreis NUMERIC(6,2), Beginn DATE, Ende DATE, aktGebot NUMERIC (6,2), Sofortkaufoption BOOLEAN, Sofortkaufpreis NUMERIC(6,2), CONSTRAINT pk_Auktion PRIMARY KEY (AuNr), CONSTRAINT fk_Auktion1 FOREIGN KEY (KNr) REFERENCES Ebay_Kunde (KNr) ); CREATE TABLE Zuordnung( KatNr INTEGER, AuNr INTEGER, CONSTRAINT pk_Zuordung1 PRIMARY KEY (KatNr, AuNr), CONSTRAINT fk_Zuordnung1 FOREIGN KEY (KatNr) REFERENCES Kategorie (KatNr), CONSTRAINT fk_Zuordnung2 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Auktionstypzuordnung( ATNr INTEGER, AuNr INTEGER, CONSTRAINT pk_Auktionstypzuordung PRIMARY KEY (ATNr, AuNr), CONSTRAINT fk_Auktionszuordnung1 FOREIGN KEY (ATNr) REFERENCES Auktionstyp (ATNr), CONSTRAINT fk_Auktionstypzuordnung2 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Aktuell( AuNr INTEGER, CONSTRAINT pk_Aktuell PRIMARY KEY (AuNr), CONSTRAINT fk_Aktuell FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Gebot( GNr INTEGER, Knr INTEGER, AuNr INTEGER, Datum DATE, Zeit TIME, Hoehe NUMERIC (6,2), Sofortkauf BOOLEAN, CONSTRAINT pk_Gebot PRIMARY KEY (GNr), CONSTRAINT fk_Gebot1 FOREIGN KEY (KNr) REFERENCES Ebay_Kunde (KNr), CONSTRAINT fk_Gebot2 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Beobachtung( AuNr INTEGER, KNr INTEGER, CONSTRAINT pk_Beobachtung PRIMARY KEY (AuNr, KNr), CONSTRAINT fk_Beobachtung1 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr), CONSTRAINT fk_Beobachtungg2 FOREIGN KEY (KNr) REFERENCES Ebay_Kunde (KNr) ); CREATE TABLE Abschluss( GNR INTEGER, Preis NUMERIC (6,2), CONSTRAINT pk_Abschluss PRIMARY KEY (GNr), CONSTRAINT fk_Abschluss1 FOREIGN KEY (GNr) REFERENCES Gebot (GNr) ); CREATE TABLE Kommentar_Bewertung( GNr INTEGER, VonKNr INTEGER, AnKNr INTEGER, Kommentar VARCHAR(255), Erwiderung VARCHAR(255), Kommentar2 VARCHAR(255), Bewertungsart VARCHAR(255), CONSTRAINT pk_Kommentar_Bewertung PRIMARY KEY (GNr, vonKNr), CONSTRAINT fk_Kommentar_Bewertung1 FOREIGN KEY (GNr) REFERENCES Gebot (GNr), CONSTRAINT fk_Kommentar_Bewertung2 FOREIGN KEY (VonKNr) REFERENCES Ebay_Kunde (KNr), CONSTRAINT fk_Kommentar_Bewertung3 FOREIGN KEY (AnKNr) REFERENCES Ebay_Kunde_dummie (KNr) );", + }, + { + id: 5, + name: "Ebay, Daten (DDL)", + category: categories[0], + templateQuery: + "INSERT INTO Ebay_Kunde VALUES(100000, 'brocklesnar', 'Müller', 'Frank', 'Königsalle', '347a', '44795', 'Bochum', '185453942', '40060119', 2, 0, 100); INSERT INTO Ebay_Kunde VALUES(100001, 'supermoppelchen', 'Mayer', 'Max', 'Universiätsstraße', '99', '44221', 'Dortmund', '294153942', '50098763', 2, 0, 100); INSERT INTO Ebay_Kunde VALUES(100002, 'jandel', 'Schröder', 'Tim', 'Königswall', '108', '44164', 'Dortmund', '194359154', '35968716', 1, 1, 50); INSERT INTO Ebay_Kunde VALUES(100003, 'vossen', 'Weber', 'Franz', 'Leopoldstraße', '34', '80264', 'München', '468125987', '24868712', 0, 2, 0); INSERT INTO Ebay_Kunde VALUES(100004, 'steinmann', 'Kaufmann', 'Annabelle', 'Sonnenstraße', '12', '23957', 'Hamburg', '168945035', '12468725', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100005, 'roadrunner', 'Schulze', 'Anna-Maria', 'Lilienallee', '3', '10555', 'Berlin', '184695354', '40069722', 0, 1, 0); INSERT INTO Ebay_Kunde VALUES(100006, 'pittkuss', 'Schäfer', 'Simone', 'Burgstraße', '47', '30678', 'Hannover', '298648148', '30057458', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100007, 'masterflash', 'Franken', 'Stefanie', 'Mauerstraße', '58', '69122', 'Heidelberg', '397125984', '21485367', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100008, 'meikelex', 'Mustermann', 'Chris', 'Lüner Hellweg', '23', '06199', 'Halle', '195698456', '40298568', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100009, 'hobbyzuechter', 'Krämer', 'Thomas', 'Baroper Weg', '11', '62333', 'Frankfurt', '123987654', '46865215', 0, 1, 0); INSERT INTO Ebay_Kunde VALUES(100010, 'maurimirko', 'Schneider', 'Bettina', 'Zepelinstraße', '80', '51698', 'Köln', '198597364', '56661166', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100011, 'thorn', 'Schulz', 'Marc', 'Kaufingerstraße', '258', '89321', 'Ulm', '284697248', '20156986', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100012, 'timslaedle', 'Thomalla', 'Heinz', 'Landgrafenallee', '54', '97011', 'Würzburg', '365795148', '24465139', 0, 1, 0); INSERT INTO Ebay_Kunde VALUES(100013, 'virgenierot', 'Hoffmann', 'Erika', 'Hauptstraße', '80', '97877', 'Wertheim', '134598264', '34436915', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100014, 'kehrtag', 'Fischer', 'Franziska', 'Schloßalle', '65', '40359', 'Düsseldorf', '123456789', '12268820', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100015, 'homie', 'Neumann', 'Martin', 'Badstraße', '1c', '47555', 'Krefeld', '132198567', '45698723', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100000, 'brocklesnar', 'Müller', 'Frank', 'Königsalle', '347a', '44795', 'Bochum', '185453942', '40060119', 2, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100001, 'supermoppelchen', 'Mayer', 'Max', 'Universiätsstraße', '99', '44221', 'Dortmund', '294153942', '50098763', 2, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100002, 'jandel', 'Schröder', 'Tim', 'Königswall', '108', '44164', 'Dortmund', '194359154', '35968716', 1, 1, 50); INSERT INTO Ebay_Kunde_Dummie VALUES(100003, 'vossen', 'Weber', 'Franz', 'Leopoldstraße', '34', '80264', 'München', '468125987', '24868712', 0, 2, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100004, 'steinmann', 'Kaufmann', 'Annabelle', 'Sonnenstraße', '12', '23957', 'Hamburg', '168945035', '12468725', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100005, 'roadrunner', 'Schulze', 'Anna-Maria', 'Lilienallee', '3', '10555', 'Berlin', '184695354', '40069722', 0, 1, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100006, 'pittkuss', 'Schäfer', 'Simone', 'Burgstraße', '47', '30678', 'Hannover', '298648148', '30057458', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100007, 'masterflash', 'Franken', 'Stefanie', 'Mauerstraße', '58', '69122', 'Heidelberg', '397125984', '21485367', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100008, 'meikelex', 'Mustermann', 'Chris', 'Lüner Hellweg', '23', '06199', 'Halle', '195698456', '40298568', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100009, 'hobbyzuechter', 'Krämer', 'Thomas', 'Baroper Weg', '11', '62333', 'Frankfurt', '123987654', '46865215', 0, 1, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100010, 'maurimirko', 'Schneider', 'Bettina', 'Zepelinstraße', '80', '51698', 'Köln', '198597364', '56661166', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100011, 'thorn', 'Schulz', 'Marc', 'Kaufingerstraße', '258', '89321', 'Ulm', '284697248', '20156986', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100012, 'timslaedle', 'Thomalla', 'Heinz', 'Landgrafenallee', '54', '97011', 'Würzburg', '365795148', '24465139', 0, 1, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100013, 'virgenierot', 'Hoffmann', 'Erika', 'Hauptstraße', '80', '97877', 'Wertheim', '134598264', '34436915', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100014, 'kehrtag', 'Fischer', 'Franziska', 'Schloßalle', '65', '40359', 'Düsseldorf', '123456789', '12268820', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100015, 'homie', 'Neumann', 'Martin', 'Badstraße', '1c', '47555', 'Krefeld', '132198567', '45698723', 0, 0, 0); INSERT INTO Auktionstyp VALUES (1, 'SofortKaufen', 'Wenn Sie neben einem Angebot das Symbol SofortKaufen sehen, können Sie diesen Artikel sofort zu einem Festpreis kaufen.'); INSERT INTO Auktionstyp VALUES (2, 'Sofort&Neu', 'Wenn Sie neben einem Angebot das Symbol Sofort&Neu sehen, können Sie diesen Artikel sofort zu einem Festpreis kaufen.'); INSERT INTO Auktionstyp VALUES (3, 'Gebot', 'Innerhalb der Auktionsdauer kann eine Gebotsabgabe für einen Artikel abgegeben werden.'); INSERT INTO Kategorie VALUES (1, 'Audio & Hifi'); INSERT INTO Kategorie VALUES (2, 'CD Player'); INSERT INTO Kategorie VALUES (3, 'DJ Equipment'); INSERT INTO Kategorie VALUES (4, 'MP3 Player'); INSERT INTO Kategorie VALUES (5, 'Verstärker'); INSERT INTO Kategorie VALUES (6, 'Zubehör'); INSERT INTO Kategorie VALUES (7, 'Bücher'); INSERT INTO Kategorie VALUES (8, 'Belletristik'); INSERT INTO Kategorie VALUES (9, 'Kinder - & Jugendbücher'); INSERT INTO Kategorie VALUES (10, 'Sachbücher & Ratgeber'); INSERT INTO Kategorie VALUES (11, 'Schule & Ausbildung'); INSERT INTO Kategorie VALUES (12, 'Englischsprachige Bücher'); INSERT INTO Kategorie VALUES (13, 'Musik'); INSERT INTO Kategorie VALUES (14, 'CDs'); INSERT INTO Kategorie VALUES (15, 'Vinyl'); INSERT INTO Kategorie VALUES (16, 'Zubehör & Aufbewahrung'); INSERT INTO Kategorie VALUES (17, 'Hörbücher & Hörspiele'); INSERT INTO Kategorie VALUES (18, 'Fanartikel & Merchandise'); INSERT INTO Kategorie VALUES (19, 'Sport'); INSERT INTO Kategorie VALUES (20, 'Fubball'); INSERT INTO Kategorie VALUES (21, 'Camping & Outdoor'); INSERT INTO Kategorie VALUES (22, 'Inlineskating'); INSERT INTO Kategorie VALUES (23, 'Skisport'); INSERT INTO Kategorie VALUES (24, 'Bootsport'); INSERT INTO Kategorie VALUES (25, 'Tv, Video & Elektronik'); INSERT INTO Kategorie VALUES (26, 'Blu-Ray-Player'); INSERT INTO Kategorie VALUES (27, 'DVD-Player'); INSERT INTO Kategorie VALUES (28, 'Fernseher'); INSERT INTO Kategorie VALUES (29, 'GPS'); INSERT INTO Kategorie VALUES (30, 'Leinwände'); INSERT INTO Kategorie_Dummie VALUES (1, 'Audio & Hifi'); INSERT INTO Kategorie_Dummie VALUES (2, 'CD Player'); INSERT INTO Kategorie_Dummie VALUES (3, 'DJ Equipment'); INSERT INTO Kategorie_Dummie VALUES (4, 'MP3 Player'); INSERT INTO Kategorie_Dummie VALUES (5, 'Verstärker'); INSERT INTO Kategorie_Dummie VALUES (6, 'Zubehör'); INSERT INTO Kategorie_Dummie VALUES (7, 'Bücher'); INSERT INTO Kategorie_Dummie VALUES (8, 'Belletristik'); INSERT INTO Kategorie_Dummie VALUES (9, 'Kinder - & Jugendbücher'); INSERT INTO Kategorie_Dummie VALUES (10, 'Sachbücher & Ratgeber'); INSERT INTO Kategorie_Dummie VALUES (11, 'Schule & Ausbildung'); INSERT INTO Kategorie_Dummie VALUES (12, 'Englischsprachige Bücher'); INSERT INTO Kategorie_Dummie VALUES (13, 'Musik'); INSERT INTO Kategorie_Dummie VALUES (14, 'CDs'); INSERT INTO Kategorie_Dummie VALUES (15, 'Vinyl'); INSERT INTO Kategorie_Dummie VALUES (16, 'Zubehör & Aufbewahrung'); INSERT INTO Kategorie_Dummie VALUES (17, 'Hörbücher & Hörspiele'); INSERT INTO Kategorie_Dummie VALUES (18, 'Fanartikel & Merchandise'); INSERT INTO Kategorie_Dummie VALUES (19, 'Sport'); INSERT INTO Kategorie_Dummie VALUES (20, 'Fubball'); INSERT INTO Kategorie_Dummie VALUES (21, 'Camping & Outdoor'); INSERT INTO Kategorie_Dummie VALUES (22, 'Inlineskating'); INSERT INTO Kategorie_Dummie VALUES (23, 'Skisport'); INSERT INTO Kategorie_Dummie VALUES (24, 'Bootsport'); INSERT INTO Kategorie_Dummie VALUES (25, 'Tv, Video & Elektronik'); INSERT INTO Kategorie_Dummie VALUES (26, 'Blu-Ray-Player'); INSERT INTO Kategorie_Dummie VALUES (27, 'DVD-Player'); INSERT INTO Kategorie_Dummie VALUES (28, 'Fernseher'); INSERT INTO Kategorie_Dummie VALUES (29, 'GPS'); INSERT INTO Kategorie_Dummie VALUES (30, 'Leinwände'); INSERT INTO Struktur VALUES (2, 1); INSERT INTO Struktur VALUES (3, 1); INSERT INTO Struktur VALUES (4, 1); INSERT INTO Struktur VALUES (5, 1); INSERT INTO Struktur VALUES (6, 1); INSERT INTO Struktur VALUES (8, 7); INSERT INTO Struktur VALUES (9, 7); INSERT INTO Struktur VALUES (10, 7); INSERT INTO Struktur VALUES (11, 7); INSERT INTO Struktur VALUES (12, 7); INSERT INTO Struktur VALUES (14, 11); INSERT INTO Struktur VALUES (15, 11); INSERT INTO Struktur VALUES (16, 11); INSERT INTO Struktur VALUES (17, 11); INSERT INTO Struktur VALUES (18, 11); INSERT INTO Struktur VALUES (20, 19); INSERT INTO Struktur VALUES (21, 19); INSERT INTO Struktur VALUES (22, 19); INSERT INTO Struktur VALUES (23, 19); INSERT INTO Struktur VALUES (24, 19); INSERT INTO Struktur VALUES (26, 25); INSERT INTO Struktur VALUES (27, 25); INSERT INTO Struktur VALUES (28, 25); INSERT INTO Struktur VALUES (29, 25); INSERT INTO Struktur VALUES (30, 25); INSERT INTO Auktion VALUES (1, 100000, 1.00, '20070101', '20070501', 6.00, true, 6.00); INSERT INTO Auktion VALUES (2, 100001, 1.50, '20070101', '20070501', 3.00, false, 6.50); INSERT INTO Auktion VALUES (3, 100002, 2.00, '20070301', '20070901', 7.00, true, 7.00); INSERT INTO Auktion VALUES (4, 100003, 3.50, '20070301', '20070901', 3.50, false, 8.50); INSERT INTO Auktion VALUES (5, 100000, 6.00, '20070301', '20070901', 11.00, true, 11.00); INSERT INTO Auktion VALUES (6, 100001, 9.99, '20070501', '20080301', 9.99, false, 14.99); INSERT INTO Auktion VALUES (7, 100002, 10.00, '20070501', '20080401', 15.00, true, 15.00); INSERT INTO Auktion VALUES (8, 100003, 15.00, '20070901', '20080501', 0.00, false, 22.50); INSERT INTO Auktion VALUES (9, 100005, 20.00, '20070901', '20080101', 0.00, true, 30.00); INSERT INTO Auktion VALUES (10, 100006, 40.00, '20070901', '20080201', 40.00, false, 60.00); INSERT INTO Auktion VALUES (11, 100007, 100.00, '20070901', '20080301', 150.00, true, 150.00); INSERT INTO Auktion VALUES (12, 100008, 250.00, '20070901', '20080401', 275.00, false, 375.00); INSERT INTO Auktion VALUES (13, 100009, 500.00, '20070901', '20080501', 750.00, true, 750.00); INSERT INTO Auktion VALUES (14, 100010, 5.00, '20070901', '20080601', 5.00, false, 7.50); INSERT INTO Auktion VALUES (15, 100011, 4.00, '20070901', '20080701', 0.00, true, 6.00); INSERT INTO Auktion VALUES (16, 100012, 50.00, '20070901', '20080801', 55.00, false, 75.00); INSERT INTO Auktion VALUES (17, 100013, 24.99, '20070901', '20080901', 0.00, true, 37.49); INSERT INTO Auktion VALUES (18, 100014, 99.99, '20080301', '20080901', 99.99, false, 149.99); INSERT INTO Auktion VALUES (19, 100003, 1.00, '20080401', '20080901', 1.50, true, 1.50); INSERT INTO Auktion VALUES (20, 100005, 35.00, '20080501', '20080901', 35.00, false, 52.50); INSERT INTO Auktion VALUES (21, 100006, 25.00, '20080901', '20080901', 37.50, true, 37.50); INSERT INTO Gebot VALUES (100, 100000, 1, '20070101', '00:00', 6.00, true); INSERT INTO Gebot VALUES (101, 100001, 2, '20070201', '01:00', 1.50, false); INSERT INTO Gebot VALUES (102, 100002, 3, '20070301', '02:00', 7.00, true); INSERT INTO Gebot VALUES (103, 100003, 4, '20070401', '03:00', 3.50, false); INSERT INTO Gebot VALUES (104, 100004, 5, '20070501', '04:00', 11.00, true); INSERT INTO Gebot VALUES (105, 100005, 6, '20070601', '05:00', 9.99, false); INSERT INTO Gebot VALUES (106, 100006, 7, '20070701', '06:00', 15.00, true); INSERT INTO Gebot VALUES (107, 100007, 2, '20070801', '07:00', 2, false); INSERT INTO Gebot VALUES (108, 100008, 2, '20070901', '08:00', 3, false); INSERT INTO Gebot VALUES (109, 100009, 10, '20071001', '09:00', 40.00, false); INSERT INTO Gebot VALUES (110, 100010, 11, '20071101', '10:00', 150.00, true); INSERT INTO Gebot VALUES (111, 100011, 12, '20071201', '11:00', 250.00, false); INSERT INTO Gebot VALUES (112, 100012, 13, '20080101', '12:00', 750.00, true); INSERT INTO Gebot VALUES (113, 100013, 14, '20080201', '13:00', 5.00, false); INSERT INTO Gebot VALUES (114, 100014, 12, '20080301', '14:00', 275, false); INSERT INTO Gebot VALUES (115, 100015, 16, '20080401', '15:00', 50, false); INSERT INTO Gebot VALUES (116, 100007, 16, '20080501', '16:00', 55, false); INSERT INTO Gebot VALUES (117, 100008, 18, '20080601', '17:00', 99.99, false); INSERT INTO Gebot VALUES (118, 100009, 19, '20080701', '18:00', 1.50, true); INSERT INTO Gebot VALUES (119, 100010, 20, '20080801', '19:00', 35.00, false); INSERT INTO Gebot VALUES (120, 100011, 21, '20080901', '20:00', 37.50, true); INSERT INTO Abschluss VALUES (100, 6.00); INSERT INTO Abschluss VALUES (102, 7.00); INSERT INTO Abschluss VALUES (103, 3.50); INSERT INTO Abschluss VALUES (104, 11.00); INSERT INTO Abschluss VALUES (105, 9.99); INSERT INTO Abschluss VALUES (106, 15.00); INSERT INTO Abschluss VALUES (108, 3); INSERT INTO Abschluss VALUES (109, 40.00); INSERT INTO Abschluss VALUES (110, 150.00); INSERT INTO Abschluss VALUES (112, 750.00); INSERT INTO Abschluss VALUES (113, 5.00); INSERT INTO Abschluss VALUES (114, 275); INSERT INTO Abschluss VALUES (116, 55); INSERT INTO Abschluss VALUES (117, 99.99); INSERT INTO Abschluss VALUES (118, 1.50); INSERT INTO Abschluss VALUES (119, 35.00); INSERT INTO Abschluss VALUES (120, 37.50); INSERT INTO Kommentar_Bewertung VALUES (100, 100011, 100000, 'Ware wie beschrieben . Versand schnell . Topp Ebayer', 'Danke', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (102, 100001, 100002, 'Super Ware!!! Immer Gerne!!!!', 'Viele Dank', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (103, 100002, 100003, 'Gibt 6,90 DHL Paket an und versendet als 3,90 Päckchen. Abzocke. Pfui. NEGATIV', '', '', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (104, 100003, 100000, 'Alles Bestens ,sehr netter ebayer', 'Sehr vielen Dank, für diese postive Bewertung', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (105, 100004, 100001, 'Übergabe gut gelaufen!', '', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (106, 100005, 100002, 'Negativ-Negativ-', 'Tolle Bewertung, gibts auch einen konkreten Grund?', '', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (108, 100007, 100001, 'sehr netter kontakt, bestens gelaufen', 'Wie darf ich denn den ersten Teil des Kommentars verstehen?', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (109, 100008, 100006, 'kam 1a+ an, gebrauchsspuren wie beschrieben', 'Soll das nun eine Kritik über Raucher sein?', '', 'neutral'); INSERT INTO Kommentar_Bewertung VALUES (110, 100009, 100007, 'turboschneller Versand!TOP Qualität!!Vielen Dank!!', 'Fantastisch, danke', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (112, 100011, 100009, 'Übt nach Auktionsende ungebührlichen Druck aus. Sehr fragwürdiges Auftreten.', 'KOMISCHER MENSCH,ERST KEINE BEWERTUNG, ABGEBEN,WENN MANN NACHFRAGT DANN SOWAS', 'Die Art der Frage macht einiges aus', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (113, 100012, 100010, 'Nicht ganz so guter Zustand ansonsten alles OK', 'BITTE DAS NÄCHSTE MAL ARTIKELBESCHREIBUNG GENAUER LESEN', 'Beschreibung war sehr interpretierbar', 'neutral'); INSERT INTO Kommentar_Bewertung VALUES (114, 100013, 100008, 'x', 'WAS IST DAS FÜR EINE BEWERTUNG??????', 'in meinen Kreisen bedeutet das auch :Alles super', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (116, 100015, 100012, 'Größenauszeichnung stimmt nicht', '', '', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (117, 100007, 100014, 'sehr schnell, alles gut,auch wenns eine nicht angegebene kleine macke gibt ;)', 'Muss dann wohl auf dem Postweg passiert sein - Sorry', 'War ja weiter auch nicht schlimm', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (118, 100008, 100003, 'Ware ok, Verpackung sehr schlecht', 'Als ich es losgeschickt habe, war die Verpackug noch in Ordnung', 'Das kann nicht alles auf dem Postweg passeiert sein, ich würde sagen eher am Verpackungsmaterial gespart', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (119, 100009, 100005, 'extrem unachtsame Ausdrucksweise/trotz Zahlung doppelter Beschwerde/Tipp:Yoga', 'Käufer hat die Ware erst nach Beschwerde u. 6 Wo. nach Kauf bezahlt. Frechheit!', 'Ich musste es halt erst testen bevor ich es bezahle, ganz ruhig', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (120, 100010, 100006, '!!! PERFEKT !!! Note 1a', 'Supi, thanks', '', 'positiv'); INSERT INTO Zuordnung VALUES (2, 1); INSERT INTO Zuordnung VALUES (3, 2); INSERT INTO Zuordnung VALUES (4, 3); INSERT INTO Zuordnung VALUES (5, 4); INSERT INTO Zuordnung VALUES (6, 5); INSERT INTO Zuordnung VALUES (8, 6); INSERT INTO Zuordnung VALUES (9, 7); INSERT INTO Zuordnung VALUES (10, 8); INSERT INTO Zuordnung VALUES (11, 9); INSERT INTO Zuordnung VALUES (12, 10); INSERT INTO Zuordnung VALUES (14, 11); INSERT INTO Zuordnung VALUES (15, 12); INSERT INTO Zuordnung VALUES (16, 13); INSERT INTO Zuordnung VALUES (17, 14); INSERT INTO Zuordnung VALUES (18, 15); INSERT INTO Zuordnung VALUES (20, 16); INSERT INTO Zuordnung VALUES (21, 17); INSERT INTO Zuordnung VALUES (22, 18); INSERT INTO Zuordnung VALUES (23, 19); INSERT INTO Zuordnung VALUES (24, 20); INSERT INTO Zuordnung VALUES (26, 21); INSERT INTO Auktionstypzuordnung VALUES (1, 1); INSERT INTO Auktionstypzuordnung VALUES (2, 2); INSERT INTO Auktionstypzuordnung VALUES (3, 3); INSERT INTO Auktionstypzuordnung VALUES (3, 4); INSERT INTO Auktionstypzuordnung VALUES (3, 5); INSERT INTO Auktionstypzuordnung VALUES (3, 6); INSERT INTO Auktionstypzuordnung VALUES (3, 7); INSERT INTO Auktionstypzuordnung VALUES (1, 8); INSERT INTO Auktionstypzuordnung VALUES (1, 9); INSERT INTO Auktionstypzuordnung VALUES (2, 10); INSERT INTO Auktionstypzuordnung VALUES (2, 11); INSERT INTO Auktionstypzuordnung VALUES (2, 12); INSERT INTO Auktionstypzuordnung VALUES (2, 13); INSERT INTO Auktionstypzuordnung VALUES (3, 14); INSERT INTO Auktionstypzuordnung VALUES (3, 15); INSERT INTO Auktionstypzuordnung VALUES (3, 16); INSERT INTO Auktionstypzuordnung VALUES (3, 17); INSERT INTO Auktionstypzuordnung VALUES (3, 18); INSERT INTO Auktionstypzuordnung VALUES (2, 19); INSERT INTO Auktionstypzuordnung VALUES (1, 20); INSERT INTO Auktionstypzuordnung VALUES (1, 21); INSERT INTO Beobachtung VALUES (1, 100011); INSERT INTO Beobachtung VALUES (2, 100000); INSERT INTO Beobachtung VALUES (3, 100001); INSERT INTO Beobachtung VALUES (4, 100002); INSERT INTO Beobachtung VALUES (5, 100003); INSERT INTO Beobachtung VALUES (6, 100004); INSERT INTO Beobachtung VALUES (7, 100005); INSERT INTO Beobachtung VALUES (2, 100006); INSERT INTO Beobachtung VALUES (2, 100007); INSERT INTO Beobachtung VALUES (10, 100008); INSERT INTO Beobachtung VALUES (11, 100009); INSERT INTO Beobachtung VALUES (12, 100010); INSERT INTO Beobachtung VALUES (13, 100011); INSERT INTO Beobachtung VALUES (14, 100012); INSERT INTO Beobachtung VALUES (12, 100013); INSERT INTO Beobachtung VALUES (16, 100014); INSERT INTO Beobachtung VALUES (16, 100015); INSERT INTO Beobachtung VALUES (18, 100007); INSERT INTO Beobachtung VALUES (19, 100008); INSERT INTO Beobachtung VALUES (20, 100009); INSERT INTO Beobachtung VALUES (21, 100010); INSERT INTO Beobachtung VALUES (10, 100002); INSERT INTO Beobachtung VALUES (4, 100014); INSERT INTO Beobachtung VALUES (8, 100011); INSERT INTO Aktuell VALUES (8); INSERT INTO Aktuell VALUES (9); INSERT INTO Aktuell VALUES (10); INSERT INTO Aktuell VALUES (11); INSERT INTO Aktuell VALUES (12); INSERT INTO Aktuell VALUES (13); INSERT INTO Aktuell VALUES (14); INSERT INTO Aktuell VALUES (15); INSERT INTO Aktuell VALUES (16); INSERT INTO Aktuell VALUES (17); INSERT INTO Aktuell VALUES (18); INSERT INTO Aktuell VALUES (19); INSERT INTO Aktuell VALUES (20); INSERT INTO Aktuell VALUES (21);", + }, + { + id: 6, + name: "Ebay, Schema + Daten", + category: categories[0], + templateQuery: + "CREATE TABLE Ebay_Kunde( Knr INTEGER, Nickname VARCHAR(255), Name VARCHAR(255), Vorname VARCHAR(255), Straße VARCHAR(255), Hnr VARCHAR(5), PLZ CHAR(5), Ort VARCHAR(255), KtoNr VARCHAR(10), BLZ VARCHAR(10), Anz_positiv INTEGER, Anz_negativ INTEGER, Gesamtstand INTEGER, CONSTRAINT pk_Kunde PRIMARY KEY (KNr) ); CREATE TABLE Ebay_Kunde_dummie( Knr INTEGER, Nickname VARCHAR(255), Name VARCHAR(255), Vorname VARCHAR(255), Straße VARCHAR(255), Hnr VARCHAR(5), PLZ CHAR(5), Ort VARCHAR(255), KtoNr VARCHAR(10), BLZ VARCHAR(10), Anz_positiv INTEGER, Anz_negativ INTEGER, Gesamtstand INTEGER, CONSTRAINT pk_Ebay_Kunde_dummie PRIMARY KEY (KNr) ); CREATE TABLE Auktionstyp( Atnr INTEGER , Bezeichnung VARCHAR(255), Beschreibung VARCHAR(255), CONSTRAINT pk_Auktionstyp PRIMARY KEY (Atnr) ); CREATE TABLE Kategorie( KatNr INTEGER, Bezeichnung VARCHAR(255), CONSTRAINT pk_Kategorie PRIMARY KEY (KatNr) ); CREATE TABLE Kategorie_dummie( KatNr INTEGER, Bezeichnung VARCHAR(255), CONSTRAINT pk_Kategorie_dummie PRIMARY KEY (KatNr) ); CREATE TABLE Struktur( UKatNr INTEGER, OKatNr INTEGER, CONSTRAINT pk_Struktur PRIMARY KEY (UKatNr), CONSTRAINT fk_Struktur1 FOREIGN KEY (UKatNr) REFERENCES Kategorie (KatNr), CONSTRAINT fk_Struktur2 FOREIGN KEY (OKatNr) REFERENCES Kategorie_dummie (KatNr) ); CREATE TABLE Auktion( AuNr INTEGER, Knr INTEGER, Startpreis NUMERIC(6,2), Beginn DATE, Ende DATE, aktGebot NUMERIC (6,2), Sofortkaufoption BOOLEAN, Sofortkaufpreis NUMERIC(6,2), CONSTRAINT pk_Auktion PRIMARY KEY (AuNr), CONSTRAINT fk_Auktion1 FOREIGN KEY (KNr) REFERENCES Ebay_Kunde (KNr) ); CREATE TABLE Zuordnung( KatNr INTEGER, AuNr INTEGER, CONSTRAINT pk_Zuordung1 PRIMARY KEY (KatNr, AuNr), CONSTRAINT fk_Zuordnung1 FOREIGN KEY (KatNr) REFERENCES Kategorie (KatNr), CONSTRAINT fk_Zuordnung2 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Auktionstypzuordnung( ATNr INTEGER, AuNr INTEGER, CONSTRAINT pk_Auktionstypzuordung PRIMARY KEY (ATNr, AuNr), CONSTRAINT fk_Auktionszuordnung1 FOREIGN KEY (ATNr) REFERENCES Auktionstyp (ATNr), CONSTRAINT fk_Auktionstypzuordnung2 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Aktuell( AuNr INTEGER, CONSTRAINT pk_Aktuell PRIMARY KEY (AuNr), CONSTRAINT fk_Aktuell FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Gebot( GNr INTEGER, Knr INTEGER, AuNr INTEGER, Datum DATE, Zeit TIME, Hoehe NUMERIC (6,2), Sofortkauf BOOLEAN, CONSTRAINT pk_Gebot PRIMARY KEY (GNr), CONSTRAINT fk_Gebot1 FOREIGN KEY (KNr) REFERENCES Ebay_Kunde (KNr), CONSTRAINT fk_Gebot2 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr) ); CREATE TABLE Beobachtung( AuNr INTEGER, KNr INTEGER, CONSTRAINT pk_Beobachtung PRIMARY KEY (AuNr, KNr), CONSTRAINT fk_Beobachtung1 FOREIGN KEY (AuNr) REFERENCES Auktion (AuNr), CONSTRAINT fk_Beobachtungg2 FOREIGN KEY (KNr) REFERENCES Ebay_Kunde (KNr) ); CREATE TABLE Abschluss( GNR INTEGER, Preis NUMERIC (6,2), CONSTRAINT pk_Abschluss PRIMARY KEY (GNr), CONSTRAINT fk_Abschluss1 FOREIGN KEY (GNr) REFERENCES Gebot (GNr) ); CREATE TABLE Kommentar_Bewertung( GNr INTEGER, VonKNr INTEGER, AnKNr INTEGER, Kommentar VARCHAR(255), Erwiderung VARCHAR(255), Kommentar2 VARCHAR(255), Bewertungsart VARCHAR(255), CONSTRAINT pk_Kommentar_Bewertung PRIMARY KEY (GNr, vonKNr), CONSTRAINT fk_Kommentar_Bewertung1 FOREIGN KEY (GNr) REFERENCES Gebot (GNr), CONSTRAINT fk_Kommentar_Bewertung2 FOREIGN KEY (VonKNr) REFERENCES Ebay_Kunde (KNr), CONSTRAINT fk_Kommentar_Bewertung3 FOREIGN KEY (AnKNr) REFERENCES Ebay_Kunde_dummie (KNr) ); INSERT INTO Ebay_Kunde VALUES(100000, 'brocklesnar', 'Müller', 'Frank', 'Königsalle', '347a', '44795', 'Bochum', '185453942', '40060119', 2, 0, 100); INSERT INTO Ebay_Kunde VALUES(100001, 'supermoppelchen', 'Mayer', 'Max', 'Universiätsstraße', '99', '44221', 'Dortmund', '294153942', '50098763', 2, 0, 100); INSERT INTO Ebay_Kunde VALUES(100002, 'jandel', 'Schröder', 'Tim', 'Königswall', '108', '44164', 'Dortmund', '194359154', '35968716', 1, 1, 50); INSERT INTO Ebay_Kunde VALUES(100003, 'vossen', 'Weber', 'Franz', 'Leopoldstraße', '34', '80264', 'München', '468125987', '24868712', 0, 2, 0); INSERT INTO Ebay_Kunde VALUES(100004, 'steinmann', 'Kaufmann', 'Annabelle', 'Sonnenstraße', '12', '23957', 'Hamburg', '168945035', '12468725', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100005, 'roadrunner', 'Schulze', 'Anna-Maria', 'Lilienallee', '3', '10555', 'Berlin', '184695354', '40069722', 0, 1, 0); INSERT INTO Ebay_Kunde VALUES(100006, 'pittkuss', 'Schäfer', 'Simone', 'Burgstraße', '47', '30678', 'Hannover', '298648148', '30057458', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100007, 'masterflash', 'Franken', 'Stefanie', 'Mauerstraße', '58', '69122', 'Heidelberg', '397125984', '21485367', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100008, 'meikelex', 'Mustermann', 'Chris', 'Lüner Hellweg', '23', '06199', 'Halle', '195698456', '40298568', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100009, 'hobbyzuechter', 'Krämer', 'Thomas', 'Baroper Weg', '11', '62333', 'Frankfurt', '123987654', '46865215', 0, 1, 0); INSERT INTO Ebay_Kunde VALUES(100010, 'maurimirko', 'Schneider', 'Bettina', 'Zepelinstraße', '80', '51698', 'Köln', '198597364', '56661166', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100011, 'thorn', 'Schulz', 'Marc', 'Kaufingerstraße', '258', '89321', 'Ulm', '284697248', '20156986', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100012, 'timslaedle', 'Thomalla', 'Heinz', 'Landgrafenallee', '54', '97011', 'Würzburg', '365795148', '24465139', 0, 1, 0); INSERT INTO Ebay_Kunde VALUES(100013, 'virgenierot', 'Hoffmann', 'Erika', 'Hauptstraße', '80', '97877', 'Wertheim', '134598264', '34436915', 0, 0, 0); INSERT INTO Ebay_Kunde VALUES(100014, 'kehrtag', 'Fischer', 'Franziska', 'Schloßalle', '65', '40359', 'Düsseldorf', '123456789', '12268820', 1, 0, 100); INSERT INTO Ebay_Kunde VALUES(100015, 'homie', 'Neumann', 'Martin', 'Badstraße', '1c', '47555', 'Krefeld', '132198567', '45698723', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100000, 'brocklesnar', 'Müller', 'Frank', 'Königsalle', '347a', '44795', 'Bochum', '185453942', '40060119', 2, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100001, 'supermoppelchen', 'Mayer', 'Max', 'Universiätsstraße', '99', '44221', 'Dortmund', '294153942', '50098763', 2, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100002, 'jandel', 'Schröder', 'Tim', 'Königswall', '108', '44164', 'Dortmund', '194359154', '35968716', 1, 1, 50); INSERT INTO Ebay_Kunde_Dummie VALUES(100003, 'vossen', 'Weber', 'Franz', 'Leopoldstraße', '34', '80264', 'München', '468125987', '24868712', 0, 2, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100004, 'steinmann', 'Kaufmann', 'Annabelle', 'Sonnenstraße', '12', '23957', 'Hamburg', '168945035', '12468725', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100005, 'roadrunner', 'Schulze', 'Anna-Maria', 'Lilienallee', '3', '10555', 'Berlin', '184695354', '40069722', 0, 1, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100006, 'pittkuss', 'Schäfer', 'Simone', 'Burgstraße', '47', '30678', 'Hannover', '298648148', '30057458', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100007, 'masterflash', 'Franken', 'Stefanie', 'Mauerstraße', '58', '69122', 'Heidelberg', '397125984', '21485367', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100008, 'meikelex', 'Mustermann', 'Chris', 'Lüner Hellweg', '23', '06199', 'Halle', '195698456', '40298568', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100009, 'hobbyzuechter', 'Krämer', 'Thomas', 'Baroper Weg', '11', '62333', 'Frankfurt', '123987654', '46865215', 0, 1, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100010, 'maurimirko', 'Schneider', 'Bettina', 'Zepelinstraße', '80', '51698', 'Köln', '198597364', '56661166', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100011, 'thorn', 'Schulz', 'Marc', 'Kaufingerstraße', '258', '89321', 'Ulm', '284697248', '20156986', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100012, 'timslaedle', 'Thomalla', 'Heinz', 'Landgrafenallee', '54', '97011', 'Würzburg', '365795148', '24465139', 0, 1, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100013, 'virgenierot', 'Hoffmann', 'Erika', 'Hauptstraße', '80', '97877', 'Wertheim', '134598264', '34436915', 0, 0, 0); INSERT INTO Ebay_Kunde_Dummie VALUES(100014, 'kehrtag', 'Fischer', 'Franziska', 'Schloßalle', '65', '40359', 'Düsseldorf', '123456789', '12268820', 1, 0, 100); INSERT INTO Ebay_Kunde_Dummie VALUES(100015, 'homie', 'Neumann', 'Martin', 'Badstraße', '1c', '47555', 'Krefeld', '132198567', '45698723', 0, 0, 0); INSERT INTO Auktionstyp VALUES (1, 'SofortKaufen', 'Wenn Sie neben einem Angebot das Symbol SofortKaufen sehen, können Sie diesen Artikel sofort zu einem Festpreis kaufen.'); INSERT INTO Auktionstyp VALUES (2, 'Sofort&Neu', 'Wenn Sie neben einem Angebot das Symbol Sofort&Neu sehen, können Sie diesen Artikel sofort zu einem Festpreis kaufen.'); INSERT INTO Auktionstyp VALUES (3, 'Gebot', 'Innerhalb der Auktionsdauer kann eine Gebotsabgabe für einen Artikel abgegeben werden.'); INSERT INTO Kategorie VALUES (1, 'Audio & Hifi'); INSERT INTO Kategorie VALUES (2, 'CD Player'); INSERT INTO Kategorie VALUES (3, 'DJ Equipment'); INSERT INTO Kategorie VALUES (4, 'MP3 Player'); INSERT INTO Kategorie VALUES (5, 'Verstärker'); INSERT INTO Kategorie VALUES (6, 'Zubehör'); INSERT INTO Kategorie VALUES (7, 'Bücher'); INSERT INTO Kategorie VALUES (8, 'Belletristik'); INSERT INTO Kategorie VALUES (9, 'Kinder - & Jugendbücher'); INSERT INTO Kategorie VALUES (10, 'Sachbücher & Ratgeber'); INSERT INTO Kategorie VALUES (11, 'Schule & Ausbildung'); INSERT INTO Kategorie VALUES (12, 'Englischsprachige Bücher'); INSERT INTO Kategorie VALUES (13, 'Musik'); INSERT INTO Kategorie VALUES (14, 'CDs'); INSERT INTO Kategorie VALUES (15, 'Vinyl'); INSERT INTO Kategorie VALUES (16, 'Zubehör & Aufbewahrung'); INSERT INTO Kategorie VALUES (17, 'Hörbücher & Hörspiele'); INSERT INTO Kategorie VALUES (18, 'Fanartikel & Merchandise'); INSERT INTO Kategorie VALUES (19, 'Sport'); INSERT INTO Kategorie VALUES (20, 'Fubball'); INSERT INTO Kategorie VALUES (21, 'Camping & Outdoor'); INSERT INTO Kategorie VALUES (22, 'Inlineskating'); INSERT INTO Kategorie VALUES (23, 'Skisport'); INSERT INTO Kategorie VALUES (24, 'Bootsport'); INSERT INTO Kategorie VALUES (25, 'Tv, Video & Elektronik'); INSERT INTO Kategorie VALUES (26, 'Blu-Ray-Player'); INSERT INTO Kategorie VALUES (27, 'DVD-Player'); INSERT INTO Kategorie VALUES (28, 'Fernseher'); INSERT INTO Kategorie VALUES (29, 'GPS'); INSERT INTO Kategorie VALUES (30, 'Leinwände'); INSERT INTO Kategorie_Dummie VALUES (1, 'Audio & Hifi'); INSERT INTO Kategorie_Dummie VALUES (2, 'CD Player'); INSERT INTO Kategorie_Dummie VALUES (3, 'DJ Equipment'); INSERT INTO Kategorie_Dummie VALUES (4, 'MP3 Player'); INSERT INTO Kategorie_Dummie VALUES (5, 'Verstärker'); INSERT INTO Kategorie_Dummie VALUES (6, 'Zubehör'); INSERT INTO Kategorie_Dummie VALUES (7, 'Bücher'); INSERT INTO Kategorie_Dummie VALUES (8, 'Belletristik'); INSERT INTO Kategorie_Dummie VALUES (9, 'Kinder - & Jugendbücher'); INSERT INTO Kategorie_Dummie VALUES (10, 'Sachbücher & Ratgeber'); INSERT INTO Kategorie_Dummie VALUES (11, 'Schule & Ausbildung'); INSERT INTO Kategorie_Dummie VALUES (12, 'Englischsprachige Bücher'); INSERT INTO Kategorie_Dummie VALUES (13, 'Musik'); INSERT INTO Kategorie_Dummie VALUES (14, 'CDs'); INSERT INTO Kategorie_Dummie VALUES (15, 'Vinyl'); INSERT INTO Kategorie_Dummie VALUES (16, 'Zubehör & Aufbewahrung'); INSERT INTO Kategorie_Dummie VALUES (17, 'Hörbücher & Hörspiele'); INSERT INTO Kategorie_Dummie VALUES (18, 'Fanartikel & Merchandise'); INSERT INTO Kategorie_Dummie VALUES (19, 'Sport'); INSERT INTO Kategorie_Dummie VALUES (20, 'Fubball'); INSERT INTO Kategorie_Dummie VALUES (21, 'Camping & Outdoor'); INSERT INTO Kategorie_Dummie VALUES (22, 'Inlineskating'); INSERT INTO Kategorie_Dummie VALUES (23, 'Skisport'); INSERT INTO Kategorie_Dummie VALUES (24, 'Bootsport'); INSERT INTO Kategorie_Dummie VALUES (25, 'Tv, Video & Elektronik'); INSERT INTO Kategorie_Dummie VALUES (26, 'Blu-Ray-Player'); INSERT INTO Kategorie_Dummie VALUES (27, 'DVD-Player'); INSERT INTO Kategorie_Dummie VALUES (28, 'Fernseher'); INSERT INTO Kategorie_Dummie VALUES (29, 'GPS'); INSERT INTO Kategorie_Dummie VALUES (30, 'Leinwände'); INSERT INTO Struktur VALUES (2, 1); INSERT INTO Struktur VALUES (3, 1); INSERT INTO Struktur VALUES (4, 1); INSERT INTO Struktur VALUES (5, 1); INSERT INTO Struktur VALUES (6, 1); INSERT INTO Struktur VALUES (8, 7); INSERT INTO Struktur VALUES (9, 7); INSERT INTO Struktur VALUES (10, 7); INSERT INTO Struktur VALUES (11, 7); INSERT INTO Struktur VALUES (12, 7); INSERT INTO Struktur VALUES (14, 11); INSERT INTO Struktur VALUES (15, 11); INSERT INTO Struktur VALUES (16, 11); INSERT INTO Struktur VALUES (17, 11); INSERT INTO Struktur VALUES (18, 11); INSERT INTO Struktur VALUES (20, 19); INSERT INTO Struktur VALUES (21, 19); INSERT INTO Struktur VALUES (22, 19); INSERT INTO Struktur VALUES (23, 19); INSERT INTO Struktur VALUES (24, 19); INSERT INTO Struktur VALUES (26, 25); INSERT INTO Struktur VALUES (27, 25); INSERT INTO Struktur VALUES (28, 25); INSERT INTO Struktur VALUES (29, 25); INSERT INTO Struktur VALUES (30, 25); INSERT INTO Auktion VALUES (1, 100000, 1.00, '20070101', '20070501', 6.00, true, 6.00); INSERT INTO Auktion VALUES (2, 100001, 1.50, '20070101', '20070501', 3.00, false, 6.50); INSERT INTO Auktion VALUES (3, 100002, 2.00, '20070301', '20070901', 7.00, true, 7.00); INSERT INTO Auktion VALUES (4, 100003, 3.50, '20070301', '20070901', 3.50, false, 8.50); INSERT INTO Auktion VALUES (5, 100000, 6.00, '20070301', '20070901', 11.00, true, 11.00); INSERT INTO Auktion VALUES (6, 100001, 9.99, '20070501', '20080301', 9.99, false, 14.99); INSERT INTO Auktion VALUES (7, 100002, 10.00, '20070501', '20080401', 15.00, true, 15.00); INSERT INTO Auktion VALUES (8, 100003, 15.00, '20070901', '20080501', 0.00, false, 22.50); INSERT INTO Auktion VALUES (9, 100005, 20.00, '20070901', '20080101', 0.00, true, 30.00); INSERT INTO Auktion VALUES (10, 100006, 40.00, '20070901', '20080201', 40.00, false, 60.00); INSERT INTO Auktion VALUES (11, 100007, 100.00, '20070901', '20080301', 150.00, true, 150.00); INSERT INTO Auktion VALUES (12, 100008, 250.00, '20070901', '20080401', 275.00, false, 375.00); INSERT INTO Auktion VALUES (13, 100009, 500.00, '20070901', '20080501', 750.00, true, 750.00); INSERT INTO Auktion VALUES (14, 100010, 5.00, '20070901', '20080601', 5.00, false, 7.50); INSERT INTO Auktion VALUES (15, 100011, 4.00, '20070901', '20080701', 0.00, true, 6.00); INSERT INTO Auktion VALUES (16, 100012, 50.00, '20070901', '20080801', 55.00, false, 75.00); INSERT INTO Auktion VALUES (17, 100013, 24.99, '20070901', '20080901', 0.00, true, 37.49); INSERT INTO Auktion VALUES (18, 100014, 99.99, '20080301', '20080901', 99.99, false, 149.99); INSERT INTO Auktion VALUES (19, 100003, 1.00, '20080401', '20080901', 1.50, true, 1.50); INSERT INTO Auktion VALUES (20, 100005, 35.00, '20080501', '20080901', 35.00, false, 52.50); INSERT INTO Auktion VALUES (21, 100006, 25.00, '20080901', '20080901', 37.50, true, 37.50); INSERT INTO Gebot VALUES (100, 100000, 1, '20070101', '00:00', 6.00, true); INSERT INTO Gebot VALUES (101, 100001, 2, '20070201', '01:00', 1.50, false); INSERT INTO Gebot VALUES (102, 100002, 3, '20070301', '02:00', 7.00, true); INSERT INTO Gebot VALUES (103, 100003, 4, '20070401', '03:00', 3.50, false); INSERT INTO Gebot VALUES (104, 100004, 5, '20070501', '04:00', 11.00, true); INSERT INTO Gebot VALUES (105, 100005, 6, '20070601', '05:00', 9.99, false); INSERT INTO Gebot VALUES (106, 100006, 7, '20070701', '06:00', 15.00, true); INSERT INTO Gebot VALUES (107, 100007, 2, '20070801', '07:00', 2, false); INSERT INTO Gebot VALUES (108, 100008, 2, '20070901', '08:00', 3, false); INSERT INTO Gebot VALUES (109, 100009, 10, '20071001', '09:00', 40.00, false); INSERT INTO Gebot VALUES (110, 100010, 11, '20071101', '10:00', 150.00, true); INSERT INTO Gebot VALUES (111, 100011, 12, '20071201', '11:00', 250.00, false); INSERT INTO Gebot VALUES (112, 100012, 13, '20080101', '12:00', 750.00, true); INSERT INTO Gebot VALUES (113, 100013, 14, '20080201', '13:00', 5.00, false); INSERT INTO Gebot VALUES (114, 100014, 12, '20080301', '14:00', 275, false); INSERT INTO Gebot VALUES (115, 100015, 16, '20080401', '15:00', 50, false); INSERT INTO Gebot VALUES (116, 100007, 16, '20080501', '16:00', 55, false); INSERT INTO Gebot VALUES (117, 100008, 18, '20080601', '17:00', 99.99, false); INSERT INTO Gebot VALUES (118, 100009, 19, '20080701', '18:00', 1.50, true); INSERT INTO Gebot VALUES (119, 100010, 20, '20080801', '19:00', 35.00, false); INSERT INTO Gebot VALUES (120, 100011, 21, '20080901', '20:00', 37.50, true); INSERT INTO Abschluss VALUES (100, 6.00); INSERT INTO Abschluss VALUES (102, 7.00); INSERT INTO Abschluss VALUES (103, 3.50); INSERT INTO Abschluss VALUES (104, 11.00); INSERT INTO Abschluss VALUES (105, 9.99); INSERT INTO Abschluss VALUES (106, 15.00); INSERT INTO Abschluss VALUES (108, 3); INSERT INTO Abschluss VALUES (109, 40.00); INSERT INTO Abschluss VALUES (110, 150.00); INSERT INTO Abschluss VALUES (112, 750.00); INSERT INTO Abschluss VALUES (113, 5.00); INSERT INTO Abschluss VALUES (114, 275); INSERT INTO Abschluss VALUES (116, 55); INSERT INTO Abschluss VALUES (117, 99.99); INSERT INTO Abschluss VALUES (118, 1.50); INSERT INTO Abschluss VALUES (119, 35.00); INSERT INTO Abschluss VALUES (120, 37.50); INSERT INTO Kommentar_Bewertung VALUES (100, 100011, 100000, 'Ware wie beschrieben . Versand schnell . Topp Ebayer', 'Danke', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (102, 100001, 100002, 'Super Ware!!! Immer Gerne!!!!', 'Viele Dank', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (103, 100002, 100003, 'Gibt 6,90 DHL Paket an und versendet als 3,90 Päckchen. Abzocke. Pfui. NEGATIV', '', '', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (104, 100003, 100000, 'Alles Bestens ,sehr netter ebayer', 'Sehr vielen Dank, für diese postive Bewertung', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (105, 100004, 100001, 'Übergabe gut gelaufen!', '', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (106, 100005, 100002, 'Negativ-Negativ-', 'Tolle Bewertung, gibts auch einen konkreten Grund?', '', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (108, 100007, 100001, 'sehr netter kontakt, bestens gelaufen', 'Wie darf ich denn den ersten Teil des Kommentars verstehen?', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (109, 100008, 100006, 'kam 1a+ an, gebrauchsspuren wie beschrieben', 'Soll das nun eine Kritik über Raucher sein?', '', 'neutral'); INSERT INTO Kommentar_Bewertung VALUES (110, 100009, 100007, 'turboschneller Versand!TOP Qualität!!Vielen Dank!!', 'Fantastisch, danke', '', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (112, 100011, 100009, 'Übt nach Auktionsende ungebührlichen Druck aus. Sehr fragwürdiges Auftreten.', 'KOMISCHER MENSCH,ERST KEINE BEWERTUNG, ABGEBEN,WENN MANN NACHFRAGT DANN SOWAS', 'Die Art der Frage macht einiges aus', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (113, 100012, 100010, 'Nicht ganz so guter Zustand ansonsten alles OK', 'BITTE DAS NÄCHSTE MAL ARTIKELBESCHREIBUNG GENAUER LESEN', 'Beschreibung war sehr interpretierbar', 'neutral'); INSERT INTO Kommentar_Bewertung VALUES (114, 100013, 100008, 'x', 'WAS IST DAS FÜR EINE BEWERTUNG??????', 'in meinen Kreisen bedeutet das auch :Alles super', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (116, 100015, 100012, 'Größenauszeichnung stimmt nicht', '', '', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (117, 100007, 100014, 'sehr schnell, alles gut,auch wenns eine nicht angegebene kleine macke gibt ;)', 'Muss dann wohl auf dem Postweg passiert sein - Sorry', 'War ja weiter auch nicht schlimm', 'positiv'); INSERT INTO Kommentar_Bewertung VALUES (118, 100008, 100003, 'Ware ok, Verpackung sehr schlecht', 'Als ich es losgeschickt habe, war die Verpackug noch in Ordnung', 'Das kann nicht alles auf dem Postweg passeiert sein, ich würde sagen eher am Verpackungsmaterial gespart', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (119, 100009, 100005, 'extrem unachtsame Ausdrucksweise/trotz Zahlung doppelter Beschwerde/Tipp:Yoga', 'Käufer hat die Ware erst nach Beschwerde u. 6 Wo. nach Kauf bezahlt. Frechheit!', 'Ich musste es halt erst testen bevor ich es bezahle, ganz ruhig', 'negativ'); INSERT INTO Kommentar_Bewertung VALUES (120, 100010, 100006, '!!! PERFEKT !!! Note 1a', 'Supi, thanks', '', 'positiv'); INSERT INTO Zuordnung VALUES (2, 1); INSERT INTO Zuordnung VALUES (3, 2); INSERT INTO Zuordnung VALUES (4, 3); INSERT INTO Zuordnung VALUES (5, 4); INSERT INTO Zuordnung VALUES (6, 5); INSERT INTO Zuordnung VALUES (8, 6); INSERT INTO Zuordnung VALUES (9, 7); INSERT INTO Zuordnung VALUES (10, 8); INSERT INTO Zuordnung VALUES (11, 9); INSERT INTO Zuordnung VALUES (12, 10); INSERT INTO Zuordnung VALUES (14, 11); INSERT INTO Zuordnung VALUES (15, 12); INSERT INTO Zuordnung VALUES (16, 13); INSERT INTO Zuordnung VALUES (17, 14); INSERT INTO Zuordnung VALUES (18, 15); INSERT INTO Zuordnung VALUES (20, 16); INSERT INTO Zuordnung VALUES (21, 17); INSERT INTO Zuordnung VALUES (22, 18); INSERT INTO Zuordnung VALUES (23, 19); INSERT INTO Zuordnung VALUES (24, 20); INSERT INTO Zuordnung VALUES (26, 21); INSERT INTO Auktionstypzuordnung VALUES (1, 1); INSERT INTO Auktionstypzuordnung VALUES (2, 2); INSERT INTO Auktionstypzuordnung VALUES (3, 3); INSERT INTO Auktionstypzuordnung VALUES (3, 4); INSERT INTO Auktionstypzuordnung VALUES (3, 5); INSERT INTO Auktionstypzuordnung VALUES (3, 6); INSERT INTO Auktionstypzuordnung VALUES (3, 7); INSERT INTO Auktionstypzuordnung VALUES (1, 8); INSERT INTO Auktionstypzuordnung VALUES (1, 9); INSERT INTO Auktionstypzuordnung VALUES (2, 10); INSERT INTO Auktionstypzuordnung VALUES (2, 11); INSERT INTO Auktionstypzuordnung VALUES (2, 12); INSERT INTO Auktionstypzuordnung VALUES (2, 13); INSERT INTO Auktionstypzuordnung VALUES (3, 14); INSERT INTO Auktionstypzuordnung VALUES (3, 15); INSERT INTO Auktionstypzuordnung VALUES (3, 16); INSERT INTO Auktionstypzuordnung VALUES (3, 17); INSERT INTO Auktionstypzuordnung VALUES (3, 18); INSERT INTO Auktionstypzuordnung VALUES (2, 19); INSERT INTO Auktionstypzuordnung VALUES (1, 20); INSERT INTO Auktionstypzuordnung VALUES (1, 21); INSERT INTO Beobachtung VALUES (1, 100011); INSERT INTO Beobachtung VALUES (2, 100000); INSERT INTO Beobachtung VALUES (3, 100001); INSERT INTO Beobachtung VALUES (4, 100002); INSERT INTO Beobachtung VALUES (5, 100003); INSERT INTO Beobachtung VALUES (6, 100004); INSERT INTO Beobachtung VALUES (7, 100005); INSERT INTO Beobachtung VALUES (2, 100006); INSERT INTO Beobachtung VALUES (2, 100007); INSERT INTO Beobachtung VALUES (10, 100008); INSERT INTO Beobachtung VALUES (11, 100009); INSERT INTO Beobachtung VALUES (12, 100010); INSERT INTO Beobachtung VALUES (13, 100011); INSERT INTO Beobachtung VALUES (14, 100012); INSERT INTO Beobachtung VALUES (12, 100013); INSERT INTO Beobachtung VALUES (16, 100014); INSERT INTO Beobachtung VALUES (16, 100015); INSERT INTO Beobachtung VALUES (18, 100007); INSERT INTO Beobachtung VALUES (19, 100008); INSERT INTO Beobachtung VALUES (20, 100009); INSERT INTO Beobachtung VALUES (21, 100010); INSERT INTO Beobachtung VALUES (10, 100002); INSERT INTO Beobachtung VALUES (4, 100014); INSERT INTO Beobachtung VALUES (8, 100011); INSERT INTO Aktuell VALUES (8); INSERT INTO Aktuell VALUES (9); INSERT INTO Aktuell VALUES (10); INSERT INTO Aktuell VALUES (11); INSERT INTO Aktuell VALUES (12); INSERT INTO Aktuell VALUES (13); INSERT INTO Aktuell VALUES (14); INSERT INTO Aktuell VALUES (15); INSERT INTO Aktuell VALUES (16); INSERT INTO Aktuell VALUES (17); INSERT INTO Aktuell VALUES (18); INSERT INTO Aktuell VALUES (19); INSERT INTO Aktuell VALUES (20); INSERT INTO Aktuell VALUES (21);", + }, + { + id: 7, + name: "ÜB1: Hotelbeispiel", + category: categories[1], + templateQuery: + "CREATE TABLE hotel ( HoNr INTEGER NOT NULL, HName VARCHAR(40), Ort VARCHAR(40), Straße VARCHAR(40), HausNr VARCHAR(5), PLZ CHAR(5), CONSTRAINT pk_hotel PRIMARY KEY(HoNr)); CREATE TABLE zimmer ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ZName VARCHAR(40), Kapazitaet INTEGER, Preis DECIMAL(8, 2), CONSTRAINT pk_zimmer PRIMARY KEY(HoNr, ZNr), CONSTRAINT fk_zimmer FOREIGN KEY(HoNr) REFERENCES hotel(HoNr)); CREATE TABLE ausstattung ( ANr INTEGER NOT NULL, Bezeichnung VARCHAR(40), Zusatzkosten DECIMAL(8, 2), CONSTRAINT pk_ausstattung PRIMARY KEY(ANr)); CREATE TABLE normal ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ANr INTEGER NOT NULL, CONSTRAINT pk_normal PRIMARY KEY(HoNr, ZNr, ANr), CONSTRAINT fk_normal_1 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT fk_normal_2 FOREIGN KEY(HoNr, ZNr) REFERENCES zimmer(HoNr, ZNr)); CREATE TABLE gast ( GNr INTEGER NOT NULL, Name VARCHAR(30), Vorname VARCHAR(40), Ort VARCHAR(50), PLZ CHAR(5), Strasse VARCHAR(50), HausNr VARCHAR(5), CONSTRAINT pk_gast PRIMARY KEY(GNr)); INSERT INTO hotel VALUES(132,'Gruene Bogenschuetze','Geseke','An der Abtei','3','59590'); INSERT INTO zimmer VALUES(132, 115,'Waldruh', 2, 55.34); INSERT INTO zimmer VALUES(132, 134,'Hochsitz', 4, 89.47); INSERT INTO gast VALUES(95792,'Müller','Martin','Musterstadt','10000','Poststrasse','13-15'); INSERT INTO ausstattung VALUES(1,'Großleinwand mit Beamer','24.50'); INSERT INTO ausstattung VALUES(2,'Film Titanic','2.35'); INSERT INTO ausstattung VALUES(3,'DVD-Player', 18.52); INSERT INTO hotel VALUES(625,'Hotel Adlon','Dortmund','Lilienthalstrasse','68a','44369'); INSERT INTO hotel VALUES(392,'Hotel Kempinski','Muenchen','Terminalstrasse', '20-22','85356'); INSERT INTO hotel VALUES(393,'Sternwirt','Weigendorf','Wellnesstraße', '12','91249'); INSERT INTO hotel VALUES(394,'Landhaus Sponsel-Regus','Heiligenstadt i. Ofr.','Landhausstr', '12','91332'); INSERT INTO gast VALUES(59375,'Engelke-Meise','Silke','Herne','44625','Jaegerstrasse','13'); INSERT INTO gast VALUES(58,'Ebbingmann','Adalbert','Fuessen','87629','Froschseenstrasse','33'); INSERT INTO gast VALUES(4711,'Matzke','Muximilian','Waldshut','79761','Kaiserstrasse','27'); INSERT INTO gast VALUES(30,'Hansen','Irmgard','Bamberg','96023','Neuer Weg','15'); INSERT INTO gast VALUES(31,'Rosenberg','Brigitte','Duisburg','41025','Rahmerstr','168'); INSERT INTO zimmer VALUES(625,5,'No5',2,'21.99'); INSERT INTO zimmer VALUES(625,412,'Rosa Raum',2,'90.35'); INSERT INTO zimmer VALUES(625,414,'Schlafwohl',4,'59.95'); INSERT INTO zimmer VALUES(392,333,'Stollen West',2,'24.99'); INSERT INTO zimmer VALUES(392,135,'Missippi',6,'52.89'); INSERT INTO zimmer VALUES(392,334,'Schoene Aussicht',2,'74.25'); INSERT INTO zimmer VALUES(393,363,'Morgenroete',5,'195.25'); INSERT INTO zimmer VALUES(393,512,'Angeraue',2,'50.12'); INSERT INTO zimmer VALUES(394,12,'Jordanquelle',2,'45.40'); INSERT INTO zimmer VALUES(394,14,'Lippequelle',2,50.50); INSERT INTO zimmer VALUES(394,26,'Stadttor',2,78.99); INSERT INTO zimmer VALUES(394,27,'Kniebruecke',4,74.99);", + }, + { + id: 8, + name: "ÜB2: Hotelbeispiel", + category: categories[1], + templateQuery: + "CREATE TABLE hotel ( HoNr INTEGER NOT NULL, HName VARCHAR(40), Ort VARCHAR(40), Straße VARCHAR(40), HausNr VARCHAR(5), PLZ CHAR(5), CONSTRAINT pk_hotel PRIMARY KEY(HoNr)); CREATE TABLE zimmer ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ZName VARCHAR(40), Kapazitaet INTEGER, Preis DECIMAL(8,2), CONSTRAINT pk_zimmer PRIMARY KEY(HoNr,ZNr), CONSTRAINT fk_zimmer FOREIGN KEY(HoNr) REFERENCES hotel(HoNr)); CREATE TABLE ausstattung ( ANr INTEGER NOT NULL, Bezeichnung VARCHAR(40), Zusatzkosten DECIMAL(8,2), CONSTRAINT pk_ausstattung PRIMARY KEY(ANr)); CREATE TABLE normal ( HoNr INTEGER NOT NULL, ZNr INTEGER NOT NULL, ANr INTEGER NOT NULL, anzahl INTEGER DEFAULT 1, CONSTRAINT pk_normal PRIMARY KEY(HoNr,ZNr,ANr), CONSTRAINT fk_normal_1 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT fk_normal_2 FOREIGN KEY(HoNr,ZNr) REFERENCES zimmer(HoNr,ZNr)); CREATE TABLE gast ( GNr INTEGER NOT NULL, Name VARCHAR(30), Vorname VARCHAR(40), Ort VARCHAR(50), PLZ CHAR(5), Strasse VARCHAR(50), HausNr VARCHAR(5), CONSTRAINT pk_gast PRIMARY KEY(GNr)); CREATE TABLE reservierung ( RNr INTEGER NOT NULL, Datum DATE, HoNr INTEGER, GNr INTEGER, CONSTRAINT pk_reservierung PRIMARY KEY(RNr), CONSTRAINT fk_reservierung_1 FOREIGN KEY(HoNr) REFERENCES hotel(HoNr), CONSTRAINT fk_reservierung_2 FOREIGN KEY(GNr) REFERENCES gast(GNr)); CREATE TABLE rposition ( RNr INTEGER NOT NULL, RPos INTEGER NOT NULL, von DATE, bis DATE, HoNr INTEGER, ZNr INTEGER, CONSTRAINT pk_position PRIMARY KEY(RNr,RPos), CONSTRAINT fk_position_1 FOREIGN KEY(RNr) REFERENCES reservierung(RNr), CONSTRAINT fk_position_2 FOREIGN KEY(HoNr,ZNr) REFERENCES zimmer(HoNr,ZNr), CONSTRAINT check_date CHECK (von <= bis)); CREATE TABLE zusatz ( RNr INTEGER NOT NULL, RPos INTEGER NOT NULL, ANr INTEGER NOT NULL, von DATE, bis DATE, anzahl INTEGER DEFAULT 1, CONSTRAINT pk_zusatz PRIMARY KEY(RNr,RPos,ANr), CONSTRAINT fk_zusatz_1 FOREIGN KEY(RNr,RPos) REFERENCES rposition(RNr,RPos), CONSTRAINT fk_zusatz_2 FOREIGN KEY(ANr) REFERENCES ausstattung(ANr), CONSTRAINT check_date CHECK (von <= bis)); INSERT INTO hotel VALUES(1036,'Ringhotel','Luenen','Kurt-Schumacher-Strasse','1','44534'); INSERT INTO hotel VALUES(34 ,'Haus Schmuelling','Bergkamen','Landwehrstrasse','54','59192'); INSERT INTO hotel VALUES(135,'City Hotel','Dortmund','Auf dem Wall','62','44147'); INSERT INTO hotel VALUES(843,'Maritim','Stralsund','Strandgasse','37','18435'); INSERT INTO hotel VALUES(428,'Riss','Chemnitz','An der Erzkuhle','23','09008'); INSERT INTO hotel VALUES(522,'Bohne','Kakau b. Bitterfeld','Zur Plantage','14','06785'); INSERT INTO hotel VALUES(132,'Gruene Bogenschuetze','Geseke','An der Abtei','3','59590'); INSERT INTO hotel VALUES(625,'Hotel Adlon','Dortmund','Lilienthalstrasse','68a','44369'); INSERT INTO hotel VALUES(392,'Hotel Kempinski','Muenchen','Terminalstrasse','20-22','85356'); INSERT INTO hotel VALUES(736,'Gasthof Sybille','Bad Lippspringe','An der Jordanquelle','1','33188'); INSERT INTO hotel VALUES(758,'Kastens Hotel','Duesseldorf','Lorettostr','5','40219'); INSERT INTO hotel VALUES(761,'Am Glockenturm','Arnsberg','Soesterstr','1','59821'); INSERT INTO ausstattung VALUES(23,'Telefon',5.67); INSERT INTO ausstattung VALUES(35,'Goldene Wascharmaturen',45.16); INSERT INTO ausstattung VALUES(47,'Extragroße Badetuecher',9.99); INSERT INTO ausstattung VALUES(59,'Bettwaesche',10.32); INSERT INTO ausstattung VALUES(61,'Haekelkissenbezuege',13.57); INSERT INTO ausstattung VALUES(73,'Kabelfernsehen',15.66); INSERT INTO ausstattung VALUES(84,'Satellitenfernsehen',16.55); INSERT INTO ausstattung VALUES(96,'Beamer',23.79); INSERT INTO ausstattung VALUES(108,'Overheadprojektor',17.43); INSERT INTO ausstattung VALUES(111,'Videorekorder',16.89); INSERT INTO ausstattung VALUES(123,'DVD-Player',18.52); INSERT INTO ausstattung VALUES(130,'HiFi-Multifunktionsanlage',25.91); INSERT INTO ausstattung VALUES(142,'Stuhl',4.31); INSERT INTO ausstattung VALUES(154,'Tisch',5.76); INSERT INTO ausstattung VALUES(166,'Kopfkissen',15.69); INSERT INTO ausstattung VALUES(178,'Gummibettlaken',17.83); INSERT INTO ausstattung VALUES(62,'gehaekelte Toilettenrollendeckchen',11.46); INSERT INTO ausstattung VALUES(46,'Bademantel','5.50'); INSERT INTO ausstattung VALUES(45,'Hausschuhe','2.35'); INSERT INTO ausstattung VALUES(50,'Kinderbett','0.0'); INSERT INTO ausstattung VALUES(51,'Hochstuhl','0.0'); INSERT INTO ausstattung VALUES(52,'Safe','2.45'); INSERT INTO ausstattung VALUES(53,'Heizdecke','16.85'); INSERT INTO ausstattung VALUES(54,'Duftkerzen','12.15'); INSERT INTO ausstattung VALUES(24,'W-LAN Zugang','5.95'); INSERT INTO ausstattung VALUES(25,'DSL-Anschluss','7.69'); INSERT INTO zimmer VALUES(34,3,'No3',1,19.99); INSERT INTO zimmer VALUES(135,312,'Praesidentensuite',6,399.99); INSERT INTO zimmer VALUES(135,313,'Bernsteinzimmer',6,600.00); INSERT INTO zimmer VALUES(428,222,'Stollen Sued',2,24.99); INSERT INTO zimmer VALUES(843,145,'Seeblick',3,89.67); INSERT INTO zimmer VALUES(1036,217,'Waldblick',2,45.99); INSERT INTO zimmer VALUES(428,111,'Stollen Nord',1,23.99); INSERT INTO zimmer VALUES(843,732,'Krabbenkutter',5,485.00); INSERT INTO zimmer VALUES(135,521,'Westfalenzimmer',4,167.55); INSERT INTO zimmer VALUES(34,4,'No4',2,21.99); INSERT INTO zimmer VALUES(1036,1214,'Schwanenteich',3,76.99); INSERT INTO zimmer VALUES(522,113,'Onkel Toms Huette',2,54.99); INSERT INTO zimmer VALUES(522,124,'Singendes Zuckerrohr',3,65.35); INSERT INTO zimmer VALUES(132,115,'Waldruh',2,55.34); INSERT INTO zimmer VALUES(132,134,'Hochsitz',4,89.47); INSERT INTO zimmer VALUES(625,257,'Metropolian',2,76.21); INSERT INTO zimmer VALUES(625,412,'Blickpunkt',3,87.25); INSERT INTO zimmer VALUES(392,233,'Waldfried',1,32.46); INSERT INTO zimmer VALUES(392,513,'Flugplatz',2,43.62); INSERT INTO zimmer VALUES(34,5,'No5',2,'21.99'); INSERT INTO zimmer VALUES(132,122,'Strecke',2,'60.45'); INSERT INTO zimmer VALUES(135,412,'Rosa Raum',2,'90.35'); INSERT INTO zimmer VALUES(392,414,'Schlafwohl',2,'59.95'); INSERT INTO zimmer VALUES(428,333,'Stollen West',2,'24.99'); INSERT INTO zimmer VALUES(522,135,'Missippi',2,'52.89'); INSERT INTO zimmer VALUES(625,333,'Schoene Aussicht',2,'74.25'); INSERT INTO zimmer VALUES(843,363,'Morgenroete',2,'195.25'); INSERT INTO zimmer VALUES(1036,512,'Angeraue',2,'50.12'); INSERT INTO zimmer VALUES(736,11,'Arminiusquelle',2,'45.40'); INSERT INTO zimmer VALUES(736,12,'Jordanquelle',2,'45.40'); INSERT INTO zimmer VALUES(736,14,'Lippequelle',2,50.50); INSERT INTO zimmer VALUES(758,25,'Rheinturm',2,78.99); INSERT INTO zimmer VALUES(758,26,'Stadttor',2,78.99); INSERT INTO zimmer VALUES(758,27,'Kniebruecke',2,74.99); INSERT INTO zimmer VALUES(761,31,'Schlossberg',2,25.85); INSERT INTO zimmer VALUES(761,32,'Gambrinus',2,19.99); INSERT INTO zimmer VALUES(761,33,'Muffrika',4,48.55); INSERT INTO normal VALUES(1036,217,23); INSERT INTO normal VALUES(843,145,73); INSERT INTO normal VALUES(34,3,23); INSERT INTO normal VALUES(428,222,61); INSERT INTO normal VALUES(135,312,166); INSERT INTO normal VALUES(428,111,142); INSERT INTO normal VALUES(34,4,59); INSERT INTO normal VALUES(1036,1214,84); INSERT INTO normal VALUES(135,521,178); INSERT INTO normal VALUES(843,732,130); INSERT INTO normal VALUES(522,113,62); INSERT INTO normal VALUES(522,124,59); INSERT INTO normal VALUES(132,115,73); INSERT INTO normal VALUES(132,134,84); INSERT INTO normal VALUES(625,257,23); INSERT INTO normal VALUES(625,412,166); INSERT INTO normal VALUES(392,233,35); INSERT INTO normal VALUES(392,513,130); INSERT INTO normal VALUES(522,113,59); INSERT INTO normal VALUES(34,5,59,2); INSERT INTO normal VALUES(132,122,59,2); INSERT INTO normal VALUES(135,412,59,2); INSERT INTO normal VALUES(392,414,59,2); INSERT INTO normal VALUES(428,333,59,2); INSERT INTO normal VALUES(522,135,59,2); INSERT INTO normal VALUES(625,333,59,2); INSERT INTO normal VALUES(843,363,59,2); INSERT INTO normal VALUES(1036,512,59,2); INSERT INTO normal VALUES(736,11,59,2); INSERT INTO normal VALUES(736,12,59,2); INSERT INTO normal VALUES(736,14,59,2); INSERT INTO normal VALUES(758,25,59,2); INSERT INTO normal VALUES(758,26,59,2); INSERT INTO normal VALUES(758,27,59,2); INSERT INTO normal VALUES(761,31,59,2); INSERT INTO normal VALUES(761,32,59,2); INSERT INTO normal VALUES(761,33,59,4); INSERT INTO normal VALUES(34,5,62,1); INSERT INTO normal VALUES(132,122,62,1); INSERT INTO normal VALUES(135,412,62,1); INSERT INTO normal VALUES(392,414,62,1); INSERT INTO normal VALUES(428,333,62,1); INSERT INTO normal VALUES(522,135,62,1); INSERT INTO normal VALUES(625,333,62,1); INSERT INTO normal VALUES(843,363,62,1); INSERT INTO normal VALUES(1036,512,62,1); INSERT INTO normal VALUES(736,11,53,1); INSERT INTO normal VALUES(736,12,53,1); INSERT INTO normal VALUES(736,14,53,1); INSERT INTO normal VALUES(758,25,142,1); INSERT INTO normal VALUES(758,26,142,1); INSERT INTO normal VALUES(758,27,142,1); INSERT INTO normal VALUES(761,31,178,2); INSERT INTO normal VALUES(761,32,178,2); INSERT INTO normal VALUES(761,33,178,4); INSERT INTO gast VALUES(453,'Muller','Jean-Paul','Havixbeck','48329','Willi-Richter-Platz','2b'); INSERT INTO gast VALUES(14753,'Richter','Trude','Buxtehude','21614','Zwischen den Bruecken','6'); INSERT INTO gast VALUES(795,'Stein','Flut','Herten','46599','Stan-Libuda-Strasse','1'); INSERT INTO gast VALUES(8531,'Mustermann','Martin','Musterstadt','10000','Poststrasse','13-15'); INSERT INTO gast VALUES(7184,'Postmann','Elfriede','Chemnitz','09008','Erich-Honecker-Platz','23'); INSERT INTO gast VALUES(3417,'Randzio','Katharina','Aue','08280','Goethestrasse','101a'); INSERT INTO gast VALUES(59375,'Engelke-Meise','Silke','Herne','44625','Jaegerstrasse','13'); INSERT INTO gast VALUES(58,'Ebbingmann','Adalbert','Fuessen','87629','Froschseenstrasse','33'); INSERT INTO gast VALUES(4711,'Matzke','Muximilian','Waldshut','79761','Kaiserstrasse','27'); INSERT INTO gast VALUES(8624,'Rupprecht','Knecht','Himmelstadt','97267','Kirchplatz','5'); INSERT INTO gast VALUES(2738,'Schmitz','Klaus','Dortmund','44147','Linienstrasse','7b'); INSERT INTO gast VALUES(2631,'Biene','Maja','Blumenberg','50765','Auf der Blume','24'); INSERT INTO gast VALUES(25,'Binz','Gunnar','Duesseldorf','40549','Heerdter Sandberg','3'); INSERT INTO gast VALUES(26,'Haller','Karl-Heinz','Dortmund','44143','Breierspfad','134'); INSERT INTO gast VALUES(27,'Kloepping','Harald','Bamberg','96058','Eckeystr','15'); INSERT INTO gast VALUES(28,'Schlanstein','Christina','Dillenburg','35683','Carl-Schurz-Str','9'); INSERT INTO gast VALUES(29,'Gauss','Kerstin','Neuss','41453','Badstr','3'); INSERT INTO gast VALUES(30,'Hansen','Irmgard','Bamberg','96023','Neuer Weg','15'); INSERT INTO gast VALUES(31,'Rosenberg','Brigitte','Duisburg','41025','Rahmerstr','168'); INSERT INTO gast VALUES(32,'Lampe','Rosa','Vechta','49377','Schwichtelerstr','14'); INSERT INTO gast VALUES(33,'Mondo','Dolores','Hagen','58093','Dortmunder Str','15a'); INSERT INTO reservierung VALUES(86542,'2022-09-09',34,453); INSERT INTO reservierung VALUES(145863,'2022-01-02',135,14753); INSERT INTO reservierung VALUES(46357,'2023-04-01',843,795); INSERT INTO reservierung VALUES(43358,'2023-03-23',428,8531); INSERT INTO reservierung VALUES(135,'2015-09-19',1036,7184); INSERT INTO reservierung VALUES(6834,'2024-08-13',34,3417); INSERT INTO reservierung VALUES(115,'2023-05-27',428,59375); INSERT INTO reservierung VALUES(8673,'2023-05-03',135,58); INSERT INTO reservierung VALUES(24,'2019-08-31',843,4711); INSERT INTO reservierung VALUES(9999,'2023-12-12',1036,8624); INSERT INTO reservierung VALUES(735,'2023-03-13',132,4711); INSERT INTO reservierung VALUES(567,'2022-02-24',625,2738); INSERT INTO reservierung VALUES(568,'2023-02-24',135,2738); INSERT INTO reservierung VALUES(818,'2024-03-01',392,8624); INSERT INTO reservierung VALUES(361,'2018-12-21',34,59375); INSERT INTO reservierung VALUES(5294,'2021-10-10',392,3417); INSERT INTO reservierung VALUES(2732,'2016-04-13',132,7184); INSERT INTO reservierung VALUES(2432,'2021-07-16',522,453); INSERT INTO reservierung VALUES(1953,'2021-08-23',135,14753); INSERT INTO reservierung VALUES(356,'2024-01-01',1036,2631); INSERT INTO reservierung VALUES(5646,'2025-02-05',522,795); INSERT INTO reservierung VALUES(6748,'2025-03-22',522,795); INSERT INTO reservierung VALUES(2748,'2024-02-10',132,4711); INSERT INTO reservierung VALUES(2349,'2024-02-10',132,58); INSERT INTO reservierung VALUES(4241,'2025-02-10',132,58); INSERT INTO reservierung VALUES(6878,'2026-02-10',132,58); INSERT INTO reservierung VALUES(221,'2022-05-15',736,25); INSERT INTO reservierung VALUES(222,'2022-01-11',758,26); INSERT INTO reservierung VALUES(223,'2021-11-05',761,27); INSERT INTO reservierung VALUES(224,'2021-10-03',761,28); INSERT INTO reservierung VALUES(225,'2020-07-18',135,27); INSERT INTO reservierung VALUES(226,'2020-11-06',522,29); INSERT INTO reservierung VALUES(227,'2020-12-13',428,30); INSERT INTO reservierung VALUES(228,'2021-02-15',843,31); INSERT INTO reservierung VALUES(229,'2021-03-25',135,32); INSERT INTO reservierung VALUES(230,'2021-04-13',758,33); INSERT INTO reservierung VALUES(231,'2021-06-07',758,33); INSERT INTO reservierung VALUES(232,'2021-08-13',522,25); INSERT INTO reservierung VALUES(233,'2022-04-13',736,29); INSERT INTO reservierung VALUES(234,'2022-02-26',522,27); INSERT INTO reservierung VALUES(235,'2022-08-13',761,26); INSERT INTO reservierung VALUES(236,'2022-09-30',761,25); INSERT INTO reservierung VALUES(237,'2022-03-11',843,33); INSERT INTO reservierung VALUES(238,'2022-04-13',843,58); INSERT INTO reservierung VALUES(239,'2021-11-11',758,58); INSERT INTO reservierung VALUES(240,'2022-02-03',135,453); INSERT INTO reservierung VALUES(241,'2020-12-28',522,795); INSERT INTO rposition VALUES(86542,1,'2022-10-10','2023-10-10',34,3); INSERT INTO rposition VALUES(145863,1,'2023-04-11','2023-04-22',135,312); INSERT INTO rposition VALUES(145863,2,'2023-04-11','2023-04-22',135,313); INSERT INTO rposition VALUES(43358,1,'2023-05-05','2023-05-06',428,222); INSERT INTO rposition VALUES(46357,1,'2024-04-26','2024-05-07',843,145); INSERT INTO rposition VALUES(135,1,'2017-09-18','2017-09-22',1036,217); INSERT INTO rposition VALUES(115,1,'2024-05-28','2024-05-31',428,111); INSERT INTO rposition VALUES(24,1,'2021-04-08','2021-04-25',843,732); INSERT INTO rposition VALUES(24,2,'2021-04-08','2021-04-25',843,145); INSERT INTO rposition VALUES(24,3,'2021-07-31','2021-09-01',34,3); INSERT INTO rposition VALUES(24,4,'2021-07-31','2021-09-01',34,4); INSERT INTO rposition VALUES(8673,1,'2023-07-01','2023-07-15',135,521); INSERT INTO rposition VALUES(6834,1,'2024-08-15','2024-08-27',34,4); INSERT INTO rposition VALUES(9999,1,'2024-04-30','2024-06-30',1036,1214); INSERT INTO rposition VALUES(9999,2,'2024-07-01','2024-07-31',135,312); INSERT INTO rposition VALUES(9999,3,'2024-08-31','2024-10-01',843,145); INSERT INTO rposition VALUES(9999,4,'2024-07-01','2024-07-31',135,313); INSERT INTO rposition VALUES(735,1,'2023-03-20','2024-04-20',392,233); INSERT INTO rposition VALUES(567,1,'2023-04-23','2023-05-07',522,113); INSERT INTO rposition VALUES(568,1,'2023-02-23','2023-03-07',135,412); INSERT INTO rposition VALUES(818,1,'2024-03-24','2024-03-31',132,134); INSERT INTO rposition VALUES(361,1,'2019-12-23','2020-01-06',625,257); INSERT INTO rposition VALUES(5294,1,'2022-04-02','2022-04-16',428,111); INSERT INTO rposition VALUES(2732,1,'2016-08-17','2016-09-04',522,124); INSERT INTO rposition VALUES(2432,1,'2022-06-15','2022-07-16',132,115); INSERT INTO rposition VALUES(1953,1,'2024-08-07','2024-08-15',392,513); INSERT INTO rposition VALUES(818,2,'2024-04-01','2024-04-12',843,732); INSERT INTO rposition VALUES(356,1,'2024-01-02','2024-04-22',522,113); INSERT INTO rposition VALUES(5646,1,'2025-03-06','2025-03-22',843,145); INSERT INTO rposition VALUES(6748,1,'2026-01-01','2026-01-08',843,145); INSERT INTO rposition VALUES(2748,1,'2024-04-01','2024-04-08',392,233); INSERT INTO rposition VALUES(2349,1,'2024-07-16','2024-07-18',392,233); INSERT INTO rposition VALUES(4241,1,'2025-07-16','2025-07-18',392,233); INSERT INTO rposition VALUES(6878,1,'2026-07-16','2026-07-18',392,233); INSERT INTO rposition VALUES(221,1,'2022-05-25','2022-06-05',736,11); INSERT INTO rposition VALUES(222,1,'2022-04-15','2022-04-18',736,12); INSERT INTO rposition VALUES(223,1,'2022-01-11','2022-01-18',736,14); INSERT INTO rposition VALUES(223,2,'2022-02-11','2022-02-18',736,11); INSERT INTO rposition VALUES(223,3,'2022-03-11','2022-03-18',736,14); INSERT INTO rposition VALUES(224,1,'2021-11-11','2021-11-15',758,25); INSERT INTO rposition VALUES(225,1,'2020-07-31','2020-08-15',758,26); INSERT INTO rposition VALUES(226,1,'2020-11-11','2020-11-13',758,27); INSERT INTO rposition VALUES(227,1,'2021-01-12','2021-01-15',761,31); INSERT INTO rposition VALUES(228,1,'2021-03-02','2021-03-08',761,32); INSERT INTO rposition VALUES(228,2,'2021-04-02','2021-04-08',761,32); INSERT INTO rposition VALUES(228,3,'2021-05-02','2021-05-08',761,32); INSERT INTO rposition VALUES(229,1,'2021-03-28','2021-04-07',761,33); INSERT INTO rposition VALUES(230,1,'2021-05-02','2021-05-13',132,122); INSERT INTO rposition VALUES(231,1,'2021-07-01','2021-07-05',34,3); INSERT INTO rposition VALUES(231,2,'2021-07-01','2021-07-05',34,4); INSERT INTO rposition VALUES(231,3,'2021-07-01','2021-07-05',34,5); INSERT INTO rposition VALUES(232,1,'2021-09-19','2021-09-21',135,412); INSERT INTO rposition VALUES(233,1,'2022-05-01','2022-05-05',392,414); INSERT INTO rposition VALUES(234,1,'2022-03-01','2022-03-05',428,333); INSERT INTO rposition VALUES(235,1,'2021-09-01','2021-09-05',522,135); INSERT INTO rposition VALUES(236,1,'2021-12-01','2021-12-10',625,333); INSERT INTO rposition VALUES(237,1,'2022-03-18','2022-03-25',843,363); INSERT INTO rposition VALUES(238,1,'2021-07-01','2021-07-05',1036,512); INSERT INTO rposition VALUES(239,1,'2021-11-11','2021-11-15',758,26); INSERT INTO rposition VALUES(240,1,'2022-02-11','2022-02-15',135,412); INSERT INTO rposition VALUES(241,1,'2021-01-02','2021-01-09',522,135); INSERT INTO zusatz VALUES(735,1,84,'2023-03-21','2024-03-30'); INSERT INTO zusatz VALUES(567,1,61,'2023-04-23','2023-05-07'); INSERT INTO zusatz VALUES(818,1,111,'2024-03-24','2024-03-28'); INSERT INTO zusatz VALUES(361,1,142,'2019-12-26','2020-01-06'); INSERT INTO zusatz VALUES(43358,1,154,'2023-05-05','2023-05-06'); INSERT INTO zusatz VALUES(2732,1,47,'2016-08-17','2016-08-18'); INSERT INTO zusatz VALUES(2432,1,123,'2022-06-30','2022-07-01'); INSERT INTO zusatz VALUES(1953,1,178,'2024-08-07','2024-08-15'); INSERT INTO zusatz VALUES(818,2,96,'2024-04-04','2024-04-11'); INSERT INTO zusatz VALUES(818,2,108,'2024-04-03','2024-04-10'); INSERT INTO zusatz VALUES(818,2,111,'2024-04-03','2024-04-11'); INSERT INTO zusatz VALUES(735,1,130,'2023-03-22','2024-03-29'); INSERT INTO zusatz VALUES(145863,1,35,'2023-04-14','2023-04-19'); INSERT INTO zusatz VALUES(46357,1,61,'2024-04-26','2024-05-07'); INSERT INTO zusatz VALUES(46357,1,84,'2024-04-30','2024-05-03'); INSERT INTO zusatz VALUES(46357,1,111,'2024-05-01','2024-05-03'); INSERT INTO zusatz VALUES(46357,1,130,'2024-04-30','2024-05-02'); INSERT INTO zusatz VALUES(135,1,96,'2017-09-19','2017-09-20'); INSERT INTO zusatz VALUES(135,1,108,'2017-09-19','2017-09-19'); INSERT INTO zusatz VALUES(135,1,111,'2017-09-20','2017-09-20'); INSERT INTO zusatz VALUES(24,1,142,'2021-04-16','2021-04-19'); INSERT INTO zusatz VALUES(24,3,178,'2021-08-01','2021-08-27'); INSERT INTO zusatz VALUES(24,4,47,'2021-08-01','2021-08-27'); INSERT INTO zusatz VALUES(8673,1,47,'2023-07-03','2023-07-05'); INSERT INTO zusatz VALUES(9999,1,84,'2024-05-05','2024-05-05'); INSERT INTO zusatz VALUES(9999,1,130,'2024-06-06','2024-06-07'); INSERT INTO zusatz VALUES(9999,2,130,'2024-07-01','2024-07-31'); INSERT INTO zusatz VALUES(9999,3,130,'2024-09-01','2024-09-30'); INSERT INTO zusatz VALUES(9999,3,61,'2024-09-01','2024-09-30'); INSERT INTO zusatz Values(356,1,35,'2024-01-02','2024-04-22'); INSERT INTO zusatz Values(356,1,47,'2024-01-02','2024-04-22'); INSERT INTO zusatz VALUES(221,1,50,'2022-05-25','2022-06-05',2); INSERT INTO zusatz VALUES(221,1,51,'2022-05-25','2022-06-05',2); INSERT INTO zusatz VALUES(222,1,53,'2022-04-15','2022-04-18',2); INSERT INTO zusatz VALUES(224,1,53,'2021-11-11','2021-11-15',1); INSERT INTO zusatz VALUES(225,1,52,'2020-07-31','2020-08-15',1); INSERT INTO zusatz VALUES(226,1,52,'2020-11-11','2020-11-13',1); INSERT INTO zusatz VALUES(227,1,52,'2021-01-12','2021-01-15',2); INSERT INTO zusatz VALUES(229,1,45,'2021-03-29','2021-04-07',2); INSERT INTO zusatz VALUES(230,1,45,'2021-05-03','2021-05-13',1); INSERT INTO zusatz VALUES(230,1,46,'2021-05-03','2021-05-13',1); INSERT INTO zusatz VALUES(232,1,54,'2021-09-19','2021-09-21',1); INSERT INTO zusatz VALUES(233,1,24,'2022-05-01','2022-05-05',1); INSERT INTO zusatz VALUES(234,1,25,'2022-03-03','2022-03-05',1); INSERT INTO zusatz VALUES(235,1,142,'2021-09-03','2021-09-04',4); INSERT INTO zusatz VALUES(235,1,154,'2021-09-03','2021-09-04',1); INSERT INTO zusatz VALUES(239,1,84,'2021-11-11','2021-11-15',1); INSERT INTO zusatz VALUES(240,1,111,'2022-02-11','2022-02-15',1);", + }, + { + id: 9, + name: "Use-Case Firma", + category: categories[0], + templateQuery: + "CREATE TABLE Abteilung (Abteilungsnr INT PRIMARY KEY,Abteilungsname VARCHAR(255)); CREATE TABLE Person (PersonalNr INT PRIMARY KEY,Name VARCHAR(255),Gehalt DECIMAL(10, 2),Ort VARCHAR(255),Abteilung INT,FOREIGN KEY (Abteilung) REFERENCES abteilung (abteilungsnr)); INSERT INTO Abteilung (Abteilungsnr, Abteilungsname) VALUES (1, 'EDV'),(2, 'Produktion'),(3, 'Vertrieb'),(4, 'Verwaltung'),(5, 'Entwicklung'); INSERT INTO Person (PersonalNr, Name, Gehalt, Ort, Abteilung) VALUES (100, 'Maier', 3800.00, 'Künzelsau', 1),(101, 'Müller', 4100.00, 'Künzelsau', 2),(102, 'Schmidt', 3500.00, 'Öhringen', 1),(103, 'Schulze', 4600.00, 'Heilbronn', 3),(104, 'Hinz', 4200.00, 'Heilbronn', 3),(105, 'Kunz', 4000.00, 'Schwäbisch Hall', 5);", + }, + { + id: 10, + name: "Use-Case Fussballverband", + category: categories[0], + templateQuery: + "CREATE TABLE Verein (V_Nr INT PRIMARY KEY,Name VARCHAR(255),Ort VARCHAR(255)); CREATE TABLE Spieler (Pass_Nr INT PRIMARY KEY,Name VARCHAR(255),Geburtsjahr INT); CREATE TABLE Meldung (Spieler INT,Saison VARCHAR(5),Verein INT,Einsaetze INT,Tore INT,FOREIGN KEY (Spieler) REFERENCES Spieler(Pass_Nr),FOREIGN KEY (Verein) REFERENCES Verein(V_Nr)); INSERT INTO Verein (V_Nr,Name,Ort) VALUES (1,'Schlappen-Kicker 05','Heilbronn'),(2,'Knochen-Knacker 09','Künzelsau'),(3,'Ballermann 1955','Heilbronn'),(4,'Alte Herren 1880','Schwäbisch Hall'); INSERT INTO Spieler (Pass_Nr,Name,Geburtsjahr) VALUES (1,'Peter Maier',1960),(2,'Klaus Müller',1980),(3,'Karl Hinz',1987),(4,'Thomas Kunze',1975); INSERT INTO Meldung (Spieler,Saison,Verein,Einsaetze,Tore) VALUES (1,'00/01',1,6,3),(2,'00/01',3,12,1),(3,'00/01',2,1,0),(1,'99/00',2,6,4),(4,'00/01',1,2,1);", + }, + { + id: 11, + name: "Rezepte", + category: categories[0], + templateQuery: + "CREATE TABLE benutzer (id_benutzer INT,benutzername VARCHAR(40),email VARCHAR(60),PRIMARY KEY (id_benutzer));CREATE TABLE zutat (id_zutat INT,bezeichnung VARCHAR(40),PRIMARY KEY (id_zutat));CREATE TABLE rezept (id_rezept INT,id_benutzer INT,titel VARCHAR(40),portionen INT,dauer TIME,PRIMARY KEY (id_rezept),FOREIGN KEY (id_benutzer) REFERENCES benutzer(id_benutzer));CREATE TABLE rezept_schritt (id_rezept INT,nr_schritt INT,titel VARCHAR(40),anweisung VARCHAR(200),PRIMARY KEY (id_rezept, nr_schritt),FOREIGN KEY (id_rezept) REFERENCES rezept(id_rezept));CREATE TYPE einheit AS ENUM ('ml', 'l', 'tl', 'el', 'cups', 'gr', 'kg', 'Stück');CREATE TABLE schritt_zutat (id_rezept INT,nr_schritt INT,zutat INT,menge INT,einheit einheit,PRIMARY KEY (id_rezept, nr_schritt, zutat),FOREIGN KEY (id_rezept, nr_schritt) REFERENCES rezept_schritt(id_rezept, nr_schritt),FOREIGN KEY (zutat) REFERENCES zutat(id_zutat));CREATE TABLE bewertung (id_rezept INT,id_benutzer INT,anz_sterne INT,datum DATE,PRIMARY KEY (id_rezept, id_benutzer),FOREIGN KEY (id_rezept) REFERENCES rezept(id_rezept),FOREIGN KEY (id_benutzer) REFERENCES benutzer(id_benutzer));INSERT INTO benutzer (id_benutzer, benutzername, email) VALUES (1, 'KlausMeier', 'klaus.meier@example.de'),(2, 'AnnaSchmidt', 'anna.schmidt@example.de'),(3, 'JohannesBauer', 'johannes.bauer@example.de');INSERT INTO zutat (id_zutat, bezeichnung) VALUES (1, 'Mehl'),(2, 'Zucker'),(3, 'Eier'),(4, 'Milch'),(5, 'Backpulver'),(6, 'Butter');INSERT INTO rezept (id_rezept, id_benutzer, titel, portionen, dauer) VALUES (1, 1, 'Apfelkuchen', 8, '01:30:00'),(2, 2, 'Linseneintopf', 4, '00:45:00');INSERT INTO rezept_schritt (id_rezept, nr_schritt, titel, anweisung) VALUES (1, 1, 'Vorbereitung', 'Mischen Sie Mehl und Backpulver.'),(1, 2, 'Teig kneten', 'Fügen Sie Butter und Zucker hinzu und kneten Sie den Teig.'),(1, 3, 'Backen', 'Teig in einer Form verteilen und im Ofen backen.'),(2, 1, 'Zwiebeln schneiden', 'Zwiebeln und Knoblauch fein würfeln.'),(2, 2, 'Kochen', 'Alle Zutaten in einem Topf mit Wasser aufkochen.');INSERT INTO schritt_zutat (id_rezept, nr_schritt, zutat, menge, einheit) VALUES (1, 1, 1, 200, 'gr'),(1, 1, 5, 10, 'gr'),(1, 2, 2, 150, 'gr'),(1, 2, 6, 100, 'gr'),(2, 1, 3, 2, 'Stück'),(2, 2, 4, 500, 'ml');INSERT INTO bewertung (id_rezept, id_benutzer, anz_sterne, datum) VALUES (1, 2, 4, '2023-03-21'),(2, 3, 5, '2023-03-22'),(1, 3, 3, '2023-03-23');", + }, + { + id: 12, + name: "Online-Marktplatzsystem", + category: categories[1], + templateQuery: + "CREATE TABLE Kunde (KNr SERIAL PRIMARY KEY,Vorname VARCHAR(50) NOT NULL,Nachname VARCHAR(50) NOT NULL,PLZ VARCHAR(10) NOT NULL,Registriert_am DATE NOT NULL ); CREATE TABLE Kategorie (KatNr SERIAL PRIMARY KEY,Bezeichnung VARCHAR(50) NOT NULL ); CREATE TABLE Auktion (ANr SERIAL PRIMARY KEY,Titel VARCHAR(100) NOT NULL,Beschreibung TEXT NOT NULL,Startpreis DECIMAL(10, 2) NOT NULL,Eingestellt_am DATE NOT NULL,KNr INT NOT NULL,Kategorie INT NOT NULL,FOREIGN KEY (KNr) REFERENCES Kunde(KNr),FOREIGN KEY (Kategorie) REFERENCES Kategorie(KatNr) ); CREATE TABLE Gebot (Auktion INT NOT NULL,Bieter INT NOT NULL,Geboten_am TIMESTAMP NOT NULL,Gebotspreis DECIMAL(10, 2) NOT NULL,PRIMARY KEY (Auktion, Bieter, Geboten_am),FOREIGN KEY (Auktion) REFERENCES Auktion(ANr),FOREIGN KEY (Bieter) REFERENCES Kunde(KNr) ); INSERT INTO Kunde (KNr, Vorname, Nachname, PLZ, Registriert_am) VALUES (1, 'Max', 'Mustermann', '12345', '2020-01-15'), (2, 'Anna', 'Müller', '54321', '2021-06-10'), (3, 'Peter', 'Schmidt', '98765', '2020-12-04'), (4, 'Julia', 'Meier', '67890', '2020-08-21'), (5, 'Lena', 'Fischer', '12346', '2020-02-20'), (6, 'Jonas', 'Weber', '54322', '2019-06-16'), (7, 'Emma', 'Schneider', '98764', '2019-06-17'), (8, 'Paul', 'Koch', '67891', '2020-12-02'), (9, 'Marie', 'Bauer', '12347', '2020-03-05'), (10, 'Leon', 'Hoffmann', '54323', '2021-08-25'), (11, 'Sophie', 'Schulz', '98763', '2021-05-15'), (12, 'Finn', 'Zimmermann', '67892', '2022-08-01'), (13, 'Mia', 'Lehmann', '12348', '2020-04-10'), (14, 'Noah', 'Schmid', '54324', '2019-06-28'), (15, 'Leonie', 'Hartmann', '98762', '2022-06-25'), (16, 'Elias', 'König', '67893', '2020-10-05'), (17, 'Clara', 'Winkler', '12349', '2020-05-15'), (18, 'Ben', 'Maier', '54325', '2019-10-20'), (19, 'Hanna', 'Schmitt', '98761', '2019-07-20'), (20, 'Luca', 'Walter', '67894', '2021-11-01'), (21, 'Laura', 'Lang', '12350', '2020-06-10'), (22, 'Felix', 'Klein', '54326', '2021-11-15'), (23, 'Nina', 'Peters', '98760', '2022-08-05'), (24, 'Lara', 'Hermann', '67895', '2021-12-10'), (25, 'Tim', 'Becker', '12351', '2020-07-25'), (26, 'Amelie', 'Graf', '54327', '2019-12-20'), (27, 'Oskar', 'Krüger', '98759', '2022-09-10'), (28, 'Lilly', 'Lorenz', '67896', '2022-11-20'), (29, 'Matteo', 'Fuchs', '12352', '2020-08-30'), (30, 'Johanna', 'Weiß', '54328', '2021-11-01'); INSERT INTO Kategorie (Bezeichnung) VALUES ('Elektronik'), ('Möbel'), ('Kleidung'), ('Bücher'), ('Spielzeug'), ('Haushaltsgeräte'), ('Sport & Freizeit'), ('Autos & Motorräder'), ('Immobilien'), ('Sammelobjekte'), ('Schmuck & Uhren'), ('Kosmetik'), ('Garten'), ('Tierbedarf'), ('Musikinstrumente'); INSERT INTO Auktion (ANr, Titel, Beschreibung, Startpreis, Eingestellt_am, KNr, Kategorie) VALUES (1, 'Apple iPhone 12', 'Apple iPhone 12 in gutem Zustand.', 400.00, '2022-05-15 08:20:00', 1, 1), (2, 'Wohnzimmertisch', 'Moderner Tisch aus Holz.', 80.00, '2021-08-20 12:20:00', 2, 2), (3, 'Winterjacke', 'Wasserdichte Jacke, Größe L.', 60.00, '2023-01-10 05:20:00', 3, 3), (4, 'Lego Set', 'Komplettes Set mit Figuren.', 50.00, '2022-11-05 16:20:00', 5, 5), (5, 'Mikrowelle', 'Funktioniert einwandfrei.', 30.00, '2020-06-15 12:20:00', 6, 6), (6, 'Mountainbike', 'Gut erhaltenes Fahrrad.', 200.00, '2023-04-01 01:20:00', 7, 7), (7, 'BMW 3er', 'Gebrauchtwagen, Baujahr 2015.', 5000.00, '2021-12-01 23:20:00', 8, 8), (8, 'Eigentumswohnung', 'Wohnung mit 3 Zimmern.', 200000.00, '2023-07-20 22:20:00', 9, 9), (9, 'Briefmarkensammlung', 'Raritäten aus den 80ern.', 300.00, '2020-10-10 19:20:00', 10, 10), (10, 'Goldkette', '18 Karat, neuwertig.', 150.00, '2022-03-15 18:20:00', 11, 11), (11, 'Parfüm', 'Originalflasche, 50ml.', 40.00, '2021-09-30 21:20:00', 12, 12), (12, 'Gartenmöbel', 'Set aus Tisch und 4 Stühlen.', 120.00, '2023-02-15 08:20:00', 13, 13), (13, 'Hundekörbchen', 'Großes Körbchen, neuwertig.', 25.00, '2022-08-10 09:20:00', 14, 14), (14, 'Akustikgitarre', 'Yamaha-Modell, kaum genutzt.', 180.00, '2023-05-05 08:20:00', 15, 15), (15, 'Laptop', 'HP Laptop, guter Zustand.', 350.00, '2023-10-15 12:50:00', 16, 1), (16, 'Gaming-Stuhl', 'Ergonomischer Gaming-Stuhl.', 120.00, '2023-03-10 15:50:00', 17, 2), (17, 'Designer-Schuhe', 'Schuhe von Marke X, Größe 42.', 70.00, '2021-11-05 20:50:00', 18, 3), (18, 'iPhone 10', 'Apple iPhone 10 in schlechtem Zustand.', 300.00, '2022-05-15 11:30:00', 1, 1), (19, 'iPHONE X', 'iPhone X in gutem Zustand.', 300.00, '2023-11-15 02:20:00', 2, 1), (20, 'iphone Cover', 'Schutzhülle für iPhone 12.', 20.00, '2023-11-16 03:20:28', 3, 1), (21, 'iPhones verkaufen', 'Sammlung von iPhones.', 1000.00, '2023-11-17 04:34:00', 4, 1), (22, 'iPHONE X', 'iPhone X in gutem Zustand.', 300.00, '2023-11-15 05:45:00', 2, 1), (23, 'iphone Cover', 'Schutzhülle für iPhone 12.', 20.00, '2023-11-16 06:34:00', 3, 1), (24, 'iPhones verkaufen', 'Sammlung von iPhones.', 1000.00, '2023-11-17 07:14:00', 4, 1), (25, '[iPhone 13]', 'Neues iPhone 13 in OVP.', 800.00, '2023-11-18 14:21:00', 5, 1), (26, ' iPhone 14 ', 'Brandneues iPhone 14.', 1200.00, '2023-11-19 15:01:00', 6, 1); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (1, 24, '2022-05-15 10:00:00', 410.00), (1, 2, '2022-05-16 12:00:00', 420.00), (1, 8, '2022-05-17 14:00:00', 430.00), (1, 6, '2022-05-18 16:00:00', 440.00), (1, 9, '2022-05-19 18:00:00', 450.00), (1, 29, '2022-05-20 20:00:00', 460.00), (1, 1, '2022-06-25 22:54:00', 522.03); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (2, 1, '2021-08-22 12:00:00', 90.00), (2, 5, '2021-08-23 14:00:00', 95.00), (2, 16, '2021-08-24 16:00:00', 100.00), (2, 4, '2021-08-21 10:00:00', 85.00), (2, 2, '2021-06-25 18:00:00', 120.00); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (3, 2, '2023-01-11 08:00:00', 65.00), (3, 2, '2023-01-11 08:44:00', 60.00); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (4, 1, '2022-11-06 09:20:00', 55.00), (4, 6, '2022-11-07 10:30:00', 60.00), (4, 5, '2022-11-08 11:40:00', 59.00); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (5, 6, '2020-06-16 14:00:00', 35.00), (5, 7, '2020-06-17 15:30:00', 40.00), (5, 13, '2022-11-18 20:16:00', 79.82), (5, 27, '2022-11-13 23:18:00', 127.42); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (6, 5, '2023-04-02 09:00:00', 210.00), (6, 9, '2023-04-03 11:30:00', 220.00),(6, 14, '2020-06-28 01:48:00', 55.08); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (7, 8, '2021-12-02 09:00:00', 5100.00), (7, 9, '2021-12-03 11:30:00', 5200.00), (7, 3, '2021-12-04 13:00:00', 5300.00), (7, 4, '2021-12-05 15:00:00', 5400.00), (7, 5, '2021-12-06 17:30:00', 5500.00), (7, 6, '2021-12-07 20:00:00', 5600.00), (7, 30, '2021-12-15 14:00:00', 5500.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (8, 14, '2023-07-21 10:00:00', 201000.00), (8, 15, '2023-07-22 12:30:00', 202000.00), (8, 9, '2023-07-23 15:00:00', 203000.00), (8, 12, '2023-08-01 11:30:00', 201000.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (9, 18, '2020-10-11 14:00:00', 350.00), (9, 19, '2020-10-12 16:30:00', 400.00), (9, 12, '2023-08-01 11:30:00', 201000.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (10, 10, '2022-03-16 14:00:00', 160.00), (10, 11, '2022-03-17 15:30:00', 170.00), (10, 17, '2022-03-18 17:00:00', 180.00), (10, 29, '2020-10-20 10:45:00', 500.00); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (11, 25, '2021-10-01 11:10:00', 45.00), (11, 26, '2021-10-02 12:30:00', 50.00), (11, 8, '2022-03-27 13:00:00', 230.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (12, 27, '2023-02-16 14:10:00', 125.00), (12, 28, '2023-02-17 15:20:00', 130.00), (12, 7, '2021-10-15 12:45:00', 55.0), (12, 7, '2023-10-15 12:45:00', 999999.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (13, 20, '2022-08-11 15:30:00', 30.00), (13, 21, '2022-08-12 18:45:00', 35.00), (13, 12, '2023-08-01 11:30:00', 201000.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (14, 22, '2023-05-06 10:10:00', 185.00), (14, 23, '2023-05-07 13:00:00', 190.00), (14, 24, '2023-05-08 15:30:00', 195.00), (14, 12, '2023-08-01 11:30:00', 201000.0); INSERT INTO Gebot (Auktion, Bieter, Geboten_am, Gebotspreis) VALUES (15, 12, '2023-10-16 13:00:00', 360.00), (15, 13, '2023-10-17 15:45:00', 370.00), (15, 12, '2023-08-01 11:30:00', 201000.0);", + }, + ], + }) + ); - getTemplatesByCategory(): any[] { - let templatesByCategory: any[] = []; + this.templates$ = this.store.select(selectAllTemplates); + this.categories$ = this.store.select(selectAllCategories); + this.error$ = this.store.select(selectTemplatesError); + this.activeDb$ = this.store.select(selectAllDatabases); - this.categories.forEach((category) => { - let templates = this.templates.filter( - (template) => template.category.id == category.id - ); - templatesByCategory.push({ - category: category, - templates: templates, - }); - }); - return templatesByCategory; + const globalRole = this.authService.getToken().globalRole; + this.isAdmin = Roles.GlobalRole.isAdmin(globalRole); } editTemplates() { @@ -153,9 +165,14 @@ export class DbControlTemplatesComponent implements OnInit { } insertTemplate() { - let template = this.templates.find( - (template) => template.id == this.selectedTemplateId - ); - this.submitStatement.emit(template.templateQuery); + this.templates$.subscribe((templates) => { + console.log(); + const template = templates.find( + (template) => template.id === this.selectedTemplateId + ); + if (template) { + this.submitStatement.emit(template.templateQuery); + } + }); } } diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/databases.actions.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/databases.actions.ts new file mode 100644 index 000000000..9aa12a9f2 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/databases.actions.ts @@ -0,0 +1,51 @@ +import { createAction, props } from "@ngrx/store"; +import { Database } from "src/app/model/sql_playground/Database"; + +export const loadDatabases = createAction("[Databases] Load Databases"); +export const loadDatabasesSuccess = createAction( + "[Databases] Load Databases Success", + props<{ databases: Database[] }>() +); +export const loadDatabasesFailure = createAction( + "[Databases] Load Databases Failure", + props<{ error: any }>() +); + +export const createDatabase = createAction( + "[Databases] Create Database", + props<{ name: string }>() +); +export const createDatabaseSuccess = createAction( + "[Databases] Create Database Success", + props<{ database: Database }>() +); +export const createDatabaseFailure = createAction( + "[Databases] Create Database Failure", + props<{ error: any }>() +); + +export const deleteDatabase = createAction( + "[Databases] Delete Database", + props<{ id: number }>() +); +export const deleteDatabaseSuccess = createAction( + "[Databases] Delete Database Success", + props<{ id: number }>() +); +export const deleteDatabaseFailure = createAction( + "[Databases] Delete Database Failure", + props<{ error: any }>() +); + +export const activateDatabase = createAction( + "[Databases] Activate Database", + props<{ id: number }>() +); +export const activateDatabaseSuccess = createAction( + "[Databases] Activate Database Success", + props<{ id: number }>() +); +export const activateDatabaseFailure = createAction( + "[Databases] Activate Database Failure", + props<{ error: any }>() +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/databases.effects.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/databases.effects.ts new file mode 100644 index 000000000..789624183 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/databases.effects.ts @@ -0,0 +1,123 @@ +import { Injectable } from "@angular/core"; +import { Actions, createEffect, ofType } from "@ngrx/effects"; +import { of } from "rxjs"; +import { catchError, map, mergeMap, switchMap } from "rxjs/operators"; +import { SqlPlaygroundService } from "src/app/service/sql-playground.service"; +import { MatSnackBar } from "@angular/material/snack-bar"; +import { + loadDatabases, + loadDatabasesSuccess, + loadDatabasesFailure, + createDatabase, + createDatabaseSuccess, + createDatabaseFailure, + deleteDatabase, + deleteDatabaseSuccess, + deleteDatabaseFailure, + activateDatabase, + activateDatabaseSuccess, + activateDatabaseFailure, +} from "./databases.actions"; +import { AuthService } from "../../../../service/auth.service"; +import { JWTToken } from "../../../../model/JWTToken"; +import { + changeActiveDbId, + updateScheme, +} from "../../state/sql-playground.actions"; + +@Injectable() +export class DatabasesEffects { + private token: JWTToken; + constructor( + private actions$: Actions, + private sqlPlaygroundService: SqlPlaygroundService, + private snackbar: MatSnackBar, + authService: AuthService + ) { + this.token = authService.isAuthenticated() ? authService.getToken() : null; + } + + loadDatabases$ = createEffect(() => + this.actions$.pipe( + ofType(loadDatabases), + switchMap(() => + this.sqlPlaygroundService.getDatabases(this.token.id).pipe( + switchMap((databases) => { + if (databases.length == 0) { + // create default database if none exists + return of(createDatabase({ name: "Standard Datenbank" })); + } else { + const activeId = + databases.find(({ active }) => active)?.id ?? databases[0]?.id; + return of( + loadDatabasesSuccess({ databases }), + changeActiveDbId({ dbId: activeId }), + updateScheme() + ); + } + }), + catchError((error) => of(loadDatabasesFailure({ error }))) + ) + ) + ) + ); + + createDatabase$ = createEffect(() => + this.actions$.pipe( + ofType(createDatabase), + mergeMap((action) => + this.sqlPlaygroundService + .createDatabase(this.token.id, action.name) + .pipe( + map((database) => { + this.snackbar.open("Datenbank erfolgreich erstellt", "Ok", { + duration: 3000, + }); + return createDatabaseSuccess({ database }); + }), + catchError((error) => of(createDatabaseFailure({ error }))) + ) + ) + ) + ); + + deleteDatabase$ = createEffect(() => + this.actions$.pipe( + ofType(deleteDatabase), + mergeMap((action) => + this.sqlPlaygroundService.deleteDatabase(this.token.id, action.id).pipe( + map(() => { + this.snackbar.open("Datenbank erfolgreich gelöscht", "Ok", { + duration: 3000, + }); + return deleteDatabaseSuccess({ id: action.id }); + }), + catchError((error) => of(deleteDatabaseFailure({ error }))) + ) + ) + ) + ); + + activateDatabase$ = createEffect(() => + this.actions$.pipe( + ofType(activateDatabase), + mergeMap((action) => + this.sqlPlaygroundService + .activateDatabase(this.token.id, action.id) + .pipe( + switchMap(() => { + this.snackbar.open("Datenbank erfolgreich aktiviert", "Ok", { + duration: 3000, + }); + return [ + activateDatabaseSuccess({ id: action.id }), + changeActiveDbId({ dbId: action.id }), + updateScheme(), + ]; + }), + catchError((error) => of(activateDatabaseFailure({ error }))) + ) + ) + ) + ); +} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/databases.reducer.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/databases.reducer.ts new file mode 100644 index 000000000..c897f4131 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/databases.reducer.ts @@ -0,0 +1,53 @@ +import { createReducer, on } from "@ngrx/store"; +import { Database } from "src/app/model/sql_playground/Database"; +import { + loadDatabases, + loadDatabasesSuccess, + loadDatabasesFailure, + createDatabase, + createDatabaseSuccess, + createDatabaseFailure, + deleteDatabase, + deleteDatabaseSuccess, + deleteDatabaseFailure, + activateDatabase, + activateDatabaseSuccess, + activateDatabaseFailure, +} from "./databases.actions"; + +export interface DatabasesState { + databases: Database[]; + error: any; +} + +export const initialState: DatabasesState = { + databases: [], + error: null, +}; + +export const databasesReducer = createReducer( + initialState, + on(loadDatabases, (state) => ({ ...state })), + on(loadDatabasesSuccess, (state, { databases }) => ({ ...state, databases })), + on(loadDatabasesFailure, (state, { error }) => ({ ...state, error })), + on(createDatabase, (state) => ({ ...state })), + on(createDatabaseSuccess, (state, { database }) => ({ + ...state, + databases: [...state.databases, database], + })), + on(createDatabaseFailure, (state, { error }) => ({ ...state, error })), + on(deleteDatabase, (state) => ({ ...state })), + on(deleteDatabaseSuccess, (state, { id }) => ({ + ...state, + databases: state.databases.filter((db) => db.id !== id), + })), + on(deleteDatabaseFailure, (state, { error }) => ({ ...state, error })), + on(activateDatabase, (state) => ({ ...state })), + on(activateDatabaseSuccess, (state, { id }) => ({ + ...state, + databases: state.databases.map((db) => + db.id === id ? { ...db, active: true } : { ...db, active: false } + ), + })), + on(activateDatabaseFailure, (state, { error }) => ({ ...state, error })) +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/databases.selectors.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/databases.selectors.ts new file mode 100644 index 000000000..6c14bd9b7 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/databases.selectors.ts @@ -0,0 +1,14 @@ +import { createFeatureSelector, createSelector } from "@ngrx/store"; +import { DatabasesState } from "./databases.reducer"; + +export const selectDatabasesState = + createFeatureSelector("databases"); + +export const selectAllDatabases = createSelector( + selectDatabasesState, + (state: DatabasesState) => state.databases +); +export const selectDatabasesError = createSelector( + selectDatabasesState, + (state: DatabasesState) => state.error +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/groups.actions.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/groups.actions.ts new file mode 100644 index 000000000..c04c9daf1 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/groups.actions.ts @@ -0,0 +1,12 @@ +import { createAction, props } from "@ngrx/store"; +import { Group } from "../../../../model/Group"; + +export const loadGroups = createAction("[Groups] Load Groups"); +export const loadGroupsSuccess = createAction( + "[Groups] Load Groups Success", + props<{ groups: Group[] }>() +); +export const loadGroupsFailure = createAction( + "[Groups] Load Groups Failure", + props<{ error: any }>() +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/groups.effects.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/groups.effects.ts new file mode 100644 index 000000000..95b6b5ef1 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/groups.effects.ts @@ -0,0 +1,38 @@ +import { Injectable } from "@angular/core"; +import { Actions, createEffect, ofType } from "@ngrx/effects"; +import { of } from "rxjs"; +import { catchError, switchMap } from "rxjs/operators"; +import { AuthService } from "../../../../service/auth.service"; +import { JWTToken } from "../../../../model/JWTToken"; +import { GroupRegistrationService } from "../../../../service/group-registration.sevice"; +import { + loadGroups, + loadGroupsFailure, + loadGroupsSuccess, +} from "./groups.actions"; + +@Injectable() +export class GroupsEffects { + private token: JWTToken; + constructor( + private actions$: Actions, + private groupRegistrationService: GroupRegistrationService, + authService: AuthService + ) { + this.token = authService.isAuthenticated() ? authService.getToken() : null; + } + + loadGroups = createEffect(() => + this.actions$.pipe( + ofType(loadGroups), + switchMap(() => + this.groupRegistrationService.getRegisteredGroups(this.token.id).pipe( + switchMap((groups) => { + return of(loadGroupsSuccess({ groups })); + }), + catchError((error) => of(loadGroupsFailure({ error }))) + ) + ) + ) + ); +} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/groups.reducer.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/groups.reducer.ts new file mode 100644 index 000000000..3f97e3ce5 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/groups.reducer.ts @@ -0,0 +1,24 @@ +import { createReducer, on } from "@ngrx/store"; +import { Group } from "../../../../model/Group"; +import { + loadGroups, + loadGroupsFailure, + loadGroupsSuccess, +} from "./groups.actions"; + +export interface GroupsState { + groups: Group[]; + error: any; +} + +export const initialState: GroupsState = { + groups: [], + error: null, +}; + +export const groupsReducer = createReducer( + initialState, + on(loadGroups, (state) => ({ ...state })), + on(loadGroupsSuccess, (state, { groups }) => ({ ...state, groups })), + on(loadGroupsFailure, (state, { error }) => ({ ...state, error })) +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/groups.selector.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/groups.selector.ts new file mode 100644 index 000000000..2fe96769f --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/groups.selector.ts @@ -0,0 +1,13 @@ +import { createFeatureSelector, createSelector } from "@ngrx/store"; +import { GroupsState } from "./groups.reducer"; + +export const selectGroupsState = createFeatureSelector("groups"); + +export const selectAllGroups = createSelector( + selectGroupsState, + (state: GroupsState) => state.groups +); +export const selectGroupsError = createSelector( + selectGroupsState, + (state: GroupsState) => state.error +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/templates.actions.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/templates.actions.ts new file mode 100644 index 000000000..9b5888baa --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/templates.actions.ts @@ -0,0 +1,12 @@ +import { createAction, props } from "@ngrx/store"; +import { SqlTemplates } from "../../../../model/sql_playground/SqlTemplates"; +import { TemplateCategory } from "../../../../model/sql_playground/TemplateCategory"; + +export const addTemplates = createAction( + "[Templates] Add Templates", + props<{ templates: SqlTemplates[] }>() +); +export const addCategories = createAction( + "[Templates] Add Categories", + props<{ categories: TemplateCategory[] }>() +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/templates.reducer.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/templates.reducer.ts new file mode 100644 index 000000000..8c8dfe856 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/templates.reducer.ts @@ -0,0 +1,28 @@ +import { createReducer, on } from "@ngrx/store"; +import { SqlTemplates } from "../../../../model/sql_playground/SqlTemplates"; +import { TemplateCategory } from "../../../../model/sql_playground/TemplateCategory"; +import { addCategories, addTemplates } from "./templates.actions"; + +export interface TemplatesState { + templates: SqlTemplates[]; + categories: TemplateCategory[]; + error: any; +} + +export const initialState: TemplatesState = { + templates: [], + categories: [], + error: null, +}; + +export const templatesReducer = createReducer( + initialState, + on(addTemplates, (state, { templates }) => ({ + ...state, + templates: [...state.templates, ...templates], + })), + on(addCategories, (state, { categories }) => ({ + ...state, + categories: [...state.categories, ...categories], + })) +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/templates.selectors.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/templates.selectors.ts new file mode 100644 index 000000000..7b1fc626d --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-control-panel/state/templates.selectors.ts @@ -0,0 +1,18 @@ +import { createFeatureSelector, createSelector } from "@ngrx/store"; +import { TemplatesState } from "./templates.reducer"; + +export const selectTemplatesState = + createFeatureSelector("templates"); + +export const selectAllTemplates = createSelector( + selectTemplatesState, + (state: TemplatesState) => state.templates +); +export const selectAllCategories = createSelector( + selectTemplatesState, + (state: TemplatesState) => state.categories +); +export const selectTemplatesError = createSelector( + selectTemplatesState, + (state: TemplatesState) => state.error +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-routines/db-scheme-routines.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-routines/db-scheme-routines.component.html index 587e096c0..81c81a02d 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-routines/db-scheme-routines.component.html +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-routines/db-scheme-routines.component.html @@ -1,7 +1,7 @@ -

{{ title }}

+

Routines

{{ routine.name }} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-routines/db-scheme-routines.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-routines/db-scheme-routines.component.ts index 0aa62b590..db92ea2f7 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-routines/db-scheme-routines.component.ts +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-routines/db-scheme-routines.component.ts @@ -1,12 +1,18 @@ -import { Component, Input } from "@angular/core"; +import { Component } from "@angular/core"; +import { Store } from "@ngrx/store"; +import { Observable } from "rxjs"; import { Routine } from "src/app/model/sql_playground/Routine"; -import { DbSchemeComponent } from "../db-scheme.component"; +import * as fromSqlPlayground from "../../state/sql-playground.selectors"; @Component({ selector: "app-db-scheme-routines", templateUrl: "./db-scheme-routines.component.html", styleUrls: ["../db-scheme.component.scss"], }) -export class DbSchemeRoutinesComponent extends DbSchemeComponent { - @Input() routines: Routine[]; +export class DbSchemeRoutinesComponent { + routines$: Observable; + + constructor(private store: Store) { + this.routines$ = this.store.select(fromSqlPlayground.selectRoutines); + } } diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-tables/db-scheme-tables.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-tables/db-scheme-tables.component.html index e385f7c63..c5860e42a 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-tables/db-scheme-tables.component.html +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-tables/db-scheme-tables.component.html @@ -1,6 +1,6 @@ -
-

{{ title }}

- +
+

Tables

+ {{ table.name }} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-tables/db-scheme-tables.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-tables/db-scheme-tables.component.ts index 6d03aa514..945b4f8f1 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-tables/db-scheme-tables.component.ts +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-tables/db-scheme-tables.component.ts @@ -1,53 +1,64 @@ -import { - Component, - EventEmitter, - Input, - OnChanges, - Output, -} from "@angular/core"; +import { Component, EventEmitter, OnInit, Output } from "@angular/core"; +import { Store } from "@ngrx/store"; +import { Observable, combineLatest } from "rxjs"; +import { map } from "rxjs/operators"; import { Constraint } from "src/app/model/sql_playground/Constraint"; import { Table } from "src/app/model/sql_playground/Table"; -import { DbSchemeComponent } from "../db-scheme.component"; +import * as fromSqlPlayground from "../../state/sql-playground.selectors"; @Component({ - selector: "app-db-scheme-table", + selector: "app-db-scheme-tables", templateUrl: "./db-scheme-tables.component.html", styleUrls: ["../db-scheme.component.scss"], }) -export class DbSchemeTablesComponent - extends DbSchemeComponent - implements OnChanges -{ - @Input() tables: Table[]; - @Input() constraints: Constraint[]; +export class DbSchemeTablesComponent implements OnInit { @Output() submitStatement = new EventEmitter(); - ngOnChanges() { - if (this.tables !== undefined && this.constraints !== undefined) { - this.tables.forEach((table) => { - if (this.constraints !== undefined) { - let tableConstraints = this.constraints.filter( + tables$: Observable; + constraints$: Observable; + updatedTables$: Observable; + + constructor(private store: Store) { + this.tables$ = this.store.select(fromSqlPlayground.selectTables); + this.constraints$ = this.store.select(fromSqlPlayground.selectConstraints); + } + + ngOnInit() { + this.updatedTables$ = combineLatest([this.tables$, this.constraints$]).pipe( + map(([tables, constraints]) => { + if (!tables || !constraints) return []; + + return tables.map((table) => { + const tableConstraints = constraints.find( (constraint) => constraint.table === table.name ); - if (tableConstraints[0] !== undefined) { - table.constraints = tableConstraints[0]; - table.constraints.constraints.sort((a, b) => - a.type > b.type ? -1 : 1 - ); - - table.columns.forEach((column) => { - let isPk = table.constraints.constraints.filter( - (constraint) => - constraint.columnName == column.name && - constraint.type == "PRIMARY KEY" - ); - column.isPrimaryKey = isPk.length > 0; - }); - } - } - }); - } + if (!tableConstraints) return table; + + const sortedConstraints = [...tableConstraints.constraints].sort( + (a, b) => (a.type > b.type ? -1 : 1) + ); + + const updatedColumns = table.columns.map((column) => ({ + ...column, + isPrimaryKey: sortedConstraints.some( + (constraint) => + constraint.columnName === column.name && + constraint.type === "PRIMARY KEY" + ), + })); + + return { + ...table, + constraints: { + ...tableConstraints, + constraints: sortedConstraints, + }, + columns: updatedColumns, + } as Table; + }); + }) + ); } showTableData(event: any, tableName: string): void { diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-triggers/db-scheme-triggers.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-triggers/db-scheme-triggers.component.html index 96d5f5cf6..664915501 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-triggers/db-scheme-triggers.component.html +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-triggers/db-scheme-triggers.component.html @@ -1,13 +1,14 @@ -

{{ title }}

- +

Triggers

+ {{ trigger.name }}
- {{ trigger.timing }} {{ trigger.manipulation }} {{ trigger.objecttable }} + {{ trigger.action.timing }} {{ trigger.event.manipulation }} + {{ trigger.event.objecttable }} - FOR EACH {{ trigger.orientation }} -
{{ trigger.statement }}
+ FOR EACH {{ trigger.action.orientation }} +
{{ trigger.action.statement }}
diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-triggers/db-scheme-triggers.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-triggers/db-scheme-triggers.component.ts index 48e56b324..df4296f54 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-triggers/db-scheme-triggers.component.ts +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-triggers/db-scheme-triggers.component.ts @@ -1,12 +1,18 @@ -import { Component, Input } from "@angular/core"; +import { Component } from "@angular/core"; +import { Store } from "@ngrx/store"; +import { Observable } from "rxjs"; import { Trigger } from "src/app/model/sql_playground/Trigger"; -import { DbSchemeComponent } from "../db-scheme.component"; +import * as fromSqlPlayground from "../../state/sql-playground.selectors"; @Component({ selector: "app-db-scheme-triggers", templateUrl: "./db-scheme-triggers.component.html", styleUrls: ["../db-scheme.component.scss"], }) -export class DbSchemeTriggersComponent extends DbSchemeComponent { - @Input() triggers: Trigger[]; +export class DbSchemeTriggersComponent { + triggers$: Observable; + + constructor(private store: Store) { + this.triggers$ = this.store.select(fromSqlPlayground.selectTriggers); + } } diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-views/db-scheme-views.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-views/db-scheme-views.component.html index 6ceb4e0c7..7c85ef2f2 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-views/db-scheme-views.component.html +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-views/db-scheme-views.component.html @@ -1,5 +1,5 @@ -

{{ title }}

- +

Views

+ {{ view.table }} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-views/db-scheme-views.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-views/db-scheme-views.component.ts index 18354bc00..cbfb05234 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-views/db-scheme-views.component.ts +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme-views/db-scheme-views.component.ts @@ -1,12 +1,18 @@ -import { Component, Input } from "@angular/core"; +import { Component } from "@angular/core"; +import { Store } from "@ngrx/store"; +import { Observable } from "rxjs"; import { View } from "src/app/model/sql_playground/View"; -import { DbSchemeComponent } from "../db-scheme.component"; +import * as fromSqlPlayground from "../../state/sql-playground.selectors"; @Component({ selector: "app-db-scheme-views", templateUrl: "./db-scheme-views.component.html", styleUrls: ["../db-scheme.component.scss"], }) -export class DbSchemeViewsComponent extends DbSchemeComponent { - @Input() views: View[]; +export class DbSchemeViewsComponent { + views$: Observable; + + constructor(private store: Store) { + this.views$ = this.store.select(fromSqlPlayground.selectViews); + } } diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme.component.html index e69de29bb..01593eb32 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme.component.html +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme.component.html @@ -0,0 +1,7 @@ +
+

{{ title }}

+ + + + +
diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme.component.ts index 4b81b453b..5eac9f3d1 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme.component.ts +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/db-scheme/db-scheme.component.ts @@ -1,12 +1,34 @@ -import { Component, Input } from "@angular/core"; +import { Component, Input, OnInit } from "@angular/core"; +import { Store } from "@ngrx/store"; +import { Observable } from "rxjs"; +import { Table } from "src/app/model/sql_playground/Table"; +import { View } from "src/app/model/sql_playground/View"; +import { Trigger } from "src/app/model/sql_playground/Trigger"; +import { Routine } from "src/app/model/sql_playground/Routine"; +import { Constraint } from "src/app/model/sql_playground/Constraint"; +import * as fromSqlPlayground from "../state/sql-playground.selectors"; @Component({ selector: "app-db-scheme", templateUrl: "./db-scheme.component.html", styleUrls: ["./db-scheme.component.scss"], }) -export class DbSchemeComponent { +export class DbSchemeComponent implements OnInit { @Input() title: string; - constructor() {} + tables$: Observable; + views$: Observable; + triggers$: Observable; + routines$: Observable; + constraints$: Observable; + + constructor(private store: Store) {} + + ngOnInit(): void { + this.tables$ = this.store.select(fromSqlPlayground.selectTables); + this.views$ = this.store.select(fromSqlPlayground.selectViews); + this.triggers$ = this.store.select(fromSqlPlayground.selectTriggers); + this.routines$ = this.store.select(fromSqlPlayground.selectRoutines); + this.constraints$ = this.store.select(fromSqlPlayground.selectConstraints); + } } diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/docs.txt b/modules/fbs-core/web/src/app/page-components/sql-playground/docs.txt new file mode 100644 index 000000000..7243b7d6d --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/docs.txt @@ -0,0 +1,103 @@ +Shared Types +By now, we have learned how to make an editor collaborative and how to sync document updates using different providers. But we haven't covered the most unique feature of Yjs yet: Shared Types. + +Shared types allow you to make every aspect of your application collaborative. For example, you could sync your react-state using shared types. You can sync diagrams, drawings, and even whole 3d worlds using shared types to automatically resolve conflicts. + +Shared types are similar to common data types like Array, Map, or Set. The only difference is that they automatically sync & persist their state (using the providers) and that you can observe them. + +We already learned about the Y.Text type that we "bound" to an editor instance to automatically sync a rich-text editor. Yjs supports many other shared types like Y.Array, Y.Map, and Y.Xml. A complete list, including documentation for each type, can be found in the shared types section. + +Shared type instances must be connected to a Yjs document so we can sync them. First, we define a shared type on a Yjs document. Then we can manipulate it and observe changes. + +Copy +import * as Y from 'yjs' + +const ydoc = new Y.Doc() +// Define an instance of Y.Array named "my array" +// Every peer that defines "my array" like this will sync content with this peer. +const yarray = ydoc.getArray('my array') + +// We can register change-observers like this +yarray.observe(event => { + // Log a delta every time the type changes + // Learn more about the delta format here: https://quilljs.com/docs/delta/ + console.log('delta:', event.changes.delta) +}) + +// There are a few caveats that you need to understand when working with shared types +// It is best to explain this in a few lines of code: + +// We can insert & delete content +yarray.insert(0, ['some content']) // => delta: [{ insert: ['some content'] }] +// Note that the above method accepts an array of content to insert. +// So the final document will look like this: +yarray.toArray() // => ['some content'] +// We can insert anything that is JSON-encodable. Uint8Arrays also work. +yarray.insert(0, [1, { bool: true }, new Uint8Array([1,2,3])]) // => delta: [{ insert: [1, { bool: true }, Uint8Array([1,2,3])] }] +yarray.toArray() // => [1, { bool: true }, Uint8Array([1,2,3]), 'some content'] +// You can even insert Yjs types, allowing you to create nested structures +const subArray = new Y.Array() +yarray.insert(0, [subArray]) // => delta: [{ insert: [subArray] }] +// Note that the above observer doesn't fire when you insert content into subArray +subArray.insert(0, ['nope']) // [observer not called] +// You need to create an observer on subArray instead +subArray.observe(event => { .. }) +// Alternatively you can observe deep changes on yarray (allowing you to observe child-events as well) +yarray.observeDeep(events => { console.log('All deep events: ', events) }) +subArray.insert(0, ['this works']) // => All deep events: [..] +// You can't insert the array at another place. A shared type can only exist in one place. +yarray.insert(0, [subArray]) // Throws exception! +The other data types work similarly to Y.Array. The complete documentation is available in the shared types section that covers each type and the event format in detail. + +PAGE +Shared Types +Caveats +There are some things that are not possible with shared types, but that are possible with normal data types. Most importantly, it is not possible to move a type that was inserted into a Yjs document to a different location. The other important caveat is that you shouldn't modify JSON that you inserted or retrieved from a shared type. Yjs doesn't clone the inserted objects to improve performance. So when you modify a JSON object, you will actually change the internal representation of Yjs without notifying other peers of that change. + +Copy +// 1. An inserted array must not be moved to a different location +yarray.insert(0, ymap.get("my other array") as Y.Array) // will throw an error +// 2. It is discouraged to modify JSON that is inserted or retrieved from a Yjs type +// This might lead to documents that don't synchronize anymore. +const myObject = { val: 0 } +ymap.set(0, myObject) +ymap.get(0).val = 1 // Doesn't throw an error, but is highly discouraged +myobject.val = 2 // Also doesn't throw an error, but is also discouraged. +Transactions +All changes must happen in a transaction. When you mutate a shared type without creating a transaction (e.g. yarray.insert(..)), Yjs will automatically create a transaction before manipulating the shared object. You can create transactions explicitly like this: + +Copy +const ydoc = new Y.Doc() +const ymap = ydoc.getMap('favorites') + +// set an initial value - to demonstrate the how changes in ymap are represented +ymap.set('food', 'pizza') + +// observers are called after each transaction +ymap.observe(event => { + console.log('changes', event.changes.keys) +}) + +ydoc.transact(() => { + ymap.set('food', 'pencake') + ymap.set('number', 31) +}) // => changes: Map({ number: { action: 'added' }, food: { action: 'updated', oldValue: 'pizza' } }) +Event handlers and observers are called after each transaction. If possible, you should bundle as many changes in a single transaction as possible. The advantage is that you reduce expensive observer calls and create fewer updates that are sent to other peers. + +Yjs fires events in the following order: + +ydoc.on('beforeTransaction', event => { .. }) - Called before any transaction, allowing you to store relevant information before changes happen. + +Now the transaction function is executed. + +ydoc.on('beforeObserverCalls', event => {}) + +ytype.observe(event => { .. }) - Observers are called. + +ytype.observeDeep(event => { .. }) - Deep observers are called. + +ydoc.on('afterTransaction', event => {}) - Called after each transaction. + +ydoc.on('update', update => { .. }) - This update message is propagated by the providers. + +Especially when manipulating many objects, it makes sense to reduce the creation of update messages. So use transactions whenever possible. diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/dynamic-result-table.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/dynamic-result-table.component.html index 4ce3883a5..06d43a7c4 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/dynamic-result-table.component.html +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/dynamic-result-table.component.html @@ -1,5 +1,5 @@ - + {{ "sql-playground.result-table.create-first-query" | i18nextEager }} @@ -7,11 +7,15 @@ - - - + + + - {{ tab.name }} {{ tab.id + 1 }} + {{ tab.name }} @@ -19,80 +23,9 @@ add_circle_outline -
-
-   -
-
-
- - - - close - {{ - "sql-playground.result-table.sql-error" | i18nextEager - }} - close - - - {{ - "sql-playground.result-table.check-input-error" - | i18nextEager - }} - - -

{{ tab.errorMsg }}

-
-
-
- -
-
- - - - - - - - -
- {{ col }} - - {{ row[index] }} -
-
-
- - -
- - -
-
-
-
+
diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/dynamic-result-table.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/dynamic-result-table.component.ts index 16cd91b03..1d1247942 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/dynamic-result-table.component.ts +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/dynamic-result-table.component.ts @@ -1,112 +1,74 @@ -import { - Component, - ViewChildren, - Input, - OnChanges, - SimpleChanges, - QueryList, - AfterViewInit, -} from "@angular/core"; -import { MatPaginator } from "@angular/material/paginator"; -import { MatTableDataSource } from "@angular/material/table"; +import { Component, OnInit, ViewChild } from "@angular/core"; +import { Store } from "@ngrx/store"; +import { Observable } from "rxjs"; import { ResultTab } from "src/app/model/ResultTab"; +import * as DynamicResultTableActions from "./state/dynamic-result-table.actions"; +import * as fromDynamicResultTable from "./state/dynamic-result-table.selectors"; +import * as fromSqlPlayground from "../state/sql-playground.selectors"; +import { MatTabGroup } from "@angular/material/tabs"; @Component({ selector: "app-dynamic-result-table", templateUrl: "./dynamic-result-table.component.html", styleUrls: ["./dynamic-result-table.component.scss"], -}) -export class DynamicResultTableComponent implements OnChanges, AfterViewInit { - @ViewChildren(MatPaginator) paginator = new QueryList(); - @Input() resultset: any; - @Input() isQueryPending: boolean = false; - /* dataSource = new MatTableDataSource(bigTable.rows); - displayedColumns = bigTable.head; */ - dataSource: MatTableDataSource; - displayedColumns: string[] = []; +}) //, AfterViewInit +export class DynamicResultTableComponent implements OnInit { + @ViewChild(MatTabGroup) tabGroup: MatTabGroup; - activeResId: number = 0; - tabCounter: number = 0; - tabs: ResultTab[] = []; + resultset$: Observable; + isQueryPending$: Observable; + activeTabIndex$: Observable; + tabs$: Observable; + displayedColumns$: Observable; - ngAfterViewInit() { - this.paginator.changes.subscribe(() => { - let dataSourceCounter = 0; - this.tabs.forEach((tab) => { - if (tab.dataSource !== undefined) { - tab.dataSource.paginator = - this.paginator.toArray()[dataSourceCounter]; - dataSourceCounter++; - } - }); - }); - } + tabs: ResultTab[]; + activeTabIndex: number; + isQueryPending: boolean; - ngOnChanges(changes: SimpleChanges) { - if ( - changes.isQueryPending && - changes.isQueryPending.firstChange === false - ) { - // isQueryPending changed - } + constructor(private store: Store) {} - if (changes.resultset && changes.resultset.firstChange === false) { - // isQueryPending changed - if (this.resultset !== undefined && this.resultset.error === false) { - this.dataSource = new MatTableDataSource( - this.resultset.result[0].rows - ); - this.displayedColumns = this.resultset.result[0].head; - // rename duplicate column names - let columnNames = this.displayedColumns; - let columnNamesCount = {}; - columnNames.forEach((columnName) => { - if (columnNamesCount[columnName] === undefined) { - columnNamesCount[columnName] = 1; - } else { - columnNamesCount[columnName]++; - } - }); - columnNames.forEach((columnName, index) => { - if (columnNamesCount[columnName] > 1) { - this.displayedColumns[index] = columnName + " ".repeat(index); - } - }); - } + ngOnInit(): void { + this.resultset$ = this.store.select(fromSqlPlayground.selectResultset); + this.isQueryPending$ = this.store.select( + fromSqlPlayground.selectIsQueryPending + ); + this.activeTabIndex$ = this.store.select( + fromDynamicResultTable.selectActiveTabIndex + ); + this.tabs$ = this.store.select(fromDynamicResultTable.selectTabs); + this.displayedColumns$ = this.store.select( + fromDynamicResultTable.selectDisplayedColumns + ); - if (this.tabs.length === 0) { - this.addTab(); + this.resultset$.subscribe((resultset) => { + if (resultset) { + this.store.dispatch( + DynamicResultTableActions.handleResultSetChange({ resultset }) + ); } - - this.updateActiveTab(this.activeResId); - } + }); + this.tabs$.subscribe((tabs) => { + this.tabs = tabs; + }); + this.activeTabIndex$.subscribe((activeTabIndex) => { + setTimeout(() => { + this.activeTabIndex = activeTabIndex; + }, 100); + }); + this.isQueryPending$.subscribe((isQueryPending) => { + this.isQueryPending = isQueryPending; + }); } closeTab(index: number) { - this.tabs.splice(index, 1); + this.store.dispatch(DynamicResultTableActions.closeTab({ index })); } updateActiveTab(index: number) { - this.tabs[index].error = this.resultset.error; - if (this.resultset.error == true) { - this.tabs[index].errorMsg = this.resultset.errorMsg; - } else if (this.resultset.error == false) { - this.tabs[index].dataSource = this.dataSource; - this.tabs[index].displayedColumns = this.displayedColumns; - } else { - throw new Error("Unknown error"); - } + this.store.dispatch(DynamicResultTableActions.setActiveTabIndex({ index })); } addTab() { - this.tabs.push({ - id: this.tabCounter, - name: "Ergebnis Nr.", - }); - this.tabCounter++; - - setTimeout(() => { - this.activeResId = this.tabs.length - 1; - }, 10); + this.store.dispatch(DynamicResultTableActions.addTab()); } } diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/state/dynamic-result-table.actions.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/state/dynamic-result-table.actions.ts new file mode 100644 index 000000000..2196f4f55 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/state/dynamic-result-table.actions.ts @@ -0,0 +1,48 @@ +import { createAction, props } from "@ngrx/store"; +import { ResultTab } from "src/app/model/ResultTab"; +import { DynamicResultTableState } from "./dynamic-result-table.reducer"; + +export const addTab = createAction("[Dynamic Result Table] Add Tab"); +export const closeTab = createAction( + "[Dynamic Result Table] Close Tab", + props<{ index: number }>() +); +export const updateActiveTab = createAction( + "[Dynamic Result Table] Update Active Tab", + props<{ index: number }>() +); +export const setActiveTabIndex = createAction( + "[Dynamic Result Table] Set Active Tab Index", + props<{ index: number }>() +); +export const updateResultset = createAction( + "[Dynamic Result Table] Update Resultset", + props<{ resultset: any }>() +); +export const setQueryPending = createAction( + "[Dynamic Result Table] Set Query Pending", + props<{ isQueryPending: boolean }>() +); + +export const tabAdded = createAction( + "[Dynamic Result Table] Tab Added", + props<{ tab: ResultTab; tabCounter: number }>() +); +export const tabClosed = createAction( + "[Dynamic Result Table] Tab Closed", + props<{ index: number }>() +); +export const activeTabUpdated = createAction( + "[Dynamic Result Table] Active Tab Updated", + props<{ index: number; updatedTab: Partial }>() +); + +export const handleResultSetChange = createAction( + "[Dynamic Result Table] Handle Result Set Change", + props<{ resultset: any }>() +); + +export const handleResultSetChangeSuccess = createAction( + "[Dynamic Result Table] Handle Result Set Change Success", + props<{ change: Partial }>() +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/state/dynamic-result-table.effects.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/state/dynamic-result-table.effects.ts new file mode 100644 index 000000000..fa500b05d --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/state/dynamic-result-table.effects.ts @@ -0,0 +1,116 @@ +import { Injectable } from "@angular/core"; +import { Actions, createEffect, ofType } from "@ngrx/effects"; +import { Store } from "@ngrx/store"; +import { map, withLatestFrom, switchMap } from "rxjs/operators"; +import * as DynamicResultTableActions from "./dynamic-result-table.actions"; +import * as fromDynamicResultTable from "./dynamic-result-table.selectors"; +import { DynamicResultTableState } from "./dynamic-result-table.reducer"; +import { of } from "rxjs"; + +@Injectable() +export class DynamicResultTableEffects { + constructor(private actions$: Actions, private store: Store) {} + + addTab$ = createEffect(() => + this.actions$.pipe( + ofType(DynamicResultTableActions.addTab), + withLatestFrom( + this.store.select(fromDynamicResultTable.selectTabCounter), + this.store.select(fromDynamicResultTable.selectTabs) + ), + switchMap(([_action, tabCounter, _tabs]) => { + const newTab = { + id: crypto.randomUUID(), + name: `Ergebnis Nr. ${tabCounter}`, + }; + return of( + DynamicResultTableActions.tabAdded({ + tab: newTab, + tabCounter: tabCounter + 1, + }) + ); + }) + ) + ); + + closeTab$ = createEffect(() => + this.actions$.pipe( + ofType(DynamicResultTableActions.closeTab), + map((action) => + DynamicResultTableActions.tabClosed({ index: action.index }) + ) + ) + ); + + updateActiveTab$ = createEffect(() => + this.actions$.pipe( + ofType(DynamicResultTableActions.updateActiveTab), + withLatestFrom( + this.store.select(fromDynamicResultTable.selectResultset), + this.store.select(fromDynamicResultTable.selectDisplayedColumns) + ), + map(([action, resultset, displayedColumns]) => { + console.log(resultset); + const updatedTab = { + error: resultset.error, + errorMsg: resultset.error ? resultset.errorMsg : null, + displayedColumns: resultset.error ? [] : displayedColumns, + resultset: resultset, + }; + console.log(updatedTab); + return DynamicResultTableActions.activeTabUpdated({ + index: action.index, + updatedTab, + }); + }) + ) + ); + + handleResultSetChange$ = createEffect(() => + this.actions$.pipe( + ofType(DynamicResultTableActions.handleResultSetChange), + withLatestFrom( + this.store.select(fromDynamicResultTable.selectTabs), + this.store.select(fromDynamicResultTable.selectActiveTabIndex) + ), + switchMap(([action, tabs, activeTabIndex]) => { + const { resultset } = action; + + const updatedTabs = + tabs.length === 0 + ? [{ id: crypto.randomUUID(), name: "Result 1" }] + : tabs; + const newTabIndex = tabs.length === 0 ? 0 : activeTabIndex; + + let change = { + resultset, + tabs: updatedTabs, + activeResId: newTabIndex, + } as Partial; + console.log(change); + + if (resultset && !resultset.error) { + let displayedColumns = resultset.result[0].head; + const columnNamesCount = {}; + displayedColumns.forEach((columnName) => { + columnNamesCount[columnName] = + (columnNamesCount[columnName] || 0) + 1; + }); + displayedColumns = displayedColumns.map((columnName, index) => + columnNamesCount[columnName] > 1 + ? columnName + " ".repeat(index) + : columnName + ); + + change = { ...change, displayedColumns }; + } + return [ + DynamicResultTableActions.handleResultSetChangeSuccess({ change }), + DynamicResultTableActions.updateActiveTab({ + index: newTabIndex, + }), + ]; + }) + ) + ); +} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/state/dynamic-result-table.reducer.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/state/dynamic-result-table.reducer.ts new file mode 100644 index 000000000..b40a3c04a --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/state/dynamic-result-table.reducer.ts @@ -0,0 +1,66 @@ +import { createReducer, on } from "@ngrx/store"; +import { ResultTab } from "src/app/model/ResultTab"; +import * as DynamicResultTableActions from "./dynamic-result-table.actions"; + +export interface DynamicResultTableState { + resultset: any; + isQueryPending: boolean; + activeTabIndex: number; + tabCounter: number; + tabs: ResultTab[]; + displayedColumns: string[]; +} + +const initialState: DynamicResultTableState = { + resultset: null, + isQueryPending: false, + activeTabIndex: 0, + tabCounter: 0, + tabs: [], + displayedColumns: [], +}; + +export const dynamicResultTableReducer = createReducer( + initialState, + on(DynamicResultTableActions.tabAdded, (state, { tab, tabCounter }) => ({ + ...state, + tabs: [...state.tabs, tab], + tabCounter, + activeTabIndex: state.tabs.length, + })), + on(DynamicResultTableActions.tabClosed, (state, { index }) => ({ + ...state, + tabs: state.tabs.filter((_, i) => i !== index), + })), + on( + DynamicResultTableActions.activeTabUpdated, + (state, { index, updatedTab }) => ({ + ...state, + tabs: state.tabs.map((tab, i) => + i === index ? { ...tab, ...updatedTab } : tab + ), + }) + ), + on(DynamicResultTableActions.setActiveTabIndex, (state, { index }) => ({ + ...state, + activeTabIndex: index, + })), + on(DynamicResultTableActions.updateResultset, (state, { resultset }) => ({ + ...state, + resultset, + })), + on( + DynamicResultTableActions.setQueryPending, + (state, { isQueryPending }) => ({ + ...state, + isQueryPending, + }) + ), + on( + DynamicResultTableActions.handleResultSetChangeSuccess, + (state, { change }) => ({ + ...state, + ...change, + }) + ) +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/state/dynamic-result-table.selectors.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/state/dynamic-result-table.selectors.ts new file mode 100644 index 000000000..a1e1dd14d --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/state/dynamic-result-table.selectors.ts @@ -0,0 +1,35 @@ +import { createFeatureSelector, createSelector } from "@ngrx/store"; +import { DynamicResultTableState } from "./dynamic-result-table.reducer"; + +export const selectDynamicResultTableState = + createFeatureSelector("dynamicResultTable"); + +export const selectResultset = createSelector( + selectDynamicResultTableState, + (state: DynamicResultTableState) => state.resultset +); + +export const selectIsQueryPending = createSelector( + selectDynamicResultTableState, + (state: DynamicResultTableState) => state.isQueryPending +); + +export const selectActiveTabIndex = createSelector( + selectDynamicResultTableState, + (state: DynamicResultTableState) => state.activeTabIndex +); + +export const selectTabs = createSelector( + selectDynamicResultTableState, + (state: DynamicResultTableState) => state.tabs +); + +export const selectDisplayedColumns = createSelector( + selectDynamicResultTableState, + (state: DynamicResultTableState) => state.displayedColumns +); + +export const selectTabCounter = createSelector( + selectDynamicResultTableState, + (state: DynamicResultTableState) => state.tabCounter +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/tab/dynamic-result-table-tab.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/tab/dynamic-result-table-tab.component.html new file mode 100644 index 000000000..28f1a944e --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/tab/dynamic-result-table-tab.component.html @@ -0,0 +1,69 @@ +
+
+   +
+
+
+ + + + close + {{ + "sql-playground.result-table.sql-error" | i18nextEager + }} + close + + + {{ + "sql-playground.result-table.check-input-error" | i18nextEager + }} + + +

{{ tab.errorMsg }}

+
+
+
+ +
+
+ + + + + + + + +
+ {{ col }} + + {{ row[index] }} +
+
+
+
+ +
+
+
+
diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/tab/dynamic-result-table-tab.component.scss b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/tab/dynamic-result-table-tab.component.scss new file mode 100644 index 000000000..e2c233f4a --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/tab/dynamic-result-table-tab.component.scss @@ -0,0 +1,88 @@ +.container { + display: block; + width: 100%; + justify-content: center; + align-items: center; + flex-wrap: wrap; +} + +.action-container { + position: relative; + bottom: 0px; + overflow: hidden; + display: grid; + align-items: center; + grid-template-columns: repeat(3, minmax(0, 1fr)); + grid-template-rows: 40px; + margin-top: 5px; + height: 40px; + + mat-paginator { + background: transparent; + } + + button { + grid-row-start: 1; + grid-row-end: 1; + grid-column-start: 1; + grid-column-end: 1; + height: fit-content; + width: fit-content; + background: inherit; + border: none; + color: rgba(0, 0, 0, 0.54); + cursor: pointer; + } + + button:hover { + color: black; + } +} + +.table-container { + display: block; + min-height: 100px; + max-height: 350px; + overflow-x: auto; + + table { + width: 90%; + margin: 10px; + } +} + +.cells { + width: fit-content; + padding: 5px 15px 5px 15px; + white-space: nowrap; +} + +.table-row { + height: 10px; +} + +.error-icon { + color: #f44336; +} + +mat-card-title { + display: flex; + justify-content: flex-start; + align-items: center; +} + +.spinner { + margin-top: 50px; + display: flex; + justify-content: center; + align-items: center; +} + +.info-card{ + //center the card + display: flex; + justify-content: center; + align-items: center; + flex-wrap: wrap; + margin: 15px 40px; +} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/tab/dynamic-result-table-tab.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/tab/dynamic-result-table-tab.component.ts new file mode 100644 index 000000000..0a5a31eb3 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/dynamic-result-table/tab/dynamic-result-table-tab.component.ts @@ -0,0 +1,61 @@ +import { + Component, + Input, + AfterViewInit, + ViewChild, + SimpleChanges, + OnChanges, +} from "@angular/core"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatTableDataSource } from "@angular/material/table"; +import { + selectIsQueryPending, + selectTabs, +} from "../state/dynamic-result-table.selectors"; +import { Store } from "@ngrx/store"; +import { ResultTab } from "../../../../model/ResultTab"; +import { Subscription } from "rxjs"; + +@Component({ + selector: "app-dynamic-result-table-tab", + templateUrl: "./dynamic-result-table-tab.component.html", + styleUrls: ["./dynamic-result-table-tab.component.scss"], +}) +export class DynamicResultTableTabComponent + implements OnChanges, AfterViewInit +{ + @Input() index: number; + @ViewChild(MatPaginator) paginator: MatPaginator; + private subscription: Subscription; + + constructor(private store: Store) {} + + $isQueryPending = this.store.select(selectIsQueryPending); + $tabs = this.store.select(selectTabs); + tab: ResultTab; + + dataSource: MatTableDataSource; + + ngOnChanges(changes: SimpleChanges) { + if (changes["index"]) { + if (this.subscription) this.subscription.unsubscribe(); + this.subscription = this.$tabs.subscribe((tabs) => { + console.log("tabs", { tabs, index: this.index }); + this.tab = tabs[this.index]; + const results = this.tab?.resultset?.result?.[0]; + console.log("TAB", this.tab); + console.log("results", results); + if (!results) return; + console.log(results); + this.dataSource = new MatTableDataSource(results.rows); + this.dataSource.paginator = this.paginator; + console.log("np", this.dataSource.paginator); + }); + } + } + + ngAfterViewInit(): void { + if (!this.paginator) return; + this.dataSource.paginator = this.paginator; + } +} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/highlighted-input/highlighted-input.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/highlighted-input/highlighted-input.component.html index 1794ab045..394fbd866 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/highlighted-input/highlighted-input.component.html +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/highlighted-input/highlighted-input.component.html @@ -9,7 +9,6 @@ formControlName="content" spellcheck="false" (keydown.tab)="onTab($event)" - (ngModelChange)="updateSubmission($event)" wrap="hard" >
 = new EventEmitter();
-  @Input() tabs: any[];
-  @Input() selectedIndex: number;
-
-  sub!: Subscription;
-  highlighted = false;
+export class HighlightedInputComponent implements OnDestroy, AfterViewInit {
+  @ViewChild("textArea") textArea!: ElementRef;
+  @ViewChild("codeContent") codeContent!: ElementRef;
+  @ViewChild("pre") pre!: ElementRef;
+
+  subs: Subscription[] = [];
   codeType = "sql";
 
   groupForm = new FormGroup({
@@ -40,6 +35,10 @@ export class HighlightedInputComponent
   });
 
   titleText: any;
+  @Output() update = new EventEmitter();
+
+  private lastUpdated: string;
+  @Input() index!: number;
 
   get contentControl() {
     return this.groupForm.get("content")?.value;
@@ -48,82 +47,66 @@ export class HighlightedInputComponent
   constructor(
     private prismService: PrismService,
     private fb: FormBuilder,
-    private renderer: Renderer2
+    private renderer: Renderer2,
+    private store: Store
   ) {}
 
-  ngOnChanges(changes): void {
-    if (changes.selectedIndex) {
-      this.listenForm();
-    }
-  }
-
-  ngOnInit(): void {
-    this.listenForm();
-    //this.synchronizeScroll();
-  }
-
   ngAfterViewInit() {
-    this.prismService.highlightAll();
+    this.listenForm();
   }
 
-  ngAfterViewChecked() {
-    if (this.highlighted) {
-      this.prismService.highlightAll();
-      this.highlighted = false;
-    }
+  private unsubscribe() {
+    this.subs.forEach((sub) => sub.unsubscribe());
+    this.subs = [];
   }
 
   ngOnDestroy() {
-    this.sub?.unsubscribe();
+    this.unsubscribe();
   }
 
-  updateSubmission(event) {
-    let cleanedText = this.cleanText(event);
-
-    if (cleanedText !== event) {
-      this.groupForm.patchValue({ content: cleanedText });
-    }
+  listenForm() {
+    this.unsubscribe();
+    this.subs.push(
+      this.store
+        .select(fromSqlInputTabs.selectTabs)
+        .pipe(map((tabs) => tabs[this.index]))
+        .subscribe((activeTab) => {
+          this.groupForm.setValue({
+            content: activeTab?.content ?? "",
+          });
+          this.render(activeTab?.content ?? "");
+        })
+    );
 
-    this.update.emit({ content: event });
+    this.subs.push(
+      this.groupForm.valueChanges
+        .pipe(map((val: any) => val.content))
+        .subscribe((content: string) => {
+          this.render(content);
+
+          if (content !== this.lastUpdated) {
+            this.lastUpdated = content;
+            this.store.dispatch(
+              SqlInputTabsActions.updateTabContent({
+                index: this.index,
+                content: content,
+              })
+            );
+          }
+        })
+    );
   }
 
-  listenForm() {
-    if (this.tabs[this.selectedIndex].content !== null) {
-      this.groupForm.setValue({
-        content: this.tabs[this.selectedIndex].content,
-      });
-    }
-    this.sub = this.groupForm.valueChanges.subscribe((val: any) => {
-      const modifiedContent = this.prismService.convertHtmlIntoString(
-        val.content
-      );
-
-      this.renderer.setProperty(
-        this.codeContent.nativeElement,
-        "innerHTML",
-        modifiedContent
-      );
-
-      this.highlighted = true;
-    });
-  }
+  private render(content: string) {
+    const modifiedContent = this.prismService.convertHtmlIntoString(content);
 
-  synchronizeScroll() {
-    const localSub = fromEvent(this.textArea.nativeElement, "scroll").subscribe(
-      () => {
-        const toTop = this.textArea.nativeElement.scrollTop;
-        const toLeft = this.textArea.nativeElement.scrollLeft;
-
-        this.renderer.setProperty(this.pre.nativeElement, "scrollTop", toTop);
-        this.renderer.setProperty(
-          this.pre.nativeElement,
-          "scrollLeft",
-          toLeft + 0.2
-        );
-      }
+    this.renderer.setProperty(
+      this.codeContent.nativeElement,
+      "innerHTML",
+      modifiedContent
     );
 
-    this.sub.add(localSub);
+    this.prismService.highlight(this.codeContent.nativeElement);
   }
 
   onTab(event) {
@@ -142,8 +125,6 @@ export class HighlightedInputComponent
   }
 
   cleanText(text: string) {
-    console.log(text);
-
     // allow only caracteres for valid sql query
     text = text.replace(
       /[^a-zA-Z0-9üöäÄÖÜß\(\)\[\]\{\}\s\.\,\;\=\+\-\*\/\>\<\!\@\#\$\?\%\^\&\_\~\`´°²³§\:\'\"\|\\]/g,
diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/sql-input-tabs.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/sql-input-tabs.component.html
index d68b5c64d..913103ec9 100644
--- a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/sql-input-tabs.component.html
+++ b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/sql-input-tabs.component.html
@@ -13,8 +13,8 @@
     mat-button
     matTooltip="{{ 'sql-playground.input.tooltip.downloadTab' | i18nextEager }}"
     matTooltipPosition="right"
-    [disabled]="pending"
-    (click)="downloadFile()"
+    [disabled]="isPending"
+    (click)="downloadFile(activeTabIndex)"
   >
     download
   
@@ -24,19 +24,21 @@
       'sql-playground.input.tooltip.downloadAllTabs' | i18nextEager
     }}"
     matTooltipPosition="right"
-    [disabled]="pending"
+    [disabled]="isPending"
     (click)="downloadAllFiles()"
   >
     folder
   
 
- - + +
- -
@@ -60,43 +74,37 @@

{{ "sql-playground.input.label.taskDescription" | i18nextEager }} - {{ activeTab.selectedTask.description }} + {{ activeTab?.selectedTask.description }}

- -
{{ "sql-playground.input.label.errorMessage" | i18nextEager }} -
{{ activeTab.errorMsg }}
+
{{ activeTab?.errorMsg }}
-
+
@@ -153,7 +165,7 @@ matTooltip="{{ 'sql-playground.input.tooltip.submissionStatusWrong' | i18nextEager }}" - *ngIf="activeTab.isSubmitted && !pending && !activeTab.isCorrect" + *ngIf="activeTab?.isSubmitted && !isPending && !activeTab?.isCorrect" >cancel check_circle - {{ "sql-playground.input.label.processing" | i18nextEager }} + + + {{ "sql-playground.input.label.processing" | i18nextEager }} +
diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/sql-input-tabs.component.scss b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/sql-input-tabs.component.scss index c1e264a0d..ca44c2a75 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/sql-input-tabs.component.scss +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/sql-input-tabs.component.scss @@ -144,3 +144,16 @@ // margin-right: 10px; // cursor: pointer; } + +.circle { + width: 20px; + height: 20px; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + font-size: 12px; + font-weight: bold; + color: white; + background-color: white; +} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/sql-input-tabs.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/sql-input-tabs.component.ts index dc7470d24..f4e6ac716 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/sql-input-tabs.component.ts +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/sql-input-tabs.component.ts @@ -1,33 +1,31 @@ import { + Component, + OnInit, AfterViewChecked, AfterViewInit, - Component, ElementRef, - EventEmitter, + ViewChild, HostListener, - Input, - OnInit, + EventEmitter, Output, - Renderer2, - ViewChild, } from "@angular/core"; import { MatDialog } from "@angular/material/dialog"; -import { ConfirmDialogComponent } from "src/app/dialogs/confirm-dialog/confirm-dialog.component"; -import { FormControl, FormGroup, UntypedFormControl } from "@angular/forms"; import { MatSnackBar } from "@angular/material/snack-bar"; -import { AuthService } from "src/app/service/auth.service"; +import { Store } from "@ngrx/store"; import { Observable, of } from "rxjs"; -import { Course } from "src/app/model/Course"; -import { CourseRegistrationService } from "../../../service/course-registration.service"; -import { repeat, takeWhile } from "rxjs/operators"; +import { map, take } from "rxjs/operators"; +import { AuthService } from "src/app/service/auth.service"; +import { CourseRegistrationService } from "src/app/service/course-registration.service"; +import { PrismService } from "src/app/service/prism.service"; import { TaskService } from "src/app/service/task.service"; +import { Course } from "src/app/model/Course"; import { Task } from "src/app/model/Task"; -import { SubmissionService } from "../../../service/submission.service"; -import { PrismService } from "src/app/service/prism.service"; -import { Subscription } from "rxjs"; -import { CheckerService } from "src/app/service/checker.service"; import { QueryTab } from "src/app/model/sql_playground/QueryTab"; -import { I18NextPipe } from "angular-i18next"; +import { ConfirmDialogComponent } from "src/app/dialogs/confirm-dialog/confirm-dialog.component"; +import * as SqlInputTabsActions from "./state/sql-input-tabs.actions"; +import * as fromSqlInputTabs from "./state/sql-input-tabs.selectors"; +import * as fromSqlPlayground from "../state/sql-playground.selectors"; +import { FormControl, FormGroup } from "@angular/forms"; @Component({ selector: "app-sql-input-tabs", @@ -37,23 +35,22 @@ import { I18NextPipe } from "angular-i18next"; export class SqlInputTabsComponent implements OnInit, AfterViewChecked, AfterViewInit { - @Input() isPending: boolean; @Output() submitStatement = new EventEmitter(); + isPending: boolean; + activeTabIndex: number; + tabs: QueryTab[]; + activeTab: QueryTab; + @HostListener("window:keyup", ["$event"]) keyEvent(event: KeyboardEvent) { if (event.ctrlKey && event.key === "Enter") { - // Your row selection code this.submission(); } } - @ViewChild("textArea", { static: true }) - textArea!: ElementRef; - @ViewChild("codeContent", { static: true }) - codeContent!: ElementRef; - @ViewChild("pre", { static: true }) - pre!: ElementRef; - - sub!: Subscription; + @ViewChild("textArea", { static: true }) textArea!: ElementRef; + @ViewChild("codeContent", { static: true }) codeContent!: ElementRef; + @ViewChild("pre", { static: true }) pre!: ElementRef; + highlighted = false; codeType = "sql"; @@ -65,111 +62,78 @@ export class SqlInputTabsComponent return this.groupForm.get("content")?.value; } + isPending$: Observable; + tabs$: Observable; + activeTab$: Observable; + activeTabIndex$: Observable; + courses: Observable = of(); + allTasksFromCourse: Task[] = []; + filteredTasksFromCourse: Task[] = []; + isDescriptionMode: boolean = false; + isCheckerEmpty: boolean; + constructor( private dialog: MatDialog, private snackbar: MatSnackBar, private authService: AuthService, private courseRegistrationService: CourseRegistrationService, - private submissionService: SubmissionService, private taskService: TaskService, private prismService: PrismService, - private renderer: Renderer2, - private checkerService: CheckerService, - private i18nextPipe: I18NextPipe + private store: Store ) {} + ngAfterViewChecked() { if (this.highlighted) { this.prismService.highlightAll(); this.highlighted = false; } } + ngAfterViewInit() { this.prismService.highlightAll(); } - tabs: QueryTab[] = []; - activeTabId = new UntypedFormControl(0); - activeTab: QueryTab; - pending: boolean = false; - courses: Observable = of(); - control: UntypedFormControl = new UntypedFormControl(); - allTasksFromCourse: Task[]; - filteredTasksFromCourse: Task[] = []; - isDescriptionMode: boolean = false; - isCheckerEmpty: boolean; - ngOnInit(): void { const userID = this.authService.getToken().id; this.courses = this.courseRegistrationService.getRegisteredCourses(userID); - this.activeTabId.valueChanges.subscribe((value) => { - this.activeTab = this.tabs[value]; + + this.isPending$ = this.store.select(fromSqlPlayground.selectIsQueryPending); + this.tabs$ = this.store.select(fromSqlInputTabs.selectTabs); + this.activeTab$ = this.store.select(fromSqlInputTabs.selectActiveTab); + this.activeTabIndex$ = this.store.select( + fromSqlInputTabs.selectActiveTabIndex + ); + + this.store.dispatch(SqlInputTabsActions.loadTabsFromLocalStorage()); + + this.isPending$.subscribe((isPending) => (this.isPending = isPending)); + this.activeTabIndex$.subscribe((index) => (this.activeTabIndex = index)); + this.tabs$.subscribe((tabs) => { + this.tabs = tabs; }); - this.loadFromLocalStorage(); + this.activeTab$.subscribe((activeTab) => (this.activeTab = activeTab)); } closeTab(index: number) { this.openConfirmDialog( - "Möchtest du wirklich diesen " + this.tabs[index].name + " schließen?", + "Möchtest du wirklich diesen Tab schließen?", "Achtung der Inhalt wird nicht gespeichert!" ).subscribe((result) => { - if (result == true) { - this.deleteFromLocalStorage(index); - this.tabs.splice(index, 1); - this.activeTabId.setValue(this.tabs.length - 1); - this.loadFromLocalStorage(); + if (result) { + this.store.dispatch(SqlInputTabsActions.closeTab({ index })); } }); } saveToLocalStorage() { - const data = { tabs: this.tabs }; - localStorage.setItem("tabs", JSON.stringify(data)); - } - - loadFromLocalStorage() { - const loadedData = localStorage.getItem("tabs"); - - if (loadedData && JSON.parse(loadedData).tabs.length > 0) { - this.tabs = JSON.parse(loadedData).tabs; - this.activeTab = this.tabs[this.activeTabId.value]; - } else { - this.addTab(); - } - } - - deleteFromLocalStorage(index: number) { - const data = JSON.parse(localStorage.getItem("tabs")); - data.tabs.splice(index, 1); - localStorage.setItem("tabs", JSON.stringify(data)); - } - - updateSubmissionContent(data: String) { - let submissionContent = data["content"]; - this.tabs[this.activeTabId.value].content = submissionContent; - this.saveToLocalStorage(); + this.store.dispatch(SqlInputTabsActions.saveTabsToLocalStorage()); } addTab(event?: MouseEvent) { if (event) { event.stopPropagation(); } - this.tabs.push({ - name: this.i18nextPipe.transform("sql-playground.input.new-query"), - content: "", - error: false, - errorMsg: null, - isCorrect: false, - isSubmitted: false, - isSubmitMode: false, - selectedCourse: undefined, - selectedTask: undefined, - selectedCourseName: this.i18nextPipe.transform( - "sql-playground.input.course" - ), - selectedTaskName: this.i18nextPipe.transform("sql-playground.input.task"), - }); - this.activeTabId.setValue(this.tabs.length - 1); - this.saveToLocalStorage(); + this.store.dispatch(SqlInputTabsActions.addTab({})); } closeAllTabs(event?: MouseEvent) { @@ -180,10 +144,8 @@ export class SqlInputTabsComponent "Möchtest du wirklich alle Tabs schließen?", "Achtung der Inhalt wird nicht gespeichert!" ).subscribe((result) => { - if (result == true) { - this.tabs = []; - this.addTab(); - this.saveToLocalStorage(); + if (result) { + this.store.dispatch(SqlInputTabsActions.closeAllTabs()); } }); } @@ -198,18 +160,8 @@ export class SqlInputTabsComponent return dialogRef.afterClosed(); } - downloadFile() { - var file = new Blob([this.activeTab.content], { type: ".txt" }); - var a = document.createElement("a"), - url = URL.createObjectURL(file); - a.href = url; - a.download = this.activeTab.name + ".sql"; - document.body.appendChild(a); - a.click(); - setTimeout(function () { - document.body.removeChild(a); - window.URL.revokeObjectURL(url); - }, 0); + downloadFile(index: number) { + this.store.dispatch(SqlInputTabsActions.downloadFile({ index })); } downloadAllFiles() { @@ -217,87 +169,55 @@ export class SqlInputTabsComponent "Möchtest du wirklich alle Dateien herunterladen?", "" ).subscribe((result) => { - if (result == true) { - for (let i = 0; i < this.tabs.length; i++) { - var file = new Blob([this.tabs[i].content], { type: ".txt" }); - var a = document.createElement("a"), - url = URL.createObjectURL(file); - a.href = url; - a.download = this.tabs[i].name + ".sql"; - document.body.appendChild(a); - a.click(); - setTimeout(function () { - document.body.removeChild(a); - window.URL.revokeObjectURL(url); - }, 200); - } + if (result) { + this.store.dispatch(SqlInputTabsActions.downloadAllFiles()); } }); } - isSubmissionEmpty(): boolean { - if ( - this.activeTab != undefined && - this.activeTab.content != "" && - this.pending == false - ) { - return false; - } - return true; + isSubmissionEmpty(): Observable { + return this.activeTab$.pipe( + map( + (activeTab) => !activeTab || activeTab.content === "" || this.isPending + ) + ); } submission(): void { - if (this.isSubmissionEmpty()) { - this.snackbar.open("Sie haben keine Lösung abgegeben", "Ups!"); - return; - } - this.submitStatement.emit(this.activeTab.content); + this.isSubmissionEmpty() + .pipe(take(1)) + .subscribe((isEmpty) => { + if (isEmpty) { + this.snackbar.open("Sie haben keine Lösung abgegeben", "Ups!"); + } else { + this.activeTabIndex$.pipe(take(1)).subscribe((index) => { + this.store.dispatch(SqlInputTabsActions.submission({ index })); + }); + } + }); } - updateMode(value: boolean) { - this.activeTab.isSubmitMode = value; - this.pending = false; + updateMode(index: number, value: boolean) { + this.store.dispatch(SqlInputTabsActions.updateMode({ index, value })); } - hasDeadlinePassed(task: Task = this.activeTab.selectedTask): boolean { - if (task == null) { + hasDeadlinePassed(task: Task): boolean { + if (!task) { return true; } return Date.now() > Date.parse(task.deadline); } - emptyTask() { - this.activeTab.selectedTask = null; - this.filteredTasksFromCourse = []; - this.activeTab.selectedTaskName = "Aufgabe"; + changeCourse(index: number, course: Course) { + this.store.dispatch(SqlInputTabsActions.changeCourse({ index, course })); } - changeCourse(course: Course) { - this.activeTab.selectedCourse = course; - this.activeTab.selectedCourseName = this.activeTab.selectedCourse.name; - this.activeTab.error = false; - this.activeTab.isSubmitted = false; - this.getTasks(); - this.emptyTask(); - this.saveToLocalStorage(); - } - - changeTask(task: Task) { - this.activeTab.selectedTask = task; - this.activeTab.selectedTaskName = this.activeTab.selectedTask.name; - this.activeTab.error = false; - this.activeTab.isSubmitted = false; - this.checkerService - .checkForCheckerConfig( - this.activeTab.selectedCourse.id, - this.activeTab.selectedTask.id - ) - .subscribe((res) => (this.isCheckerEmpty = res)); - this.saveToLocalStorage(); + changeTask(index: number, task: Task) { + this.store.dispatch(SqlInputTabsActions.changeTask({ index, task })); } - getTasks() { - this.taskService.getAllTasks(this.activeTab.selectedCourse.id).subscribe( + getTasks(courseId: number) { + this.taskService.getAllTasks(courseId).subscribe( (allTasks) => { this.allTasksFromCourse = allTasks; this.filterTasks(); @@ -307,11 +227,10 @@ export class SqlInputTabsComponent } private filterTasks() { - for (let task of this.allTasksFromCourse) { - if (task.mediaType == "text/plain" && !this.hasDeadlinePassed(task)) { - this.filteredTasksFromCourse.push(task); - } - } + this.filteredTasksFromCourse = this.allTasksFromCourse.filter( + (task) => task.mediaType === "text/plain" && !this.hasDeadlinePassed(task) + ); + if (this.filteredTasksFromCourse.length < 1) { this.snackbar.open("Dieser Kurs hat keine SQL Aufgaben!", "OK", { duration: 3000, @@ -319,93 +238,26 @@ export class SqlInputTabsComponent } } - wasSubmissionCorrect(subResult: number) { - if (subResult != 0) { - this.activeTab.isCorrect = false; - this.activeTab.error = true; - } else { - this.activeTab.isCorrect = true; - this.activeTab.error = false; - } + setActiveTab(index: number) { + this.store.dispatch(SqlInputTabsActions.setActiveTab({ index })); } - waitForSubDone(sid: number) { - const token = this.authService.getToken(); - this.submissionService - .getSubmission( - token.id, - this.activeTab.selectedCourse.id, - this.activeTab.selectedTask.id, - sid - ) - .pipe( - repeat(), - takeWhile((sub) => !sub.done, true) - ) - .subscribe( - (res) => { - if (res.done) { - if (res.results[0].exitCode == 0) { - this.activeTab.errorMsg = null; - this.wasSubmissionCorrect(res.results[0].exitCode); - this.pending = false; - this.activeTab.isSubmitted = true; - } else { - this.wasSubmissionCorrect(res.results[0].exitCode); - this.activeTab.errorMsg = res.results[0].resultText; - this.pending = false; - this.activeTab.isSubmitted = true; - } - } - }, - () => {}, //handle error - () => console.log("Submission Request Complete") - ); + updateTabContent(index: number, content: string) { + console.log("utca"); + this.store.dispatch( + SqlInputTabsActions.updateTabContent({ index, content }) + ); } - private submitToTask() { - this.pending = true; - const token = this.authService.getToken(); - this.submissionService - .submitSolution( - token.id, - this.activeTab.selectedCourse.id, - this.activeTab.selectedTask.id, - this.cleanUpTextAreaRegx(this.activeTab.content) - ) - .subscribe( - (subResult) => { - this.snackbar.open("Deine Abgabe wird ausgewertet.", "OK", { - duration: 3000, - }); - this.waitForSubDone(subResult.id); - }, - (error) => { - console.error(error); - this.snackbar.open( - "Beim Versenden ist ein Fehler aufgetreten. Versuche es später erneut.", - "OK", - { duration: 3000 } - ); - this.pending = false; - }, - () => { - console.log("Request Complete"); - } - ); + submissionToTask() { + // Implement the method logic } - submissionToTask(): void { - if (this.isSubmissionEmpty()) { - this.snackbar.open("Sie haben keine Lösung abgegeben", "Ups!"); - return; - } - this.submitToTask(); - this.saveToLocalStorage(); + trackByIndex(index: number, obj: any): any { + return obj.id; } - cleanUpTextAreaRegx(sqlInput: String) { - let temp = sqlInput.trim().replace(/\s+/g, " "); - return temp; + updateTabName(index: number, name: string) { + this.store.dispatch(SqlInputTabsActions.updateTabName({ index, name })); } } diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/state/sql-input-tabs.actions.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/state/sql-input-tabs.actions.ts new file mode 100644 index 000000000..84f45a6f3 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/state/sql-input-tabs.actions.ts @@ -0,0 +1,112 @@ +import { createAction, props } from "@ngrx/store"; +import { QueryTab } from "../../../../model/sql_playground/QueryTab"; +import { AwarenessState } from "../../collab/backend.service"; + +export const addTab = createAction( + "[SQL Input Tabs] Add Tab", + props<{ tab?: QueryTab }>() +); +export const closeTab = createAction( + "[SQL Input Tabs] Close Tab", + props<{ index: number }>() +); +export const closeAllTabs = createAction("[SQL Input Tabs] Close All Tabs"); +export const updateTabContent = createAction( + "[SQL Input Tabs] Update Tab Content", + props<{ index: number; content: string }>() +); +export const updateTabName = createAction( + "[SQL Input Tabs] Set Name", + props<{ index: number; name: string }>() +); +export const setActiveTab = createAction( + "[SQL Input Tabs] Set Active Tab", + props<{ index: number }>() +); +export const changeCourse = createAction( + "[SQL Input Tabs] Change Course", + props<{ index: number; course: any }>() +); +export const changeTask = createAction( + "[SQL Input Tabs] Change Task", + props<{ index: number; task: any }>() +); +export const loadTabsFromLocalStorage = createAction( + "[SQL Input Tabs] Load Tabs From Local Storage" +); +export const loadTabsFromLocalStorageSuccess = createAction( + "[SQL Input Tabs] Load Tabs From Local Storage Success", + props<{ tabs: any }>() +); +export const saveTabsToLocalStorage = createAction( + "[SQL Input Tabs] Save Tabs To Local Storage" +); +export const saveTabsToLocalStorageSuccess = createAction( + "[SQL Input Tabs] Save Tabs To Local Storage Success" +); +export const downloadFile = createAction( + "[SQL Input Tabs] Download File", + props<{ index: number }>() +); +export const downloadFileSuccess = createAction( + "[SQL Input Tabs] Download File Success" +); +export const downloadAllFiles = createAction( + "[SQL Input Tabs] Download All Files" +); +export const downloadAllFilesSuccess = createAction( + "[SQL Input Tabs] Download All Files Success" +); +export const submission = createAction( + "[SQL Input Tabs] Submission", + props<{ index: number }>() +); +export const submissionFailure = createAction( + "[SQL Input Tabs] Submission Failure" +); +export const submissionSuccess = createAction( + "[SQL Input Tabs] Submission Success" +); +export const submissionToTask = createAction( + "[SQL Input Tabs] Submission To Task", + props<{ index: number }>() +); +export const submissionToTaskSuccess = createAction( + "[SQL Input Tabs] Submission To Task Success", + props<{ taskId: number }>() +); +export const waitForSubDone = createAction( + "[SQL Input Tabs] Wait For Sub Done", + props<{ index: number; sid: number }>() +); +export const waitForSubDoneSuccess = createAction( + "[SQL Input Tabs] Wait For Sub Done Success" +); +export const updateMode = createAction( + "[SQL Input Tabs] Update Mode", + props<{ index: number; value: boolean }>() +); + +// Newly introduced actions +export const setPending = createAction( + "[SQL Input Tabs] Set Pending", + props<{ pending: boolean }>() +); +export const setSubmissionResult = createAction( + "[SQL Input Tabs] Set Submission Result", + props<{ isCorrect: boolean; error: boolean; errorMsg: string | null }>() +); +export const submitStatement = createAction( + "[SQL Input Tabs] Submit Statement", + props<{ content: string }>() +); +export const waitForSubDoneFailure = createAction( + "[SQL Input Tabs] Wait For Sub Done Failure" +); +export const submissionToTaskFailure = createAction( + "[SQL Input Tabs] Submission To Task Failure" +); +export const updateActiveTabUsers = createAction( + "[SQL Input Tabs] Update Active Tab Users", + props<{ awarenessStates: AwarenessState[] }>() +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/state/sql-input-tabs.effects.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/state/sql-input-tabs.effects.ts new file mode 100644 index 000000000..a5ee8d4db --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/state/sql-input-tabs.effects.ts @@ -0,0 +1,299 @@ +import { Injectable } from "@angular/core"; +import { Actions, createEffect, ofType } from "@ngrx/effects"; +import { Store } from "@ngrx/store"; +import { + switchMap, + map, + withLatestFrom, + takeWhile, + repeat, + catchError, +} from "rxjs/operators"; +import * as SqlInputTabsActions from "./sql-input-tabs.actions"; +import * as fromSqlInputTabs from "./sql-input-tabs.selectors"; +import { of } from "rxjs"; +import { AuthService } from "src/app/service/auth.service"; +import { SubmissionService } from "src/app/service/submission.service"; +import { CheckerService } from "src/app/service/checker.service"; +import { PrismService } from "src/app/service/prism.service"; +import { MatSnackBar } from "@angular/material/snack-bar"; +import { MatDialog } from "@angular/material/dialog"; +import * as SqlPlaygroundActions from "../../state/sql-playground.actions"; + +@Injectable() +export class SqlInputTabsEffects { + constructor( + private actions$: Actions, + private store: Store, + private authService: AuthService, + private submissionService: SubmissionService, + private checkerService: CheckerService, + private prismService: PrismService, + private snackbar: MatSnackBar, + private dialog: MatDialog + ) {} + + addTab$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.addTab), + map(() => { + return SqlInputTabsActions.saveTabsToLocalStorage(); + }) + ) + ); + + closeTab$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.closeTab), + map(({}) => { + return SqlInputTabsActions.saveTabsToLocalStorage(); + }) + ) + ); + + closeAllTabs$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.closeAllTabs), + map(() => { + return SqlInputTabsActions.saveTabsToLocalStorage(); + }) + ) + ); + + updateTabContent$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.updateTabContent), + map(({}) => { + return SqlInputTabsActions.saveTabsToLocalStorage(); + }) + ) + ); + + setActiveTab$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.setActiveTab), + map(({}) => { + return SqlInputTabsActions.saveTabsToLocalStorage(); + }) + ) + ); + + changeCourse$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.changeCourse), + map(({}) => { + return SqlInputTabsActions.saveTabsToLocalStorage(); + }) + ) + ); + + changeTask$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.changeTask), + map(({}) => { + return SqlInputTabsActions.saveTabsToLocalStorage(); + }) + ) + ); + + /*loadTabsFromLocalStorage$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.loadTabsFromLocalStorage), + switchMap(() => { + console.log("load tabs"); + const loadedData = localStorage.getItem("tabs"); + const tabs = JSON.parse(loadedData)?.tabs ?? []; + return [ + SqlInputTabsActions.loadTabsFromLocalStorageSuccess({ + tabs, + }), + ...(tabs.length === 0 ? [SqlInputTabsActions.addTab()] : []), + ]; + }) + ) + ); + + saveTabsToLocalStorage$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.saveTabsToLocalStorage), + withLatestFrom(this.store.select(fromSqlInputTabs.selectTabs)), + map(([_, tabs]) => { + const data = { tabs }; + localStorage.setItem("tabs", JSON.stringify(data)); + console.trace("save tabs"); + return SqlInputTabsActions.saveTabsToLocalStorageSuccess(); + }) + ) + );*/ + + downloadFile$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.downloadFile), + withLatestFrom(this.store.select(fromSqlInputTabs.selectActiveTab)), + map(([{}, activeTab]) => { + const file = new Blob([activeTab.content], { type: ".txt" }); + const a = document.createElement("a"), + url = URL.createObjectURL(file); + a.href = url; + a.download = activeTab.name + ".sql"; + document.body.appendChild(a); + a.click(); + setTimeout(() => { + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + }, 0); + return SqlInputTabsActions.downloadFileSuccess(); + }) + ) + ); + + downloadAllFiles$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.downloadAllFiles), + withLatestFrom(this.store.select(fromSqlInputTabs.selectTabs)), + map(([_, tabs]) => { + for (let i = 0; i < tabs.length; i++) { + const file = new Blob([tabs[i].content], { type: ".txt" }); + const a = document.createElement("a"), + url = URL.createObjectURL(file); + a.href = url; + a.download = tabs[i].name + ".sql"; + document.body.appendChild(a); + a.click(); + setTimeout(() => { + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + }, 200); + } + return SqlInputTabsActions.downloadAllFilesSuccess(); + }) + ) + ); + + submission$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.submission), + withLatestFrom(this.store.select(fromSqlInputTabs.selectActiveTab)), + switchMap(([{}, activeTab]) => { + if (!activeTab.content) { + this.snackbar.open("Sie haben keine Lösung abgegeben", "Ups!"); + return of(SqlInputTabsActions.submissionFailure()); + } + return of( + SqlPlaygroundActions.submitStatement({ + statement: activeTab.content, + }), + SqlInputTabsActions.submissionSuccess() + ); + }) + ) + ); + + submissionToTask$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.submissionToTask), + withLatestFrom(this.store.select(fromSqlInputTabs.selectActiveTab)), + switchMap(([{ index }, activeTab]) => { + this.store.dispatch(SqlInputTabsActions.setPending({ pending: true })); + const token = this.authService.getToken(); + return this.submissionService + .submitSolution( + token.id, + activeTab.selectedCourse.id, + activeTab.selectedTask.id, + this.cleanUpTextAreaRegx(activeTab.content) + ) + .pipe( + switchMap((subResult) => { + this.snackbar.open("Deine Abgabe wird ausgewertet.", "OK", { + duration: 3000, + }); + this.store.dispatch( + SqlInputTabsActions.waitForSubDone({ index, sid: subResult.id }) + ); + return of( + SqlInputTabsActions.submissionToTaskSuccess({ + taskId: activeTab.selectedTask.id, + }) + ); + }), + catchError((error) => { + console.error(error); + this.snackbar.open( + "Beim Versenden ist ein Fehler aufgetreten. Versuche es später erneut.", + "OK", + { duration: 3000 } + ); + this.store.dispatch( + SqlInputTabsActions.setPending({ pending: false }) + ); + return of(SqlInputTabsActions.submissionToTaskFailure()); + }) + ); + }) + ) + ); + + waitForSubDone$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.waitForSubDone), + withLatestFrom(this.store.select(fromSqlInputTabs.selectActiveTab)), + switchMap(([{ sid }, activeTab]) => { + const token = this.authService.getToken(); + return this.submissionService + .getSubmission( + token.id, + activeTab.selectedCourse.id, + activeTab.selectedTask.id, + sid + ) + .pipe( + repeat(), + takeWhile((sub) => !sub.done, true), + switchMap((res) => { + if (res.done) { + this.store.dispatch( + SqlInputTabsActions.setPending({ pending: false }) + ); + if (res.results[0].exitCode == 0) { + this.store.dispatch( + SqlInputTabsActions.setSubmissionResult({ + isCorrect: true, + error: false, + errorMsg: null, + }) + ); + } else { + this.store.dispatch( + SqlInputTabsActions.setSubmissionResult({ + isCorrect: false, + error: true, + errorMsg: res.results[0].resultText, + }) + ); + } + } + return of(SqlInputTabsActions.waitForSubDoneSuccess()); + }), + catchError((error) => { + console.error(error); + return of(SqlInputTabsActions.waitForSubDoneFailure()); + }) + ); + }) + ) + ); + + updateMode$ = createEffect(() => + this.actions$.pipe( + ofType(SqlInputTabsActions.updateMode), + map(({}) => { + return SqlInputTabsActions.saveTabsToLocalStorage(); + }) + ) + ); + + private cleanUpTextAreaRegx(sqlInput: String) { + return sqlInput.trim().replace(/\s+/g, " "); + } +} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/state/sql-input-tabs.reducer.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/state/sql-input-tabs.reducer.ts new file mode 100644 index 000000000..c8024440d --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/state/sql-input-tabs.reducer.ts @@ -0,0 +1,181 @@ +import { createReducer, on } from "@ngrx/store"; +import { QueryTab } from "src/app/model/sql_playground/QueryTab"; +import * as SqlInputTabsActions from "./sql-input-tabs.actions"; + +export interface SqlInputTabsState { + tabs: QueryTab[]; + activeTabIndex: number; + pending: boolean; +} + +const initialState: SqlInputTabsState = { + tabs: [], + activeTabIndex: 0, + pending: false, +}; + +export const sqlInputTabsReducer = createReducer( + initialState, + on(SqlInputTabsActions.addTab, (state, { tab }) => ({ + ...state, + tabs: [ + ...state.tabs, + tab ?? { + id: crypto.randomUUID(), + name: "New Query", + content: "", + error: false, + errorMsg: null, + isCorrect: false, + isSubmitted: false, + isSubmitMode: false, + selectedCourse: undefined, + selectedTask: undefined, + selectedCourseName: "Course", + selectedTaskName: "Task", + active: [], + }, + ], + activeTabIndex: state.tabs.length, + })), + on(SqlInputTabsActions.closeTab, (state, { index }) => { + const tabs = state.tabs.filter((_, i) => i !== index); + return { + ...state, + tabs, + activeTabIndex: tabs.length - 1, + }; + }), + on(SqlInputTabsActions.closeAllTabs, (state) => ({ + ...state, + tabs: [], + activeTabIndex: 0, + })), + on(SqlInputTabsActions.updateTabContent, (state, { index, content }) => { + let changed = false; + + const newTabs = state.tabs.map((tab, i) => { + if (i === index && tab.content !== content) { + changed = true; + return { ...tab, content }; + } else { + return tab; + } + }); + + return changed + ? { + ...state, + tabs: newTabs, + } + : state; + }), + on(SqlInputTabsActions.updateTabName, (state, { index, name }) => { + let changed = false; + + const newTabs = state.tabs.map((tab, i) => { + if (i === index && tab.name !== name) { + changed = true; + return { ...tab, name }; + } else { + return tab; + } + }); + + return changed + ? { + ...state, + tabs: newTabs, + } + : state; + }), + on(SqlInputTabsActions.updateActiveTabUsers, (state, { awarenessStates }) => { + const newTabs = state.tabs.map((tab) => { + return { + ...tab, + active: awarenessStates + .filter(({ stateId }) => stateId === tab.id) + .map(({ user }) => user), + }; + }); + + return { + ...state, + tabs: newTabs, + }; + }), + on(SqlInputTabsActions.setActiveTab, (state, { index }) => ({ + ...state, + activeTabIndex: index, + })), + on(SqlInputTabsActions.changeCourse, (state, { index, course }) => ({ + ...state, + tabs: state.tabs.map((tab, i) => + i === index + ? { + ...tab, + selectedCourse: course, + selectedCourseName: course.name, + selectedTask: undefined, + selectedTaskName: "Task", + } + : tab + ), + })), + on(SqlInputTabsActions.changeTask, (state, { index, task }) => ({ + ...state, + tabs: state.tabs.map((tab, i) => + i === index + ? { ...tab, selectedTask: task, selectedTaskName: task.name } + : tab + ), + })), + on(SqlInputTabsActions.loadTabsFromLocalStorageSuccess, (state, { tabs }) => { + if (tabs.length > 0) { + return { + ...state, + tabs: tabs, + activeTabIndex: 0, + }; + } else { + return state; + } + }), + on(SqlInputTabsActions.saveTabsToLocalStorage, (state) => state), + on(SqlInputTabsActions.saveTabsToLocalStorageSuccess, (state) => state), + on(SqlInputTabsActions.updateMode, (state, { index, value }) => ({ + ...state, + tabs: state.tabs.map((tab, i) => + i === index ? { ...tab, isSubmitMode: value } : tab + ), + })), + on(SqlInputTabsActions.submissionToTaskSuccess, (state, { taskId }) => ({ + ...state, + taskId, + })), + on(SqlInputTabsActions.downloadFileSuccess, (state) => state), + on(SqlInputTabsActions.downloadAllFilesSuccess, (state) => state), + on(SqlInputTabsActions.submissionFailure, (state) => state), + on(SqlInputTabsActions.submissionSuccess, (state) => state), + on(SqlInputTabsActions.waitForSubDoneSuccess, (state) => state), + + // Newly introduced actions + on(SqlInputTabsActions.setPending, (state, { pending }) => ({ + ...state, + pending, + })), + on( + SqlInputTabsActions.setSubmissionResult, + (state, { isCorrect, error, errorMsg }) => ({ + ...state, + tabs: state.tabs.map((tab, i) => + i === state.activeTabIndex + ? { ...tab, isCorrect, error, errorMsg, isSubmitted: true } + : tab + ), + }) + ), + on(SqlInputTabsActions.submitStatement, (state, {}) => state), + on(SqlInputTabsActions.waitForSubDoneFailure, (state) => state), + on(SqlInputTabsActions.submissionToTaskFailure, (state) => state) +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/state/sql-input-tabs.selectors.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/state/sql-input-tabs.selectors.ts new file mode 100644 index 000000000..d8a35a8cf --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-input-tabs/state/sql-input-tabs.selectors.ts @@ -0,0 +1,20 @@ +import { createFeatureSelector, createSelector } from "@ngrx/store"; +import { SqlInputTabsState } from "./sql-input-tabs.reducer"; + +export const selectSqlInputTabsState = + createFeatureSelector("sqlInputTabs"); + +export const selectTabs = createSelector( + selectSqlInputTabsState, + (state: SqlInputTabsState) => state.tabs +); + +export const selectActiveTabIndex = createSelector( + selectSqlInputTabsState, + (state: SqlInputTabsState) => state.activeTabIndex +); + +export const selectActiveTab = createSelector( + selectSqlInputTabsState, + (state: SqlInputTabsState) => state.tabs[state.activeTabIndex] +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-playground.component.html b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-playground.component.html index b61d2c5c6..dba224d5d 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-playground.component.html +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-playground.component.html @@ -1,20 +1,16 @@
- task.detail.tooltip.results
+ > +
@@ -26,31 +22,26 @@ + > +
- + >
diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-playground.component.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-playground.component.ts index be14f16b0..60a970800 100644 --- a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-playground.component.ts +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-playground.component.ts @@ -1,129 +1,70 @@ import { Component, OnInit } from "@angular/core"; +import { Store } from "@ngrx/store"; +import { Observable } from "rxjs"; import { Routine } from "src/app/model/sql_playground/Routine"; import { Trigger } from "src/app/model/sql_playground/Trigger"; import { View } from "src/app/model/sql_playground/View"; -import { TitlebarService } from "../../service/titlebar.service"; -import { AuthService } from "src/app/service/auth.service"; -import { SqlPlaygroundService } from "src/app/service/sql-playground.service"; import { Table } from "src/app/model/sql_playground/Table"; import { Constraint } from "src/app/model/sql_playground/Constraint"; -import { delay, retryWhen } from "rxjs/operators"; +import { TitlebarService } from "../../service/titlebar.service"; +import { AuthService } from "src/app/service/auth.service"; import { MatSnackBar } from "@angular/material/snack-bar"; +import * as SqlPlaygroundActions from "./state/sql-playground.actions"; +import * as fromSqlPlayground from "./state/sql-playground.selectors"; +import { BackendService } from "./collab/backend.service"; -/** - * This component is for the sql playground - */ @Component({ selector: "app-sql-playground-management", templateUrl: "./sql-playground.component.html", styleUrls: ["./sql-playground.component.scss"], }) export class SqlPlaygroundComponent implements OnInit { + activeDb$: Observable; + resultset$: Observable; + triggers$: Observable; + routines$: Observable; + views$: Observable; + tables$: Observable; + constraints$: Observable; + isQueryPending$: Observable; + constructor( private titlebar: TitlebarService, private authService: AuthService, + private backendService: BackendService, private snackbar: MatSnackBar, - private sqlPlaygroundService: SqlPlaygroundService + private store: Store ) {} - activeDb: number; - resultset: any; - - triggers: Trigger[]; - routines: Routine[]; - views: View[]; - tables: Table[]; - constraints: Constraint[]; - isQueryPending: boolean = false; - ngOnInit() { this.titlebar.emitTitle("SQL Playground"); + this.activeDb$ = this.store.select(fromSqlPlayground.selectActiveDb); + this.resultset$ = this.store.select(fromSqlPlayground.selectResultset); + this.triggers$ = this.store.select(fromSqlPlayground.selectTriggers); + this.routines$ = this.store.select(fromSqlPlayground.selectRoutines); + this.views$ = this.store.select(fromSqlPlayground.selectViews); + this.tables$ = this.store.select(fromSqlPlayground.selectTables); + this.constraints$ = this.store.select(fromSqlPlayground.selectConstraints); + this.isQueryPending$ = this.store.select( + fromSqlPlayground.selectIsQueryPending + ); + this.backendService.setupBackendHandler(); } changeActiveDbId(dbId: number) { - this.activeDb = dbId; + this.store.dispatch(SqlPlaygroundActions.changeActiveDbId({ dbId })); this.updateScheme(); } - changeQueryPending($event) { - this.isQueryPending = $event; + changeQueryPending() { + this.store.dispatch(SqlPlaygroundActions.updateScheme()); } updateScheme() { - const token = this.authService.getToken(); - - this.sqlPlaygroundService - .getTables(token.id, this.activeDb) - .subscribe((result) => { - this.tables = result; - }); - - this.sqlPlaygroundService - .getConstraints(token.id, this.activeDb) - .subscribe((result) => { - this.constraints = result; - }); - - this.sqlPlaygroundService - .getViews(token.id, this.activeDb) - .subscribe((result) => { - this.views = result; - }); - - this.sqlPlaygroundService - .getRoutines(token.id, this.activeDb) - .subscribe((result) => { - this.routines = result; - }); - - this.sqlPlaygroundService - .getTriggers(token.id, this.activeDb) - .subscribe((result) => { - this.triggers = result; - }); + this.store.dispatch(SqlPlaygroundActions.updateScheme()); } submitStatement(statement: string) { - this.isQueryPending = true; - const token = this.authService.getToken(); - - this.sqlPlaygroundService - .submitStatement(token.id, this.activeDb, statement) - .subscribe( - (result) => { - this.getResultsbyPolling(result.id); - }, - (error) => { - console.error(error); - this.snackbar.open( - "Beim Versenden ist ein Fehler aufgetreten. Versuche es später erneut.", - "OK", - { duration: 3000 } - ); - this.isQueryPending = false; - } - ); - } - - private getResultsbyPolling(rId: number) { - const token = this.authService.getToken(); - - this.sqlPlaygroundService - .getResults(token.id, this.activeDb, rId) - .pipe( - retryWhen((err) => { - return err.pipe(delay(1000)); - }) - ) - .subscribe( - (res) => { - // emit if success - this.isQueryPending = false; - this.resultset = res; - this.updateScheme(); - }, - () => {}, //handle error - () => console.log("Request Complete") - ); + this.store.dispatch(SqlPlaygroundActions.submitStatement({ statement })); } } diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/sql-playground.module.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-playground.module.ts new file mode 100644 index 000000000..a648bf770 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/sql-playground.module.ts @@ -0,0 +1,100 @@ +import { isDevMode, NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { StoreModule } from "@ngrx/store"; +import { EffectsModule } from "@ngrx/effects"; +import { sqlPlaygroundReducer } from "./state/sql-playground.reducer"; +import { SqlPlaygroundEffects } from "./state/sql-playground.effects"; +import { SqlPlaygroundComponent } from "./sql-playground.component"; +import { DynamicResultTableComponent } from "./dynamic-result-table/dynamic-result-table.component"; +import { DbControlPanelComponent } from "./db-control-panel/db-control-panel.component"; +import { SqlInputTabsComponent } from "./sql-input-tabs/sql-input-tabs.component"; +import { DbSchemeComponent } from "./db-scheme/db-scheme.component"; +import { DbSchemeViewsComponent } from "./db-scheme/db-scheme-views/db-scheme-views.component"; +import { DbSchemeTriggersComponent } from "./db-scheme/db-scheme-triggers/db-scheme-triggers.component"; +import { DbSchemeRoutinesComponent } from "./db-scheme/db-scheme-routines/db-scheme-routines.component"; +import { DbSchemeTablesComponent } from "./db-scheme/db-scheme-tables/db-scheme-tables.component"; +import { DbControlTemplatesComponent } from "./db-control-panel/db-control-templates/db-control-templates.component"; +import { DbControlCoWorkingComponent } from "./db-control-panel/db-control-co-working/db-control-co-working.component"; +import { DbControlDbOverviewComponent } from "./db-control-panel/db-control-db-overview/db-control-db-overview.component"; +import { HighlightedInputComponent } from "./sql-input-tabs/highlighted-input/highlighted-input.component"; +import { I18NextModule } from "angular-i18next"; +import { I18N_PROVIDERS } from "../../util/i18n"; +import { MaterialComponentsModule } from "../../modules/material-components/material-components.module"; +import { BorderedContainerComponent } from "./bordered-container/bordered-container.component"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { sqlInputTabsReducer } from "./sql-input-tabs/state/sql-input-tabs.reducer"; +import { dynamicResultTableReducer } from "./dynamic-result-table/state/dynamic-result-table.reducer"; +import { databasesReducer } from "./db-control-panel/state/databases.reducer"; +import { templatesReducer } from "./db-control-panel/state/templates.reducer"; +import { DatabasesEffects } from "./db-control-panel/state/databases.effects"; +import { StoreDevtoolsModule } from "@ngrx/store-devtools"; +import { SqlInputTabsEffects } from "./sql-input-tabs/state/sql-input-tabs.effects"; +import { DynamicResultTableEffects } from "./dynamic-result-table/state/dynamic-result-table.effects"; +import { DynamicResultTableTabComponent } from "./dynamic-result-table/tab/dynamic-result-table-tab.component"; +import { groupsReducer } from "./db-control-panel/state/groups.reducer"; +import { GroupsEffects } from "./db-control-panel/state/groups.effects"; + +@NgModule({ + declarations: [ + SqlPlaygroundComponent, + DynamicResultTableComponent, + DynamicResultTableTabComponent, + DbControlPanelComponent, + SqlInputTabsComponent, + DbSchemeComponent, + DbSchemeViewsComponent, + DbSchemeTriggersComponent, + DbSchemeRoutinesComponent, + DbSchemeTablesComponent, + DbControlTemplatesComponent, + DbControlCoWorkingComponent, + DbControlDbOverviewComponent, + HighlightedInputComponent, + BorderedContainerComponent, + ], + imports: [ + CommonModule, + MaterialComponentsModule, + ReactiveFormsModule, + StoreModule.forRoot({}), + StoreDevtoolsModule.instrument({ + maxAge: 25, + logOnly: !isDevMode(), + autoPause: true, + }), + StoreModule.forFeature("sqlPlayground", sqlPlaygroundReducer), + StoreModule.forFeature("sqlInputTabs", sqlInputTabsReducer), + StoreModule.forFeature("dynamicResultTable", dynamicResultTableReducer), + StoreModule.forFeature("databases", databasesReducer), + StoreModule.forFeature("templates", templatesReducer), + StoreModule.forFeature("groups", groupsReducer), + EffectsModule.forRoot(), + EffectsModule.forFeature([ + SqlPlaygroundEffects, + SqlInputTabsEffects, + DynamicResultTableEffects, + DatabasesEffects, + GroupsEffects, + ]), + I18NextModule.forRoot(), + FormsModule, + ], + exports: [ + SqlPlaygroundComponent, + DynamicResultTableComponent, + DbControlPanelComponent, + SqlInputTabsComponent, + DbSchemeComponent, + DbSchemeViewsComponent, + DbSchemeTriggersComponent, + DbSchemeRoutinesComponent, + DbSchemeTablesComponent, + DbControlTemplatesComponent, + DbControlCoWorkingComponent, + DbControlDbOverviewComponent, + HighlightedInputComponent, + BorderedContainerComponent, + ], + providers: [I18N_PROVIDERS], +}) +export class SqlPlaygroundModule {} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/state/sql-playground.actions.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/state/sql-playground.actions.ts new file mode 100644 index 000000000..317fec6ba --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/state/sql-playground.actions.ts @@ -0,0 +1,51 @@ +import { createAction, props } from "@ngrx/store"; +import { Routine } from "src/app/model/sql_playground/Routine"; +import { Trigger } from "src/app/model/sql_playground/Trigger"; +import { View } from "src/app/model/sql_playground/View"; +import { Table } from "src/app/model/sql_playground/Table"; +import { Constraint } from "src/app/model/sql_playground/Constraint"; +import { + BackendDefintion, + DatabaseInformation, +} from "../collab/backend.service"; + +export const changeActiveDbId = createAction( + "[SQL Playground] Change Active DB Id", + props<{ dbId: number }>() +); +export const updateScheme = createAction("[SQL Playground] Update Scheme"); +export const updateSchemeSuccess = createAction( + "[SQL Playground] Update Scheme Success", + props<{ + tables: Table[]; + constraints: Constraint[]; + views: View[]; + routines: Routine[]; + triggers: Trigger[]; + }>() +); +export const updateSchemeFailure = createAction( + "[SQL Playground] Update Scheme Failure", + props<{ error: any }>() +); + +export const submitStatement = createAction( + "[SQL Playground] Submit Statement", + props<{ statement: string }>() +); +export const submitStatementSuccess = createAction( + "[SQL Playground] Submit Statement Success", + props<{ resultset: any }>() +); +export const submitStatementFailure = createAction( + "[SQL Playground] Submit Statement Failure", + props<{ error: any }>() +); +export const setBackend = createAction( + "[SQL Playground] Set Backend", + props<{ backend: BackendDefintion }>() +); +export const setDatabaseInformation = createAction( + "[SQL Playground] Set Backend database information", + props<{ databaseInformation?: DatabaseInformation }>() +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/state/sql-playground.effects.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/state/sql-playground.effects.ts new file mode 100644 index 000000000..ea8b2be8b --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/state/sql-playground.effects.ts @@ -0,0 +1,149 @@ +import { Injectable } from "@angular/core"; +import { Actions, createEffect, ofType } from "@ngrx/effects"; +import { Store, select } from "@ngrx/store"; +import { of } from "rxjs"; +import { + catchError, + map, + mergeMap, + withLatestFrom, + retry, +} from "rxjs/operators"; +import { SqlPlaygroundService } from "src/app/service/sql-playground.service"; +import { AuthService } from "src/app/service/auth.service"; +import * as SqlPlaygroundActions from "./sql-playground.actions"; +import { selectActiveDb } from "./sql-playground.selectors"; +import { changeActiveDbId, updateScheme } from "./sql-playground.actions"; + +@Injectable() +export class SqlPlaygroundEffects { + constructor( + private actions$: Actions, + private sqlPlaygroundService: SqlPlaygroundService, + private authService: AuthService, + private store: Store + ) {} + + updateScheme$ = createEffect(() => + this.actions$.pipe( + ofType(SqlPlaygroundActions.updateScheme), + withLatestFrom(this.store.pipe(select(selectActiveDb))), + mergeMap(([, activeDb]) => { + const token = this.authService.getToken(); + return this.sqlPlaygroundService.getTables(token.id, activeDb).pipe( + mergeMap((tables) => + this.sqlPlaygroundService.getConstraints(token.id, activeDb).pipe( + mergeMap((constraints) => + this.sqlPlaygroundService.getViews(token.id, activeDb).pipe( + mergeMap((views) => + this.sqlPlaygroundService + .getRoutines(token.id, activeDb) + .pipe( + mergeMap((routines) => + this.sqlPlaygroundService + .getTriggers(token.id, activeDb) + .pipe( + map((triggers) => + SqlPlaygroundActions.updateSchemeSuccess({ + tables, + constraints, + views, + routines, + triggers, + }) + ) + ) + ) + ) + ) + ) + ) + ) + ), + catchError((error) => + of(SqlPlaygroundActions.updateSchemeFailure({ error })) + ) + ); + }) + ) + ); + + submitStatement$ = createEffect(() => + this.actions$.pipe( + ofType(SqlPlaygroundActions.submitStatement), + withLatestFrom(this.store.pipe(select(selectActiveDb))), + mergeMap(([{ statement }, activeDb]) => { + const token = this.authService.getToken(); + return this.sqlPlaygroundService + .submitStatement(token.id, activeDb, statement) + .pipe( + mergeMap((result) => + this.sqlPlaygroundService + .getResults(token.id, activeDb, result.id) + .pipe( + retry(), + map((res) => + SqlPlaygroundActions.submitStatementSuccess({ + resultset: res, + }) + ), + catchError((error) => + of(SqlPlaygroundActions.submitStatementFailure({ error })) + ) + ) + ), + catchError((error) => + of(SqlPlaygroundActions.submitStatementFailure({ error })) + ) + ); + }) + ) + ); + + setActive$ = createEffect(() => + this.actions$.pipe( + ofType(SqlPlaygroundActions.setDatabaseInformation), + mergeMap(({ databaseInformation }) => { + if (databaseInformation?.id) { + return of( + changeActiveDbId({ dbId: databaseInformation.id }), + updateScheme() + ); + } + }) + ) + ); + /* + // New Effect + saveTabsToLocalStorage$ = createEffect(() => + this.actions$.pipe( + ofType(SqlPlaygroundActions.saveTabsToLocalStorage), + mergeMap(({ tabs }) => { + // Logic to save tabs to local storage + try { + localStorage.setItem('tabs', JSON.stringify(tabs)); + return of(SqlPlaygroundActions.saveTabsToLocalStorageSuccess({ tabs })); + } catch (error) { + return of(SqlPlaygroundActions.saveTabsToLocalStorageFailure({ error })); + } + }) + ) + ); + + // Assuming a place to dispatch submissionToTaskSuccess + someEffect$ = createEffect(() => + this.actions$.pipe( + ofType(SqlPlaygroundActions.someAction), + mergeMap((action) => + this.someService.someMethod(action).pipe( + map((response) => + SqlPlaygroundActions.submissionToTaskSuccess({ taskId: response.taskId }) + ), + catchError((error) => + of(SqlPlaygroundActions.someActionFailure({ error })) + ) + ) + ) + ) + );*/ +} diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/state/sql-playground.reducer.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/state/sql-playground.reducer.ts new file mode 100644 index 000000000..6eb62bc62 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/state/sql-playground.reducer.ts @@ -0,0 +1,107 @@ +import { createReducer, on } from "@ngrx/store"; +import * as SqlPlaygroundActions from "./sql-playground.actions"; +import { Routine } from "src/app/model/sql_playground/Routine"; +import { Trigger } from "src/app/model/sql_playground/Trigger"; +import { View } from "src/app/model/sql_playground/View"; +import { Table } from "src/app/model/sql_playground/Table"; +import { Constraint } from "src/app/model/sql_playground/Constraint"; +import { BackendDefintion } from "../collab/backend.service"; + +export interface SqlPlaygroundState { + backend: BackendDefintion; + activeDb: number; + resultset: any; + triggers: Trigger[]; + routines: Routine[]; + views: View[]; + tables: Table[]; + constraints: Constraint[]; + isQueryPending: boolean; + error: any; +} + +const initialState: SqlPlaygroundState = { + backend: { type: "local" }, + activeDb: null, + resultset: null, + triggers: [], + routines: [], + views: [], + tables: [], + constraints: [], + isQueryPending: false, + error: null, +}; + +export const sqlPlaygroundReducer = createReducer( + initialState, + on(SqlPlaygroundActions.changeActiveDbId, (state, { dbId }) => ({ + ...state, + activeDb: dbId, + })), + on(SqlPlaygroundActions.updateScheme, (state) => ({ + ...state, + isQueryPending: true, + })), + on( + SqlPlaygroundActions.updateSchemeSuccess, + (state, { tables, constraints, views, routines, triggers }) => ({ + ...state, + tables, + constraints, + views, + routines, + triggers, + isQueryPending: false, + }) + ), + on(SqlPlaygroundActions.updateSchemeFailure, (state, { error }) => ({ + ...state, + error, + isQueryPending: false, + })), + on(SqlPlaygroundActions.submitStatement, (state) => ({ + ...state, + isQueryPending: true, + })), + on(SqlPlaygroundActions.submitStatementSuccess, (state, { resultset }) => ({ + ...state, + resultset, + isQueryPending: false, + })), + on(SqlPlaygroundActions.submitStatementFailure, (state, { error }) => ({ + ...state, + error, + isQueryPending: false, + })), + on(SqlPlaygroundActions.setBackend, (state, { backend }) => ({ + ...state, + backend, + })), + on( + SqlPlaygroundActions.setDatabaseInformation, + (state, { databaseInformation }) => ({ + ...state, + backend: { ...state.backend, database: databaseInformation }, + }) + ) + /* +// New Handlers +on(SqlPlaygroundActions.saveTabsToLocalStorage, (state) => ({ + ...state, + isQueryPending: true, +})), +on(SqlPlaygroundActions.saveTabsToLocalStorageSuccess, (state, { tabs }) => ({ + ...state, + tabs, + isQueryPending: false, +})), +on( + SqlPlaygroundActions.saveTabsToLocalStorageFailure, + (state, { error }) => ({ + ...state, + error, + isQueryPending: false, + }) +)*/ +); diff --git a/modules/fbs-core/web/src/app/page-components/sql-playground/state/sql-playground.selectors.ts b/modules/fbs-core/web/src/app/page-components/sql-playground/state/sql-playground.selectors.ts new file mode 100644 index 000000000..26a9e94c7 --- /dev/null +++ b/modules/fbs-core/web/src/app/page-components/sql-playground/state/sql-playground.selectors.ts @@ -0,0 +1,62 @@ +import { createFeatureSelector, createSelector } from "@ngrx/store"; +import { SqlPlaygroundState } from "./sql-playground.reducer"; +import { BackendDefintion } from "../collab/backend.service"; + +export const selectSqlPlaygroundState = + createFeatureSelector("sqlPlayground"); + +export const selectActiveDb = createSelector( + selectSqlPlaygroundState, + (state: SqlPlaygroundState) => state.activeDb +); + +export const selectResultset = createSelector( + selectSqlPlaygroundState, + (state: SqlPlaygroundState) => state.resultset +); + +export const selectTriggers = createSelector( + selectSqlPlaygroundState, + (state: SqlPlaygroundState) => state.triggers +); + +export const selectRoutines = createSelector( + selectSqlPlaygroundState, + (state: SqlPlaygroundState) => state.routines +); + +export const selectViews = createSelector( + selectSqlPlaygroundState, + (state: SqlPlaygroundState) => state.views +); + +export const selectTables = createSelector( + selectSqlPlaygroundState, + (state: SqlPlaygroundState) => state.tables +); + +export const selectConstraints = createSelector( + selectSqlPlaygroundState, + (state: SqlPlaygroundState) => state.constraints +); + +export const selectIsQueryPending = createSelector( + selectSqlPlaygroundState, + (state: SqlPlaygroundState) => state.isQueryPending +); + +export const selectError = createSelector( + selectSqlPlaygroundState, + (state: SqlPlaygroundState) => state.error +); + +export const selectBackend = createSelector( + selectSqlPlaygroundState, + (state: SqlPlaygroundState) => state.backend +); + +export const selectBackendDatabaseInformation = createSelector( + selectBackend, + (state: BackendDefintion) => + state.type === "collaborative" ? state.database : null +); diff --git a/modules/fbs-core/web/src/app/service/prism.service.ts b/modules/fbs-core/web/src/app/service/prism.service.ts index 4482d0478..06abc3f9c 100644 --- a/modules/fbs-core/web/src/app/service/prism.service.ts +++ b/modules/fbs-core/web/src/app/service/prism.service.ts @@ -10,6 +10,7 @@ import "prismjs/components/prism-markup"; import "prismjs/components/prism-typescript"; import "prismjs/components/prism-sass"; import "prismjs/components/prism-scss"; +import { Element } from "@angular/compiler"; declare var Prism: any; @@ -23,6 +24,10 @@ export class PrismService { Prism.highlightAll(); } + highlight(element: Element) { + Prism.highlightElement(element); + } + convertHtmlIntoString(text: string) { return text .replace(new RegExp("&", "g"), "&") diff --git a/modules/fbs-core/web/src/app/service/sql-playground.service.ts b/modules/fbs-core/web/src/app/service/sql-playground.service.ts index 132267362..b8edc0e9c 100644 --- a/modules/fbs-core/web/src/app/service/sql-playground.service.ts +++ b/modules/fbs-core/web/src/app/service/sql-playground.service.ts @@ -180,4 +180,34 @@ export class SqlPlaygroundService { `/api/v2/playground/${uid}/databases/${dbId}/routines` ); } + + /** + * shares a database with a group (updates the share if it all ready exists. + * @param uid User id + * @param dbId Database id + * @param groupId Group id + * @returns the update database + */ + shareWithGroup( + uid: number, + dbId: number, + groupId: number + ): Observable { + return this.http.put( + `/api/v2/playground/${uid}/databases/${dbId}/share-with-group`, + { groupId } + ); + } + + /** + * unshares a database with a group + * @param uid User id + * @param dbId Database id + * @returns the update database + */ + unshareWithGroup(uid: number, dbId: number): Observable { + return this.http.delete( + `/api/v2/playground/${uid}/databases/${dbId}/share-with-group` + ); + } } diff --git a/modules/fbs-core/web/src/i18n/de.ts b/modules/fbs-core/web/src/i18n/de.ts index ed9965f95..63c6b643b 100644 --- a/modules/fbs-core/web/src/i18n/de.ts +++ b/modules/fbs-core/web/src/i18n/de.ts @@ -349,9 +349,9 @@ export const germanTranslation = { "sql-playground.db-control-panel.co-working.select-group": "Select Group", "sql-playground.db-control-panel.co-working.select-database": "Select Database", - "sql-playground.db-control-panel.co-working.delete": "Löschen", - "sql-playground.db-control-panel.co-working.co": "Co-Working", - "sql-playground.db-control-panel.co-working.new": "Neue DB", + "sql-playground.db-control-panel.co-working.delete": "Beenden", + "sql-playground.db-control-panel.co-working.co": "Beitreten", + "sql-playground.db-control-panel.co-working.new": "Teilen", "sql-playground.input.highlighted.placeholder": "Hier Code einfügen (PostgreSQL)", "sql-playground.input.tooltip.closeAllTabs": "Schließe alle Tabs", diff --git a/modules/fbs-core/web/src/i18n/en.ts b/modules/fbs-core/web/src/i18n/en.ts index 0372ee0b6..36a24c1db 100644 --- a/modules/fbs-core/web/src/i18n/en.ts +++ b/modules/fbs-core/web/src/i18n/en.ts @@ -343,9 +343,9 @@ export const englishTranslation = { "sql-playground.db-control-panel.co-working.select-group": "Select Group", "sql-playground.db-control-panel.co-working.select-database": "Select Database", - "sql-playground.db-control-panel.co-working.delete": "Delete", - "sql-playground.db-control-panel.co-working.co": "Co-Working", - "sql-playground.db-control-panel.co-working.new": "New DB", + "sql-playground.db-control-panel.co-working.delete": "End", + "sql-playground.db-control-panel.co-working.co": "Connect", + "sql-playground.db-control-panel.co-working.new": "Start", "sql-playground.input.highlighted.placeholder": "Insert code here (PostgreSQL)", "sql-playground.input.tooltip.closeAllTabs": "Close all tabs", diff --git a/modules/fbs-core/web/src/main.ts b/modules/fbs-core/web/src/main.ts index 990a7d085..b340051cf 100644 --- a/modules/fbs-core/web/src/main.ts +++ b/modules/fbs-core/web/src/main.ts @@ -1,12 +1,12 @@ -import { enableProdMode } from "@angular/core"; +//import { enableProdMode } from "@angular/core"; import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; import { AppModule } from "./app/app.module"; -import { environment } from "./environments/environment"; +//import { environment } from "./environments/environment"; -if (environment.production) { +/*if (environment.production) { enableProdMode(); -} +}*/ platformBrowserDynamic() .bootstrapModule(AppModule) diff --git a/modules/fbs-eat/eat/Dockerfile b/modules/fbs-eat/eat/Dockerfile index c8aa019af..a24f28864 100644 --- a/modules/fbs-eat/eat/Dockerfile +++ b/modules/fbs-eat/eat/Dockerfile @@ -12,7 +12,7 @@ RUN poetry config virtualenvs.create false COPY pyproject.toml . # Installiere die Dependencies mit Poetry -RUN poetry install --no-dev --no-root +RUN poetry install --no-root COPY . . diff --git a/modules/fbs-sql-checker/Dockerfile b/modules/fbs-sql-checker/Dockerfile index ed442e075..66ece24ce 100755 --- a/modules/fbs-sql-checker/Dockerfile +++ b/modules/fbs-sql-checker/Dockerfile @@ -9,7 +9,7 @@ RUN pip install poetry && poetry config virtualenvs.in-project true WORKDIR "/app" COPY . . -RUN poetry install --only main --no-dev +RUN poetry install --only main FROM python:3.11 diff --git a/scripts/ci/docker-deploy.sh b/scripts/ci/docker-deploy.sh index d53b8eafb..755a3fb4d 100644 --- a/scripts/ci/docker-deploy.sh +++ b/scripts/ci/docker-deploy.sh @@ -11,12 +11,14 @@ function dockerPush() { docker tag feedbacksystem-runtime-bash thmmniii/fbs-runtime-bash:$tag docker tag feedbacksystem_sql-checker thmmniii/fbs-sql-checker:$tag docker tag feedbacksystem-dashboard thmmniii/fbs-eat:$tag + docker tag feedbacksystem-collab thmmniii/fbs-collab:$tag docker push thmmniii/fbs-core:$tag docker push thmmniii/fbs-runner:$tag docker push thmmniii/fbs-runtime-bash:$tag docker push thmmniii/fbs-sql-checker:$tag docker push thmmniii/fbs-eat:$tag + docker push thmmniii/fbs-collab:$tag } function generateDockerTag() {