├── .eslintrc ├── .gitignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── deps.ts ├── devDemoFolder └── demo.ts ├── lib ├── db-connectors │ └── pg-connector.ts ├── query-builder.ts ├── sql-template.ts └── validate-strings.ts ├── mod.ts ├── models ├── generator-helper.ts ├── init.ts ├── model-generator.ts └── relationships.sql └── test-suite ├── db_test_starwars_create.sql ├── delete-test.ts ├── drop-test.ts ├── insert-test.ts ├── join-test.ts ├── main-test.ts ├── select-test.ts ├── testing.md └── update-test.ts /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "airbnb", 4 | "plugin:@typescript-eslint/eslint-recommended", 5 | "plugin:@typescript-eslint/recommended" 6 | ], 7 | "root": true, 8 | "plugins": ["react", "react-hooks", "@typescript-eslint"], 9 | "rules": { 10 | "arrow-parens": [2, "as-needed"], 11 | "import/no-unresolved": "off", 12 | "import/extensions": "off" 13 | }, 14 | "env": { 15 | "es6": true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | # deno lint 107 | .vscode/ -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5" 4 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | . 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ## Pull Request Process 9 | 10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a 11 | build. 12 | 2. Update the README.md with details of changes to the interface, this includes new environment 13 | variables, exposed ports, useful file locations and container parameters. 14 | 3. Increase the version numbers in any examples files and the README.md to the new version that this 15 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). 16 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you 17 | do not have permission to do that, you may request the second reviewer to merge it for you. 18 | 19 | ## Code of Conduct 20 | 21 | ### Our Pledge 22 | 23 | In the interest of fostering an open and welcoming environment, we as 24 | contributors and maintainers pledge to making participation in our project and 25 | our community a harassment-free experience for everyone, regardless of age, body 26 | size, disability, ethnicity, gender identity and expression, level of experience, 27 | nationality, personal appearance, race, religion, or sexual identity and 28 | orientation. 29 | 30 | ### Our Standards 31 | 32 | Examples of behavior that contributes to creating a positive environment 33 | include: 34 | 35 | * Using welcoming and inclusive language 36 | * Being respectful of differing viewpoints and experiences 37 | * Gracefully accepting constructive criticism 38 | * Focusing on what is best for the community 39 | * Showing empathy towards other community members 40 | 41 | Examples of unacceptable behavior by participants include: 42 | 43 | * The use of sexualized language or imagery and unwelcome sexual attention or 44 | advances 45 | * Trolling, insulting/derogatory comments, and personal or political attacks 46 | * Public or private harassment 47 | * Publishing others' private information, such as a physical or electronic 48 | address, without explicit permission 49 | * Other conduct which could reasonably be considered inappropriate in a 50 | professional setting 51 | 52 | ### Our Responsibilities 53 | 54 | Project maintainers are responsible for clarifying the standards of acceptable 55 | behavior and are expected to take appropriate and fair corrective action in 56 | response to any instances of unacceptable behavior. 57 | 58 | Project maintainers have the right and responsibility to remove, edit, or 59 | reject comments, commits, code, wiki edits, issues, and other contributions 60 | that are not aligned to this Code of Conduct, or to ban temporarily or 61 | permanently any contributor for other behaviors that they deem inappropriate, 62 | threatening, offensive, or harmful. 63 | 64 | ### Scope 65 | 66 | This Code of Conduct applies both within project spaces and in public spaces 67 | when an individual is representing the project or its community. Examples of 68 | representing a project or community include using an official project e-mail 69 | address, posting via an official social media account, or acting as an appointed 70 | representative at an online or offline event. Representation of a project may be 71 | further defined and clarified by project maintainers. 72 | 73 | ### Enforcement 74 | 75 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 76 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All 77 | complaints will be reviewed and investigated and will result in a response that 78 | is deemed necessary and appropriate to the circumstances. The project team is 79 | obligated to maintain confidentiality with regard to the reporter of an incident. 80 | Further details of specific enforcement policies may be posted separately. 81 | 82 | Project maintainers who do not follow or enforce the Code of Conduct in good 83 | faith may face temporary or permanent repercussions as determined by other 84 | members of the project's leadership. 85 | 86 | ### Attribution 87 | 88 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 89 | available at [http://contributor-covenant.org/version/1/4][version] 90 | 91 | [homepage]: http://contributor-covenant.org 92 | [version]: http://contributor-covenant.org/version/1/4/ 93 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 OSLabs Beta - dORM 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![image](https://user-images.githubusercontent.com/16947485/114826955-194c0600-9d96-11eb-8db0-87b67944a365.png) 2 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Ask Me Anything !](https://img.shields.io/badge/Ask%20me-anything-1abc9c.svg)](https://github.com/whyWhyDev) 3 | 4 | This is our link to documentation website: https://dorm.land/ 5 | 6 | # What is **dORM**? 7 | 8 | **dORM** is an uber-lightweight postgreSQL query builder for Deno and is currently being expanded into a full-fledged object-relational mapping _(ORM)_ tool. Its purpose is to make your life easier when making SQL queries and let you write queries in familiar Javascript/Typescript syntax and dot notation. dORM runs in, a secure runtime environment which supports Typescript out of the box and offers cloud-based package management among other great features. 9 | 10 | You can chain our methods together, use `.then()` at the end of the query methods or simply await the results; you can even take advantage of Deno’s top-level await. **dORM** is promise-based and makes async database queries a breeze. It also handles creating the connection to the database server, using deno-postgres under the hood. 11 | 12 | # Quick Start up guide 13 | 14 | This guide will cover the basics of getting started with **dORM**. Later on we will explore some of **dORM**’S newest features related to object-relational mapping, but first let’s dive into some essential CRUD functionality with **dORM**’s query builder. 15 | 16 | ## Query Builder 17 | 18 | ### Database connection and initialization 19 | 20 | ### Securely connecting to the database using .env file _(**RECOMMENDED**)_ 21 | 22 | **dORM** can create an _.env_ file for you to securely hold your postgres connection string. From anywhere in your project folder, you can execute this in your terminal: 23 | 24 | - `$deno run --allow-read --allow-write --allow-net --unstable https://deno.land/x/dorm/models/init.ts` 25 | 26 | - This will create _.env_ file in your project’s root directory. 27 | - In your project, import the **dORM** query builder with: 28 | - If you are using a _.env_ file, you can use config like so: 29 | - Instantiate the Dorm class: 30 | 31 | ```javascript 32 | import { Dorm } from `https://deno.land/x/dorm/mod.ts`; 33 | import { config } from 'https://deno.land/x/dotenv/mod.ts'; 34 | const env = config(); 35 | const URL = `postgres://${env.USERNAME}:${env.PASSWORD}@${env.SERVER}:PORTNUMBER/${env.USERNAME}`; 36 | const dorm = new Dorm(URL); 37 | ``` 38 | 39 | ### Directly using dorm class 40 | 41 | ```javascript 42 | const URL = ``; 43 | const dorm = new Dorm(URL); 44 | ``` 45 | 46 | ## CRUD Functionality 47 | 48 | ### INSERT method 49 | 50 | ```javascript 51 | const inserted = await dorm 52 | .insert([ 53 | { name: 'Hello World', email: 'user@dorm.com' }, 54 | { name: 'Elvis', _id: 1, age: 50 }, 55 | ]) 56 | .table('user') 57 | .returning() 58 | .then((data: any) => data.rows) 59 | .catch((e: any) => e); 60 | ``` 61 | 62 | **dORM** simplifies the process of inserting multiple values into multiple columns of a table. If you only have a single object, you can pass that in without putting it inside an array.
63 | `.returning()` with no arguments will function as returning all. 64 |
65 | To use top level await use try catch block: 66 | 67 | ```javascript 68 | try { 69 | const inserted = await dorm 70 | .insert([ 71 | { 72 | 'name':'Hello World', 73 | 'email': 'user@dorm.com' 74 | }, 75 | { 76 | name: 'Elvis', 77 | '_id': 1, age: 50 78 | } 79 | ]) 80 | .table('user') 81 | .returning() 82 | } 83 | catch(e:any) { 84 | console.log(e); 85 | } 86 | ``` 87 | 88 | ### SELECT method 89 | 90 | `.where()` takes as an argument a string that defines a condition. Conditions can contain logical operators such as `AND/OR`. Currently, a value in a `.where()` string can be a string*(wrapped in single quotes)*, a number, null, or boolean. Double-quotes cannot be used inside a single-quoted string value, and neither single nor double quotes can be used anywhere else inside the condition string. Unicode tokens _(\uxxxx.)_ currently cannot be used anywhere in the condition string. 91 | 92 | ```javascript 93 | await dorm 94 | .select('name') 95 | .from('people') 96 | .where('_id=1') 97 | .then((data: any) => { 98 | return data.rows; 99 | }) 100 | .catch((e: any) => { 101 | throw e; 102 | }); 103 | ``` 104 | 105 | If you want to use single quotes inside your single-quoted string value, use two single-quotes in a row _(using backslashes to escape)_ and be sure to use double-quotes around your `.where()` argument. 106 | 107 | ```javascript 108 | .where("name = 'Jack \'\'Killer\'\' Chen' "); 109 | ``` 110 | 111 | ### UPDATE method 112 | 113 | The `.update()` method takes a single object, with the key/value pairs corresponding to the column names and values to update in the database. 114 | 115 | ```javascript 116 | await dorm 117 | .update({ username: 'Dogs', email: 'iamnotagooddog@dogs.com' }) 118 | .table('dropthis') 119 | .where('_id = 10') 120 | .returning() 121 | .then((data: any) => { 122 | return data.rows; 123 | }) 124 | .catch((e: any) => e); 125 | ``` 126 | 127 | Our `.update()` method won’t work without a `.where()` attached. If you for some extravagant reason wanted to update your whole table in such a way, that’s fine: for your convenience and well-being, we’ve provided an `.updateAll()` method that requires (and accepts) no `.where()`. 128 | 129 | Here is an example of updating all rows using **dORM**: 130 | 131 | ```javascript 132 | await dorm 133 | .updateall({ username: 'Dogs', email: 'iamnotagooddog@dogs.com' }) 134 | .table('dropthis') 135 | .returning() 136 | .then((data: any) => { 137 | return data.rows; 138 | }) 139 | .catch((e: any) => e); 140 | ``` 141 | 142 | ### DELETE method 143 | 144 | Similar to `.update()` and `.updateAll()`, **dORM** has `.delete()` and `.deleteAll()`. The `.delete()` method requires a `.where()` clause, `.deleteAll()` does not. And as an extra safeguard, if you do include a `.where()` with `.deleteAll()`, **dORM** will throw an error because it can read your mind and it knows you didn’t intend to do that. 145 | 146 | ```javascript 147 | await dorm 148 | .delete() 149 | .from('dropthis') 150 | .where(`_id = ${updateId}`) 151 | .returning() 152 | .then((data: any) => { 153 | return data; 154 | }) 155 | .catch((e: any) => e); 156 | ``` 157 | 158 | ### DROP method 159 | 160 | `.drop()` for deleting tables. Pass the table as an argument to `.drop()`, or use the `.table()` method or one of its aliases: `.from()` or `.into()`. Please proceed with caution. 161 | 162 | ```javascript 163 | await dorm 164 | .drop() 165 | .from('dropthis') 166 | .then((data: any) => { 167 | return data.rows; 168 | }) 169 | .catch((e: any) => e); 170 | ``` 171 | 172 | ### JOIN method 173 | 174 | **dORM** puts several join methods at your fingertips, each with an alias. 175 | 176 | ```javascript 177 | .innerJoin() OR .join(); 178 | .leftOuterJoin() OR leftJoin(); 179 | .rightOuterJoin() OR .rightJoin(); 180 | .fullOuterJoin() OR .fullJoin(); 181 | ``` 182 | 183 | Every `.join()` must have an accompanying `.on()` method. Here’s a sample usage: 184 | 185 | ```javascript 186 | await dorm 187 | .select() 188 | .from('people') 189 | .join('people_in_films') 190 | .on('people._id = people_in_films.person_id') 191 | .leftJoin('films') 192 | .on('people_in_films.film_id = films._id'); 193 | ``` 194 | 195 | `.on()` takes a string argument that defines a condition for the `.join()`. Although it’s probably most common to put the `.on()` directly after the `.join()` it refers to, **dORM** allows you considerable leeway here. As long as the number of `.on()` methods equals the number of `.join()` methods, **dORM** is happy. It will pair them up in the order they appear, ie. the first on with the first join, second on with second join, etc. 196 | 197 | ### **_Parameterized queries_** 198 | 199 | PostgresQL advised that all values in a query should be parameterized. Here’s how that works with **dORM**. 200 | 201 | With the `.insert()` or `.update()` methods, the values you include will be automatically parameterized. The passed-in object and the final query string sent to the database will look something like this: 202 | 203 | ```javascript 204 | const test = dorm 205 | .insert({'username':'Golden_Retreiver','password': 'golDenR','email':'iamagooddog@dogs.com'}) 206 | .table('userprofile') 207 | .toObj() 208 | 209 | //expected output--> 210 | { 211 | text: "INSERT INTO userprofile (username, password, email) VALUES ($1, $2, $3)", 212 | values: [ 213 | "Golden_Retreiver","golDenR","iamagooddog@dogs.com" 214 | ] 215 | } 216 | ``` 217 | 218 | For `.where()` and `.on()` arguments, **dORM** will parse the argument and parameterize any _string, number, boolean,_ or _null values._ 219 | When **dORM** queries the database, it sends the parameterized query string as the first argument, and an array of values (if any) as the second argument. Postgres handles everything from there, scrubbing the values to ensure no SQL injection can occur. 220 | 221 | ```javascript 222 | const values = [1, ‘Bob’]; 223 | const results = await dorm.raw(‘SELECT * FROM people WHERE id = $1 OR name = $2’, values) 224 | ``` 225 | 226 | ### toString and toObject Methods 227 | 228 | Perhaps there will be times when you want to create a query, but don’t want to send it off to the database just yet. **dORM** has a couple of methods to help you with that. 229 | 230 | A **dORM** query string is sent off to the database upon reaching a .then in the chain, or an await. You can intercept the query string with the `.toString()` method, which returns just the string with the values parameterized (ie. `'...WHERE id = $1'`). If you already have the values handy, that’s great, but if you’d want the values array returns as well, the `.toObject()` (alias .toObj) method will return an object with two properties: text and values. 231 | 232 | ```javascript 233 | const querystring = await dorm.select().from('people').where('id = 1'); 234 | 235 | Returned: { 236 | text: 'SELECT * FROM people WHERE id = $1', 237 | values: [1] 238 | }; 239 | ``` 240 | 241 | ### RAW 242 | 243 | Sometimes you just can’t or don’t want to use our chainable methods to access your database. We get it. For those funky queries that our methods don’t quite _(yet)_ cover, we give you the `dorm.raw()` method. Pass in your query string and we will make the connection for you and send it off to the db server as-is. If you’ve parameterized your values—and of course you have!—you can pass your ordered values array as a second argument to `.raw()` and we’ll send that along too. This method also has aliases: `.rawr()` and `.rawrr()`, of course. 244 | 245 | ```javascript 246 | const values = [1, 'Bob']; 247 | const results = await dorm.raw( 248 | 'SELECT * FROM people WHERE id = $1 OR name = $2', 249 | values 250 | ); 251 | ``` 252 | 253 | ## ORM (**O**bject-**R**elational **M**apping) 254 | 255 | ### MODEL INSTANCES 256 | 257 | **dORM** can create model instances from your database. Run this in your command line terminal: 258 | 259 | ```javascript 260 | $deno run --allow-read --allow-write --allow-net --unstable deno.land/x/dorm/models/init.ts 261 | ``` 262 | 263 | This will create a _.env_ file for you in your app root directory and create place holder for database url. If the _.env_ file is already created, it will be appendeded. 264 | 265 | ```javascript 266 | dorm_databaseURL = 267 | 'postgresql://USERNAME:PASSWORD@localhost:5432/DATABASENAME?schema=public'; 268 | ``` 269 | 270 | Replace `USERNAME`, `PASSWORD ` and `DATABASENAME` with your database information. 271 | 272 | After the _.env_ file was created, execute the following command to get all the relations from your database*(you will also see this instruction in *.env* file)*: 273 | 274 | ```javascript 275 | $deno run --allow-read --allow-write --allow-net --unstable deno.land/x/dorm/models/model-generator.ts 276 | ``` 277 | 278 | This will create a dorm folder containing all of your table relations as model instance files. 279 | -------------------------------------------------------------------------------- /deps.ts: -------------------------------------------------------------------------------- 1 | // DENO-POSTGRES dependecies -------------------------------------------------- 2 | export { Pool, PostgresError } from 'https://deno.land/x/postgres/mod.ts'; 3 | export { PoolClient } from 'https://deno.land/x/postgres@v0.17.0/client.ts'; 4 | export { 5 | assertEquals, 6 | assertNotEquals, 7 | } from 'https://deno.land/std@0.91.0/testing/asserts.ts'; 8 | export { config } from 'https://deno.land/x/dotenv/mod.ts'; 9 | -------------------------------------------------------------------------------- /devDemoFolder/demo.ts: -------------------------------------------------------------------------------- 1 | // import { Dorm } from '../mod.ts'; 2 | // import { config } from '../deps.ts'; 3 | 4 | // const env = config(); 5 | 6 | // const url = `postgres://${env.USERNAME}:${env.PASSWORD}@ziggy.db.elephantsql.com:5432/${env.USERNAME}`; 7 | 8 | // const dorm = new Dorm(url); 9 | 10 | /* -------------------------------------------------------------------------- */ 11 | /* SIMPLE QUERY */ 12 | /* -------------------------------------------------------------------------- */ 13 | 14 | // const simpleSelect = dorm.select().from('people').toString(); 15 | // console.log(simpleSelect); 16 | 17 | // const simpleAwait = await dorm.select().from('species'); 18 | // console.log(simpleAwait); 19 | 20 | // const simpleSelect = await dorm 21 | // .select() 22 | // .from('people') 23 | // .then((data: any) => console.log(data.rows[0])) 24 | // .catch((e) => e); 25 | 26 | // const raw = await dorm.raw('SELECT * FROM people'); 27 | // const rawr = await dorm.rawrr( 28 | // "SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_type='BASE TABLE'" 29 | // ); 30 | // const rawr = await dorm.rawrr( 31 | // "SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'people'" 32 | // ); 33 | 34 | // const rawr = await dorm.raw( 35 | // 'SELECT tc.constraint_name, tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name FROM information_schema.table_constraints AS tc JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name ORDER BY tc.table_name' 36 | // ); 37 | // async function inner(input: any) { 38 | // const arr = []; 39 | // const result = []; 40 | // for (let i = 0; i < input.length; i++) { 41 | // arr.push(input[i].table_name); 42 | // } 43 | // for (let i = 0; i < arr.length; i++) { 44 | // const temp = await dorm.rawrr( 45 | // `SELECT tc.table_schema, tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name FROM information_schema.table_constraints tc JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name JOIN information_schema.constraint_column_usage ccu ON ccu.constraint_name = tc.constraint_name WHERE constraint_type = 'FOREIGN KEY' AND ccu.table_name=${arr[i]}` 46 | // ); 47 | // result.push(temp); 48 | // } 49 | // return result; 50 | // } 51 | // console.log(raw); 52 | 53 | // dorm.drop('dropthis').then(data => { 54 | // console.log(data) 55 | // }); 56 | 57 | /* -------------------------------------------------------------------------- */ 58 | /* COMPLEX QUERY */ 59 | /* -------------------------------------------------------------------------- */ 60 | 61 | /* --------------------------------- BEFORE --------------------------------- */ 62 | 63 | // //Object from front end 64 | // const reqBodyObj = [ 65 | // { name: 'Han', birth_year: '2050' }, 66 | // { name: 'Hanji', hair_color: 'rainbow' }, 67 | // { 68 | // hair_color: 'blonde', 69 | // eye_color: 'green', 70 | // name: 'Nick', 71 | // height: 1, 72 | // }, 73 | // { 74 | // hair_color: 'dark', 75 | // mass: 'fair', 76 | // name: 'Myo', 77 | // height: 198, 78 | // } 79 | // ]; 80 | 81 | // const columns: string[] = []; 82 | // const values: unknown[] = []; 83 | 84 | // reqBodyObj.forEach((obj: any) => { 85 | // Object.keys(obj).forEach((col) => { 86 | // if (!columns.includes(col)) columns.push(col); 87 | // }); 88 | // }); 89 | 90 | // reqBodyObj.forEach((obj: any) => { 91 | // const vals: any = []; 92 | // columns.forEach((col) => { 93 | // if (obj[col] === undefined) { 94 | // vals.push('null'); 95 | // } else if (typeof obj[col] === 'string') { 96 | // vals.push(`'${obj[col]}'`); 97 | // } else { 98 | // vals.push(obj[col]); 99 | // } 100 | // }); 101 | // values.push(vals); 102 | // }); 103 | 104 | // const queryStatement = `INSERT INTO people (${columns}) VALUES (${values}) RETURNING *`; 105 | 106 | // db.query(queryStatement).then(data:any => console.log('From db.query():'data)); 107 | 108 | /* ---------------------------------- AFTER --------------------------------- */ 109 | 110 | // //Object from front end 111 | // const reqBodyObj = [ 112 | // { name: 'Han', birth_year: '2050' }, 113 | // { name: 'Hanji', hair_color: 'rainbow' }, 114 | // { 115 | // hair_color: 'blonde', 116 | // eye_color: 'green', 117 | // name: 'Nick', 118 | // height: 1, 119 | // }, 120 | // { 121 | // hair_color: 'dark', 122 | // mass: 'fair', 123 | // name: 'Myo', 124 | // height: 198, 125 | // }, 126 | // ]; 127 | 128 | // const complexQuery: any = await dorm 129 | // .insert(reqBodyObj) 130 | // .into('people') 131 | // .returning(); 132 | 133 | // console.log(complexQuery.rows); 134 | 135 | /* -------------------------------------------------------------------------- */ 136 | /* INVALID QUERY */ 137 | /* -------------------------------------------------------------------------- */ 138 | 139 | /* ----------------------------- MULTIPLE ACTION ---------------------------- */ 140 | // await dorm 141 | // .select() 142 | // .delete() 143 | // .returning() 144 | // .then((data) => console.log(data)); 145 | 146 | /* ----------------------- MULTIPLE ACTION WITH CATCH ----------------------- */ 147 | // await dorm 148 | // .select() 149 | // .delete() 150 | // .returning() 151 | // .then((data) => console.log(data)) 152 | // .catch((e) => console.log('Error: ', e)); 153 | 154 | /* --------------------- MULTIPLE ACTION WITH TRY CATCH --------------------- */ 155 | // try { 156 | // await dorm.select().delete().returning(); 157 | // } catch (error) { 158 | // console.log('Error: ', error); 159 | // } 160 | -------------------------------------------------------------------------------- /lib/db-connectors/pg-connector.ts: -------------------------------------------------------------------------------- 1 | import { Pool, PoolClient } from '../../deps.ts'; 2 | 3 | let pool: Pool; 4 | 5 | function poolConnect(url: string) { 6 | pool = new Pool(url, 3); 7 | } 8 | 9 | async function query(str: string, vals?: unknown[]) { 10 | try { 11 | const client: PoolClient = await pool.connect(); 12 | let dbResult; 13 | 14 | if (vals && vals.length) { 15 | dbResult = await client.queryObject({ text: str, args: vals }); 16 | } else { 17 | dbResult = await client.queryObject(str); 18 | } 19 | 20 | client.release(); 21 | return dbResult; 22 | } catch (e) { 23 | throw e; 24 | } 25 | } 26 | 27 | export { query, poolConnect }; 28 | -------------------------------------------------------------------------------- /lib/query-builder.ts: -------------------------------------------------------------------------------- 1 | import { query, poolConnect } from './db-connectors/pg-connector.ts'; 2 | import { template } from './sql-template.ts'; 3 | import { validate } from './validate-strings.ts'; 4 | 5 | /* ----------------------------- TYPE INTERFACE ----------------------------- */ 6 | interface Info { 7 | action: { 8 | type: null | string; 9 | table: null | string; 10 | columns: null | string | string[]; 11 | values: unknown[]; 12 | valuesParam: string; 13 | }; 14 | join: Joins[]; 15 | filter: { 16 | where: boolean; 17 | condition?: any; 18 | }; 19 | returning: { 20 | active: boolean; 21 | columns: string | string[]; 22 | }; 23 | } 24 | 25 | interface Joins { 26 | type?: string; 27 | table?: string; 28 | on?: any; 29 | } 30 | 31 | interface Callback { 32 | (key: unknown): unknown; 33 | } 34 | 35 | interface Error { 36 | id: number; 37 | message: string; 38 | } 39 | 40 | /* -------------------------------------------------------------------------- */ 41 | /* DORM CLASS */ 42 | /* -------------------------------------------------------------------------- */ 43 | export class Dorm { 44 | callOrder: string[]; 45 | error: Error; 46 | info: Info; 47 | template: any; 48 | constructor(url: string) { 49 | this.callOrder = []; 50 | 51 | this.error = { 52 | id: 0, 53 | message: '', 54 | }; 55 | 56 | this.info = { 57 | action: { 58 | type: null, 59 | table: null, 60 | columns: '*', 61 | values: [], 62 | valuesParam: '', 63 | }, 64 | join: [], 65 | filter: { 66 | where: false, 67 | condition: null, 68 | }, 69 | returning: { 70 | active: false, 71 | columns: '*', 72 | }, 73 | }; 74 | 75 | poolConnect(url); 76 | this.template = template.bind(this); 77 | } 78 | /* ------------------------------ ERROR CHECKING ----------------------------- */ 79 | checkErrors(group: number) { 80 | const errorObj = this.error; 81 | const error = 82 | (group === 1 && !!this.info.action.type) || 83 | (group === 2 && !!this.info.action.table) || 84 | (group === 3 && !!this.info.filter.where) || 85 | (group === 4 && !!this.info.returning.active); 86 | 87 | if (error) errorObj.id = group; 88 | return error; 89 | } 90 | 91 | setErrorMessage() { 92 | const msg: any = { 93 | 1: 'No multiple actions', 94 | 2: 'No multiple tables', 95 | 3: 'No multiple wheres', 96 | 4: 'No multiple returning', 97 | 5: 'Number of ONs must equal number of JOINs', 98 | 7: 'Insert data must be an object or array of objects', 99 | 8: 'Cannot have empty array/object of insert/update data', 100 | 9: 'No returning on select', 101 | 10: 'No delete without where (use deleteAll to delete all rows)', 102 | 11: 'deleteAll cannot have where', 103 | 12: 'Invalid on clause', 104 | 13: 'Invalid where clause', 105 | 14: 'No update without where (use updateAll to update all rows)', 106 | 15: 'updateAll cannot have where', 107 | 98: 'Invalid tables (cannot contain quotes)', 108 | 99: 'Invalid columns (cannot contain quotes)', 109 | }; 110 | this.error.message = msg[this.error.id]; 111 | } 112 | 113 | finalErrorCheck() { 114 | if (this.info.action.type === 'SELECT' && this.info.returning.active) { 115 | this.error.id = 9; 116 | return true; 117 | } 118 | if ( 119 | this.info.action.type === 'DELETE' && 120 | (!this.info.filter.where || !this.info.filter.condition) 121 | ) { 122 | this.error.id = 10; 123 | return true; 124 | } 125 | if (this.info.action.type === 'DELETEALL' && this.info.filter.where) { 126 | this.error.id = 11; 127 | return true; 128 | } 129 | 130 | for (const el of this.info.join) { 131 | if (!validate.columnsTables(el.table)) { 132 | this.error.id = 98; 133 | return true; 134 | } 135 | } 136 | 137 | if (!validate.columnsTables(this.info.action.table)) { 138 | this.error.id = 98; 139 | return true; 140 | } 141 | 142 | if ( 143 | !validate.columnsTables(this.info.action.columns) || 144 | !validate.columnsTables(this.info.returning.columns) 145 | ) { 146 | this.error.id = 99; 147 | return true; 148 | } 149 | 150 | return false; 151 | } 152 | 153 | /* ------------------------------ INSERT METHOD ----------------------------- */ 154 | insert(arg: any | unknown[]) { 155 | this.callOrder.push('INSERT'); 156 | 157 | if (typeof arg !== 'object') { 158 | this.error.id = 7; 159 | return this; 160 | } 161 | 162 | if (Array.isArray(arg)) { 163 | if (!arg.length) { 164 | this.error.id = 8; 165 | return this; 166 | } 167 | } 168 | 169 | if (this.checkErrors(1)) return this; 170 | 171 | this.info.action.type = 'INSERT'; 172 | 173 | const columns: string[] = []; 174 | 175 | const values: unknown[] = []; 176 | 177 | if (!Array.isArray(arg)) { 178 | if (!Object.keys(arg).length) { 179 | this.error.id = 8; 180 | return this; 181 | } 182 | const [column, value] = Object.entries(arg)[0]; 183 | 184 | columns.push(column); 185 | const val: any = []; 186 | if (value === undefined) { 187 | val.push(null); 188 | } else { 189 | val.push(value); 190 | } 191 | values.push(val); 192 | } else { 193 | arg.forEach((obj: any) => { 194 | if (!Object.keys(obj).length) { 195 | this.error.id = 8; 196 | return this; 197 | } 198 | Object.keys(obj).forEach((col) => { 199 | if (!columns.includes(col)) columns.push(col); 200 | }); 201 | }); 202 | 203 | if (!validate.columnsTables(columns)) { 204 | this.error.id = 99; 205 | return this; 206 | } 207 | 208 | arg.forEach((obj: any) => { 209 | const vals: any = []; 210 | columns.forEach((col) => { 211 | if (obj[col] === undefined) { 212 | vals.push(null); 213 | } else { 214 | arg.forEach((obj: any) => { 215 | if (!Object.keys(obj).length) { 216 | this.error.id = 8; 217 | return this; 218 | } 219 | Object.keys(obj).forEach((col) => { 220 | if (!columns.includes(col)) columns.push(col); 221 | }); 222 | }); 223 | 224 | if (!validate.columnsTables(columns)) { 225 | this.error.id = 99; 226 | return this; 227 | } 228 | 229 | arg.forEach((obj: any) => { 230 | const vals: any = []; 231 | columns.forEach((col) => { 232 | if (obj[col] === undefined) { 233 | vals.push(null); 234 | } else { 235 | vals.push(obj[col]); 236 | } 237 | }); 238 | values.push(vals); 239 | }); 240 | } 241 | }); 242 | values.push(vals); 243 | }); 244 | } 245 | 246 | this.info.action.columns = columns.join(', '); 247 | 248 | // create parameter strings 249 | this.info.action.values = values.flat(); 250 | let paramCount = 0; 251 | const valuesBound = values.map((el: any) => 252 | el.map((ele: any) => { 253 | paramCount++; 254 | return `$${paramCount}`; 255 | }) 256 | ); 257 | 258 | valuesBound.forEach((data: any, index: number) => { 259 | const tail = index === valuesBound.length - 1 ? '' : ', '; 260 | this.info.action.valuesParam += `(${data.join(', ')})${tail}`; 261 | }); 262 | 263 | return this; 264 | } 265 | 266 | /* ------------------------------ SELECT METHOD ----------------------------- */ 267 | select(arg?: string) { 268 | this.callOrder.push('SELECT'); 269 | 270 | if (this.checkErrors(1)) return this; 271 | 272 | this.info.action.type = 'SELECT'; 273 | if (arg) this.info.action.columns = arg; 274 | 275 | return this; 276 | } 277 | 278 | /* ------------------------------ UPDATE METHOD ----------------------------- */ 279 | update(obj: any) { 280 | this.callOrder.push('UPDATE'); 281 | 282 | if (this.checkErrors(1)) return this; 283 | 284 | if (!Object.keys(obj).length || Array.isArray(obj)) { 285 | this.error.id = 8; 286 | return this; 287 | } 288 | 289 | if (!validate.columnsTables(Object.keys(obj))) { 290 | this.error.id = 99; 291 | return this; 292 | } 293 | 294 | this.info.action.type = 'UPDATE'; 295 | this.info.action.columns = ''; 296 | 297 | Object.keys(obj).forEach((col, index) => { 298 | const str = `${col} = $${index + 1}`; 299 | 300 | this.info.action.values.push(obj[col]); 301 | 302 | const tail = index === Object.keys(obj).length - 1 ? '' : ', '; 303 | this.info.action.columns += `${str + tail}`; 304 | }); 305 | return this; 306 | } 307 | 308 | /* ------------------------------ DELETE METHODS ----------------------------- */ 309 | delete(arg?: string) { 310 | this.callOrder.push('DELETE'); 311 | 312 | if (this.checkErrors(1)) return this; 313 | 314 | this.info.action.type = 'DELETE'; 315 | if (arg) this.info.action.table = arg; 316 | 317 | return this; 318 | } 319 | 320 | deleteAll(arg?: string) { 321 | this.callOrder.push('DELETEALL'); 322 | 323 | if (this.checkErrors(1)) return this; 324 | 325 | this.info.action.type = 'DELETEALL'; 326 | if (arg) this.info.action.table = arg; 327 | 328 | return this; 329 | } 330 | 331 | /* ------------------------------- DROP METHOD ------------------------------ */ 332 | drop(arg?: string) { 333 | this.callOrder.push('DROP'); 334 | 335 | if (this.checkErrors(1)) return this; 336 | 337 | this.info.action.type = 'DROP'; 338 | if (arg) this.info.action.table = arg; 339 | return this; 340 | } 341 | 342 | /* ------------------------------ TABLE METHOD ------------------------------ */ 343 | table(arg: string) { 344 | this.callOrder.push('TABLE'); 345 | 346 | if (this.checkErrors(2)) return this; 347 | this.info.action.table = arg; 348 | return this; 349 | } 350 | /** 351 | * Alias for table method 352 | */ 353 | from = this.table; 354 | into = this.table; 355 | 356 | /* ------------------------------ JOIN METHODS ------------------------------ */ 357 | join(arg: string) { 358 | this.callOrder.push('JOIN-INNER'); 359 | const joinList = this.info.join; 360 | for (const el of joinList) { 361 | if (!el.type) { 362 | el.type = 'INNER JOIN'; 363 | el.table = arg; 364 | return this; 365 | } 366 | } 367 | joinList.push({ type: 'INNER JOIN', table: arg }); 368 | return this; 369 | } 370 | 371 | leftJoin(arg: string) { 372 | this.callOrder.push('JOIN-LEFT'); 373 | 374 | const joinList = this.info.join; 375 | for (const el of joinList) { 376 | if (!el.type) { 377 | el.type = 'LEFT JOIN'; 378 | el.table = arg; 379 | return this; 380 | } 381 | } 382 | 383 | joinList.push({ type: 'LEFT JOIN', table: arg }); 384 | return this; 385 | } 386 | 387 | rightJoin(arg: string) { 388 | this.callOrder.push('JOIN-RIGHT'); 389 | 390 | const joinList = this.info.join; 391 | for (const el of joinList) { 392 | if (!el.type) { 393 | el.type = 'RIGHT JOIN'; 394 | el.table = arg; 395 | return this; 396 | } 397 | } 398 | joinList.push({ type: 'RIGHT JOIN', table: arg }); 399 | 400 | return this; 401 | } 402 | 403 | fullJoin(arg: string) { 404 | this.callOrder.push('JOIN-FULL'); 405 | 406 | const joinList = this.info.join; 407 | 408 | for (const el of joinList) { 409 | if (!el.type) { 410 | el.type = 'FULL JOIN'; 411 | el.table = arg; 412 | return this; 413 | } 414 | } 415 | joinList.push({ type: 'FULL JOIN', table: arg }); 416 | 417 | return this; 418 | } 419 | /** 420 | * Alias for join method 421 | */ 422 | innerJoin = this.join; 423 | leftOuterJoin = this.leftJoin; 424 | rightOuterJoin = this.rightJoin; 425 | fullOuterJoin = this.fullJoin; 426 | 427 | /* -------------------------------- ON METHOD ------------------------------- */ 428 | on(arg: string) { 429 | this.callOrder.push('ON'); 430 | 431 | const validated = validate.onWhere(arg); 432 | 433 | if (validated === 'Error') { 434 | this.error.id = 12; 435 | return this; 436 | } 437 | 438 | const joinList = this.info.join; 439 | for (const el of joinList) { 440 | if (!el.on) { 441 | el.on = validated; 442 | return this; 443 | } 444 | } 445 | joinList.push({ on: validated }); 446 | 447 | return this; 448 | } 449 | 450 | /* ------------------------------ WHERE METHOD ------------------------------ */ 451 | where(arg: string) { 452 | this.callOrder.push('WHERE'); 453 | 454 | if (this.checkErrors(3)) return this; 455 | 456 | const validated = validate.onWhere(arg); 457 | 458 | if (validated === 'Error') { 459 | this.error.id = 13; 460 | return this; 461 | } 462 | 463 | this.info.filter.where = true; 464 | this.info.filter.condition = validated; 465 | 466 | return this; 467 | } 468 | 469 | /* ---------------------------- RETURNING METHOD ---------------------------- */ 470 | returning(arg?: string) { 471 | this.callOrder.push('RETURNING'); 472 | 473 | if (this.checkErrors(4)) return this; 474 | 475 | this.info.returning.active = true; 476 | if (arg) this.info.returning.columns = arg; 477 | return this; 478 | } 479 | 480 | /* -------------------------------------------------------------------------- */ 481 | /* QUERY BUILDER FUNCTIONS */ 482 | /* -------------------------------------------------------------------------- */ 483 | 484 | /* ------------------------------ RESET METHOD ------------------------------ */ 485 | private _reset() { 486 | // clear info for future function 487 | this.callOrder = []; 488 | 489 | this.error = { 490 | id: 0, 491 | message: '', 492 | }; 493 | 494 | this.info = { 495 | action: { 496 | type: null, 497 | table: null, 498 | columns: '*', 499 | values: [], 500 | valuesParam: '', 501 | }, 502 | join: [], 503 | filter: { 504 | where: false, 505 | condition: null, 506 | }, 507 | returning: { 508 | active: false, 509 | columns: '*', 510 | }, 511 | }; 512 | } 513 | 514 | /* ------------------------------- THEN METHOD ------------------------------ */ 515 | async then(callback: Callback, fail: Callback = (rej) => rej) { 516 | this.finalErrorCheck(); 517 | 518 | if (this.error.id) { 519 | this.setErrorMessage(); 520 | const { message } = this.error; 521 | this._reset(); 522 | 523 | const cbText = callback.toString(); 524 | 525 | if (isNative(cbText)) { 526 | return await callback(Promise.reject(message)); 527 | } 528 | return await fail(Promise.reject(message)); 529 | } 530 | 531 | let result: any; 532 | try { 533 | const params = this.info.action.values; 534 | result = await query(this.toString(), params); 535 | } catch (e) { 536 | this._reset(); 537 | 538 | const cbText = callback.toString(); 539 | 540 | if (isNative(cbText)) { 541 | return await callback(Promise.reject(e)); 542 | } 543 | return await fail(Promise.reject(e)); 544 | } 545 | 546 | try { 547 | return await callback(result); 548 | } catch (error) { 549 | throw error; 550 | } 551 | 552 | // thanks to David Walsh at https://davidwalsh.name/detect-native-function 553 | function isNative(fn: any) { 554 | return /\{\s*\[native code\]\s*\}/.test('' + fn); 555 | } 556 | } 557 | 558 | /* ----------------------------- TOSTRING METHOD ---------------------------- */ 559 | toString() { 560 | this.finalErrorCheck(); 561 | 562 | if (this.error.id) { 563 | this.setErrorMessage(); 564 | const { message } = this.error; 565 | this._reset(); 566 | throw message; 567 | } 568 | 569 | const action = this.info.action.type; 570 | const joinList = this.info.join; 571 | const filter = this.info.filter.where; 572 | const returning = this.info.returning.active; 573 | 574 | let queryTemplate = ''; 575 | 576 | if (action) queryTemplate = this.template(action); 577 | 578 | while (joinList.length) { 579 | const el = joinList[0]; 580 | if (el.type?.includes('JOIN') && el.on) { 581 | queryTemplate += this.template('JOIN'); 582 | 583 | const params = validate.insertParams( 584 | el.on.tokens, 585 | this.info.action.values.length + 1 586 | ); 587 | this.info.action.values.push(...el.on.values); 588 | 589 | el.on = params.join(' '); 590 | queryTemplate += this.template('ON'); 591 | } else { 592 | this.error.id = 5; 593 | this.setErrorMessage(); 594 | const { message } = this.error; 595 | this._reset(); 596 | throw message; 597 | } 598 | joinList.shift(); 599 | } 600 | 601 | if (this.info.filter.where) { 602 | const whereCondition = this.info.filter.condition; 603 | const params = validate.insertParams( 604 | whereCondition.tokens, 605 | this.info.action.values.length + 1 606 | ); 607 | this.info.action.values.push(...whereCondition.values); 608 | 609 | this.info.filter.condition = params.join(' '); 610 | 611 | queryTemplate += this.template('WHERE'); 612 | } 613 | 614 | if (returning) queryTemplate += this.template('RETURNING'); 615 | 616 | this._reset(); 617 | 618 | return queryTemplate; 619 | } 620 | 621 | toObj() { 622 | const values = this.info.action.values; 623 | const text = this.toString(); 624 | return { 625 | text, 626 | values, 627 | }; 628 | } 629 | /** 630 | * Alias for toObj method 631 | */ 632 | toObject = this.toObj; 633 | 634 | /* ------------------------------ RAW METHOD ------------------------------ */ 635 | async raw(arg: string, vals: unknown[] = []) { 636 | return await query(arg, vals); 637 | } 638 | rawr = this.raw; 639 | rawrr = this.raw; 640 | } 641 | -------------------------------------------------------------------------------- /lib/sql-template.ts: -------------------------------------------------------------------------------- 1 | import { Dorm } from './query-builder.ts'; 2 | 3 | export function template(this: Dorm, arg: string): string { 4 | return ( 5 | { 6 | INSERT: `INSERT INTO ${this.info.action.table} (${this.info.action.columns}) VALUES ${this.info.action.valuesParam}`, 7 | SELECT: `SELECT ${this.info.action.columns} FROM ${this.info.action.table}`, 8 | UPDATE: `UPDATE ${this.info.action.table} SET ${this.info.action.columns}`, 9 | UPDATEALL: `UPDATE ${this.info.action.table} SET ${this.info.action.columns}`, 10 | DELETE: `DELETE FROM ${this.info.action.table}`, 11 | DELETEALL: `DELETE FROM ${this.info.action.table}`, 12 | DROP: `DROP TABLE ${this.info.action.table}`, 13 | JOIN: ` ${this.info.join[0]?.type} ${this.info.join[0]?.table}`, 14 | ON: ` ON ${this.info.join[0]?.on}`, 15 | WHERE: ` WHERE ${this.info.filter.condition}`, 16 | RETURNING: ` RETURNING ${this.info.returning.columns}`, 17 | }[arg] ?? '' 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /lib/validate-strings.ts: -------------------------------------------------------------------------------- 1 | const validate = { 2 | onWhere: function (str: string): any { 3 | const tokens = this.tokenize(str); 4 | 5 | if (tokens === 'Error') return tokens; 6 | 7 | const values: unknown[] = []; 8 | 9 | tokens.forEach((token, i) => { 10 | if (token === 'true') { 11 | values.push(true); 12 | tokens[i] = '$'; 13 | } 14 | if (token === 'false') { 15 | values.push(false); 16 | tokens[i] = '$'; 17 | } 18 | if (token === 'null') { 19 | values.push(null); 20 | tokens[i] = '$'; 21 | } 22 | if (token[0] === "'" && token[token.length - 1] === "'") { 23 | values.push(token.slice(1, token.length - 1)); 24 | tokens[i] = '$'; 25 | } 26 | const parsedInt = parseInt(token); 27 | if (!isNaN(parsedInt)) { 28 | values.push(parsedInt); 29 | tokens[i] = '$'; 30 | } 31 | }); 32 | 33 | return { tokens, values }; 34 | }, 35 | 36 | insertParams: function (tokens: string[], currParam: number) { 37 | tokens.forEach((token, i) => { 38 | if (token === '$') tokens[i] = `$${currParam++}`; 39 | }); 40 | return tokens; 41 | }, 42 | 43 | columnsTables: function (arr?: string[] | string | null): boolean { 44 | if (!arr) return true; 45 | arr = typeof arr === 'string' ? [arr] : arr; 46 | 47 | for (const el of arr) { 48 | if (typeof el !== 'string') return false; 49 | if (el.includes('"') || el.includes("'") || el.includes('\\u')) 50 | return false; 51 | } 52 | return true; 53 | }, 54 | 55 | tokenize: function (str: string) { 56 | let i = 0; 57 | const tokens: string[] = []; 58 | let curr = ''; 59 | let insideString = false; 60 | let readyForString = true; 61 | let escapeNextChar = false; 62 | 63 | while (i < str.length) { 64 | const char = str[i]; 65 | 66 | if (escapeNextChar) { 67 | escapeNextChar = false; 68 | curr += char; 69 | i++; 70 | continue; 71 | } 72 | 73 | if (char === "'") { 74 | if (!readyForString) { 75 | return 'Error'; 76 | } 77 | if (str[i + 1] === "'") { 78 | curr += "'"; 79 | i += 2; 80 | continue; 81 | } 82 | curr += char; 83 | insideString = !insideString; 84 | if (!insideString) { 85 | tokens.push(curr); 86 | readyForString = false; 87 | curr = ''; 88 | } 89 | i++; 90 | continue; 91 | } 92 | 93 | if (insideString) { 94 | 95 | if (char === '\\') escapeNextChar = true; 96 | 97 | curr += char; 98 | i++; 99 | continue; 100 | } 101 | 102 | if ('\\"'.includes(char)) return 'Error'; 103 | 104 | // comparison string below contains tab character at index 1 105 | if (' =()'.includes(char)) { 106 | if (curr.length) { 107 | if ('=('.includes(char)) readyForString = true; 108 | tokens.push(curr); 109 | curr = ''; 110 | } 111 | 112 | if ('=()'.includes(char)) tokens.push(char); 113 | } else { 114 | curr += char; 115 | } 116 | i++; 117 | continue; 118 | } 119 | if (insideString) return 'Error'; 120 | if (curr.length) tokens.push(curr); 121 | 122 | return tokens; 123 | }, 124 | }; 125 | 126 | export { validate }; 127 | -------------------------------------------------------------------------------- /mod.ts: -------------------------------------------------------------------------------- 1 | export { Dorm } from './lib/query-builder.ts'; 2 | -------------------------------------------------------------------------------- /models/generator-helper.ts: -------------------------------------------------------------------------------- 1 | /* ------------------------------- INTERFACES ------------------------------- */ 2 | interface Obj { 3 | table_name: string; 4 | table_schema: string; 5 | column_name: string; 6 | ordinal_position: number; 7 | column_default: null | string; 8 | is_nullable: string; 9 | data_type: string; 10 | udt_name: string; 11 | is_updatable: string; 12 | constraint_name: string | null; 13 | constraint_type: string | null; 14 | foreign_table_name: string | null; 15 | foreign_column_name: string | null; 16 | } 17 | 18 | /** 19 | * This is a helper function that generates models for the tables in the 20 | * database into user's directory. 21 | * 22 | * The model files will be created inside the 'model' directory 23 | * 24 | * @param {unknown[]} arr Takes in a resulted query from 'relationships.sql' 25 | */ 26 | 27 | function _columnHelper(obj: Obj) { 28 | const result: any = {}; 29 | 30 | if (obj.column_default) result['autoIncrement'] = true; 31 | 32 | result['dataType'] = obj.udt_name; 33 | 34 | obj.is_nullable === 'YES' 35 | ? (result['nullable'] = true) 36 | : (result['nullable'] = false); 37 | 38 | if (obj.constraint_type === 'PRIMARY KEY') { 39 | result['primaryKey'] = true; 40 | } else if (obj.constraint_type === 'FOREIGN KEY') { 41 | result['reference'] = { 42 | table: obj.foreign_table_name, 43 | column: obj.foreign_column_name, 44 | }; 45 | } 46 | 47 | return result; 48 | } 49 | 50 | function _generatorHelper(arr: any) { 51 | const result: any = {}; 52 | 53 | // Loop through the columns and make an object for the model 54 | for (let i = 0; i < arr.length; i++) { 55 | if (!result[arr[i].table_name]) result[arr[i].table_name] = {}; 56 | result[arr[i].table_name][arr[i].column_name] = _columnHelper(arr[i]); 57 | } 58 | 59 | return result; 60 | } 61 | 62 | export default _generatorHelper; 63 | -------------------------------------------------------------------------------- /models/init.ts: -------------------------------------------------------------------------------- 1 | import { config } from '../deps.ts'; 2 | 3 | const env = config(); 4 | 5 | const envFileText = ` 6 | 7 | # Inserted by 'dORM init': 8 | #-------------------------------------------------------------------------- 9 | # DORM: PUT YOUR POSTGRES DATABASE URL HERE | 10 | #-------------------------------------------------------------------------- 11 | 12 | # dORM supports the native connection string format for PostgreSQL. 13 | 14 | dorm_databaseURL='postgresql://USERNAME:PASSWORD@localhost:5432/DATABASENAME?schema=public' 15 | 16 | # Please run the following command in your terminal to generate model : 17 | # deno run --allow-read --allow-write --allow-net --unstable https://deno.land/x/dorm/models/model-generator.ts 18 | 19 | `; 20 | 21 | // Case 1: when user does not have .env file 22 | // Case 2: when use does have .env file but does not have dorm setting 23 | if (!env.dorm_databaseURL) { 24 | const writeEnv = Deno.writeTextFile('.env', envFileText, { append: true }); 25 | writeEnv.then(() => console.log('DORM: .env file edited.')); 26 | } else { 27 | // Case 3: when user does have .env file and also dorm setting 28 | console.log( 29 | 'DORM: .env file already has a dorm_databaseURL environment variable' 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /models/model-generator.ts: -------------------------------------------------------------------------------- 1 | import { config } from '../deps.ts'; 2 | import { query, poolConnect } from '../lib/db-connectors/pg-connector.ts'; 3 | import generator from './generator-helper.ts'; 4 | 5 | const env = config(); 6 | 7 | const url = env.dorm_databaseURL; 8 | 9 | poolConnect(url); 10 | 11 | const __dirname = new URL('.', import.meta.url).pathname; 12 | 13 | const modelQuery = Deno.readTextFileSync(`${__dirname}relationships.sql`); 14 | 15 | const informationSchema = await query(modelQuery); 16 | 17 | const databaseTables = generator(informationSchema.rows); 18 | 19 | Deno.mkdirSync('./dorm', { recursive: true }); 20 | 21 | Object.keys(databaseTables).forEach((table) => { 22 | const tablePrettier = JSON.stringify(databaseTables[table], null, 2).replace( 23 | /"([^"]+)":/g, 24 | '$1:' 25 | ); 26 | 27 | const modelFileText = `MODEL IS STILL UNDER CONSTRUCTION SORRY!!\n\nimport { Model } from 'https://deno.land/x/dorm/mod.ts';\n\nconst ${table} = new Model('${table}', ${tablePrettier})\n\nexport default ${table};`; 28 | 29 | /** 30 | * Make directory in the root folder and create model files inside 'dorm' directory 31 | */ 32 | Deno.writeTextFileSync(`dorm/${table}.ts`, modelFileText); 33 | console.log(`DORM: created <${table}> model file`); 34 | }); 35 | -------------------------------------------------------------------------------- /models/relationships.sql: -------------------------------------------------------------------------------- 1 | SELECT ist.table_name, crt.* 2 | FROM information_schema.tables AS ist 3 | LEFT JOIN 4 | (SELECT isc.table_schema, isc.table_name, isc.column_name, isc.ordinal_position, isc.column_default, isc.is_nullable, isc.data_type, isc.udt_name, isc.is_updatable, 5 | pfkt.constraint_name, pfkt.constraint_type, pfkt.foreign_table_name, pfkt.foreign_column_name 6 | FROM INFORMATION_SCHEMA.COLUMNS AS isc 7 | LEFT JOIN 8 | (SELECT istc.constraint_name, istc.constraint_type, istc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name 9 | FROM information_schema.table_constraints AS istc 10 | JOIN information_schema.key_column_usage AS kcu 11 | ON istc.constraint_name = kcu.constraint_name 12 | JOIN information_schema.constraint_column_usage AS ccu 13 | ON ccu.constraint_name = istc.constraint_name 14 | WHERE constraint_type = 'FOREIGN KEY' OR constraint_type = 'PRIMARY KEY') AS pfkt 15 | ON isc.column_name = pfkt.column_name AND isc.table_name = pfkt.table_name) AS crt 16 | ON crt.table_name = ist.table_name 17 | WHERE ist.table_schema='public' AND ist.table_type='BASE TABLE' 18 | ORDER BY ist.table_name, crt.ordinal_position -------------------------------------------------------------------------------- /test-suite/db_test_starwars_create.sql: -------------------------------------------------------------------------------- 1 | 2 | -- PostgreSQL database dump 3 | -- 4 | 5 | -- Dumped from database version 11.3 (Ubuntu 11.3-1.pgdg18.04+1) 6 | -- Dumped by pg_dump version 11.5 7 | 8 | -- Started on 2019-09-11 16:56:10 PDT 9 | 10 | SET statement_timeout 11 | = 0; 12 | SET lock_timeout 13 | = 0; 14 | SET idle_in_transaction_session_timeout 15 | = 0; 16 | SET client_encoding 17 | = 'UTF8'; 18 | SET standard_conforming_strings 19 | = on; 20 | SELECT pg_catalog.set_config('search_path', '', false); 21 | SET check_function_bodies 22 | = false; 23 | SET xmloption 24 | = content; 25 | SET client_min_messages 26 | = warning; 27 | SET row_security 28 | = off; 29 | 30 | CREATE TABLE public.people 31 | ( 32 | "_id" serial NOT NULL, 33 | "name" varchar NOT NULL, 34 | "mass" varchar, 35 | "hair_color" varchar, 36 | "skin_color" varchar, 37 | "eye_color" varchar, 38 | "birth_year" varchar, 39 | "gender" varchar, 40 | "species_id" INT, 41 | "homeworld_id" INT, 42 | "height" integer, 43 | CONSTRAINT "people_pk" PRIMARY KEY ("_id") 44 | ) 45 | WITH ( 46 | OIDS=FALSE 47 | ); 48 | 49 | 50 | 51 | CREATE TABLE public.films 52 | ( 53 | "_id" serial NOT NULL, 54 | "title" varchar NOT NULL, 55 | "episode_id" integer NOT NULL, 56 | "opening_crawl" varchar NOT NULL, 57 | "director" varchar NOT NULL, 58 | "producer" varchar NOT NULL, 59 | "release_date" DATE NOT NULL, 60 | CONSTRAINT "films_pk" PRIMARY KEY ("_id") 61 | ) 62 | WITH ( 63 | OIDS=FALSE 64 | ); 65 | 66 | 67 | 68 | CREATE TABLE public.people_in_films 69 | ( 70 | "_id" serial NOT NULL, 71 | "person_id" INT NOT NULL, 72 | "film_id" INT NOT NULL, 73 | CONSTRAINT "people_in_films_pk" PRIMARY KEY ("_id") 74 | ) 75 | WITH ( 76 | OIDS=FALSE 77 | ); 78 | 79 | 80 | 81 | CREATE TABLE public.planets 82 | ( 83 | "_id" serial NOT NULL, 84 | "name" varchar, 85 | "rotation_period" integer, 86 | "orbital_period" integer, 87 | "diameter" integer, 88 | "climate" varchar, 89 | "gravity" varchar, 90 | "terrain" varchar, 91 | "surface_water" varchar, 92 | "population" bigint, 93 | CONSTRAINT "planets_pk" PRIMARY KEY ("_id") 94 | ) 95 | WITH ( 96 | OIDS=FALSE 97 | ); 98 | 99 | 100 | 101 | CREATE TABLE public.species 102 | ( 103 | "_id" serial NOT NULL, 104 | "name" varchar NOT NULL, 105 | "classification" varchar, 106 | "average_height" varchar, 107 | "average_lifespan" varchar, 108 | "hair_colors" varchar, 109 | "skin_colors" varchar, 110 | "eye_colors" varchar, 111 | "language" varchar, 112 | "homeworld_id" INT, 113 | CONSTRAINT "species_pk" PRIMARY KEY ("_id") 114 | ) 115 | WITH ( 116 | OIDS=FALSE 117 | ); 118 | 119 | 120 | 121 | CREATE TABLE public.vessels 122 | ( 123 | "_id" serial NOT NULL, 124 | "name" varchar NOT NULL, 125 | "manufacturer" varchar, 126 | "model" varchar, 127 | "vessel_type" varchar NOT NULL, 128 | "vessel_class" varchar NOT NULL, 129 | "cost_in_credits" INT, 130 | "length" varchar, 131 | "max_atmosphering_speed" varchar, 132 | "crew" integer, 133 | "passengers" integer, 134 | "cargo_capacity" varchar, 135 | "consumables" varchar, 136 | CONSTRAINT "vessels_pk" PRIMARY KEY ("_id") 137 | ) 138 | WITH ( 139 | OIDS=FALSE 140 | ); 141 | 142 | 143 | 144 | CREATE TABLE public.species_in_films 145 | ( 146 | "_id" serial NOT NULL, 147 | "film_id" INT NOT NULL, 148 | "species_id" INT NOT NULL, 149 | CONSTRAINT "species_in_films_pk" PRIMARY KEY ("_id") 150 | ) 151 | WITH ( 152 | OIDS=FALSE 153 | ); 154 | 155 | 156 | 157 | CREATE TABLE public.planets_in_films 158 | ( 159 | "_id" serial NOT NULL, 160 | "film_id" INT NOT NULL, 161 | "planet_id" INT NOT NULL, 162 | CONSTRAINT "planets_in_films_pk" PRIMARY KEY ("_id") 163 | ) 164 | WITH ( 165 | OIDS=FALSE 166 | ); 167 | 168 | 169 | 170 | CREATE TABLE public.pilots 171 | ( 172 | "_id" serial NOT NULL, 173 | "person_id" INT NOT NULL, 174 | "vessel_id" INT NOT NULL, 175 | CONSTRAINT "pilots_pk" PRIMARY KEY ("_id") 176 | ) 177 | WITH ( 178 | OIDS=FALSE 179 | ); 180 | 181 | 182 | 183 | CREATE TABLE public.vessels_in_films 184 | ( 185 | "_id" serial NOT NULL, 186 | "vessel_id" INT NOT NULL, 187 | "film_id" INT NOT NULL, 188 | CONSTRAINT "vessels_in_films_pk" PRIMARY KEY ("_id") 189 | ) 190 | WITH ( 191 | OIDS=FALSE 192 | ); 193 | 194 | 195 | 196 | CREATE TABLE public.starship_specs 197 | ( 198 | "_id" serial NOT NULL, 199 | "hyperdrive_rating" varchar, 200 | "MGLT" varchar, 201 | "vessel_id" INT NOT NULL, 202 | CONSTRAINT "starship_specs_pk" PRIMARY KEY ("_id") 203 | ) 204 | WITH ( 205 | OIDS=FALSE 206 | ); 207 | 208 | CREATE TABLE public.dropthis 209 | ( 210 | "_id" serial PRIMARY KEY, 211 | "username" VARCHAR ( 150 ) NULL, 212 | "email" VARCHAR ( 255 ) NULL 213 | ) 214 | WITH ( 215 | OIDS=FALSE 216 | ); 217 | 218 | ALTER TABLE public.people ADD CONSTRAINT "people_fk0" FOREIGN KEY ("species_id") REFERENCES public.species("_id"); 219 | ALTER TABLE public.people ADD CONSTRAINT "people_fk1" FOREIGN KEY ("homeworld_id") REFERENCES public.planets("_id"); 220 | 221 | 222 | ALTER TABLE public.people_in_films ADD CONSTRAINT "people_in_films_fk0" FOREIGN KEY ("person_id") REFERENCES public.people("_id"); 223 | ALTER TABLE public.people_in_films ADD CONSTRAINT "people_in_films_fk1" FOREIGN KEY ("film_id") REFERENCES public.films("_id"); 224 | 225 | 226 | ALTER TABLE public.species ADD CONSTRAINT "species_fk0" FOREIGN KEY ("homeworld_id") REFERENCES public.planets("_id"); 227 | 228 | 229 | ALTER TABLE public.species_in_films ADD CONSTRAINT "species_in_films_fk0" FOREIGN KEY ("film_id") REFERENCES public.films("_id"); 230 | ALTER TABLE public.species_in_films ADD CONSTRAINT "species_in_films_fk1" FOREIGN KEY ("species_id") REFERENCES public.species("_id"); 231 | 232 | ALTER TABLE public.planets_in_films ADD CONSTRAINT "planets_in_films_fk0" FOREIGN KEY ("film_id") REFERENCES public.films("_id"); 233 | ALTER TABLE public.planets_in_films ADD CONSTRAINT "planets_in_films_fk1" FOREIGN KEY ("planet_id") REFERENCES public.planets("_id"); 234 | 235 | ALTER TABLE public.pilots ADD CONSTRAINT "pilots_fk0" FOREIGN KEY ("person_id") REFERENCES public.people("_id"); 236 | ALTER TABLE public.pilots ADD CONSTRAINT "pilots_fk1" FOREIGN KEY ("vessel_id") REFERENCES public.vessels("_id"); 237 | 238 | ALTER TABLE public.vessels_in_films ADD CONSTRAINT "vessels_in_films_fk0" FOREIGN KEY ("vessel_id") REFERENCES public.vessels("_id"); 239 | ALTER TABLE public.vessels_in_films ADD CONSTRAINT "vessels_in_films_fk1" FOREIGN KEY ("film_id") REFERENCES public.films("_id"); 240 | 241 | ALTER TABLE public.starship_specs ADD CONSTRAINT "starship_specs_fk0" FOREIGN KEY ("vessel_id") REFERENCES public.vessels("_id"); 242 | 243 | 244 | 245 | -- 246 | -- TOC entry 4120 (class 0 OID 4163856) 247 | -- Dependencies: 225 248 | -- Data for Name: films; Type: TABLE DATA; Schema: Owner: - 249 | -- 250 | 251 | INSERT INTO public.films 252 | VALUES 253 | (1, 'A New Hope', 4, 'It is a period of civil war. 254 | Rebel spaceships, striking 255 | from a hidden base, have won 256 | their first victory against 257 | the evil Galactic Empire. 258 | During the battle, Rebel 259 | spies managed to steal secret 260 | plans to the Empire''s 261 | ultimate weapon, the DEATH 262 | STAR, an armored space 263 | station with enough power 264 | to destroy an entire planet. 265 | Pursued by the Empire''s 266 | sinister agents, Princess 267 | Leia races home aboard her 268 | starship, custodian of the 269 | stolen plans that can save her 270 | people and restore 271 | freedom to the galaxy....', 'George Lucas', 'Gary Kurtz, Rick McCallum', '1977-05-25'); 272 | INSERT INTO public.films 273 | VALUES 274 | (5, 'Attack of the Clones', 2, 'There is unrest in the Galactic 275 | Senate. Several thousand solar 276 | systems have declared their 277 | intentions to leave the Republic. 278 | This separatist movement, 279 | under the leadership of the 280 | mysterious Count Dooku, has 281 | made it difficult for the limited 282 | number of Jedi Knights to maintain 283 | peace and order in the galaxy. 284 | Senator Amidala, the former 285 | Queen of Naboo, is returning 286 | to the Galactic Senate to vote 287 | on the critical issue of creating 288 | an ARMY OF THE REPUBLIC 289 | to assist the overwhelmed 290 | Jedi....', 'George Lucas', 'Rick McCallum', '2002-05-16'); 291 | INSERT INTO public.films 292 | VALUES 293 | (4, 'The Phantom Menace', 1, 'Turmoil has engulfed the 294 | Galactic Republic. The taxation 295 | of trade routes to outlying star 296 | systems is in dispute. 297 | Hoping to resolve the matter 298 | with a blockade of deadly 299 | battleships, the greedy Trade 300 | Federation has stopped all 301 | shipping to the small planet 302 | of Naboo. 303 | While the Congress of the 304 | Republic endlessly debates 305 | this alarming chain of events, 306 | the Supreme Chancellor has 307 | secretly dispatched two Jedi 308 | Knights, the guardians of 309 | peace and justice in the 310 | galaxy, to settle the conflict....', 'George Lucas', 'Rick McCallum', '1999-05-19'); 311 | INSERT INTO public.films 312 | VALUES 313 | (6, 'Revenge of the Sith', 3, 'War! The Republic is crumbling 314 | under attacks by the ruthless 315 | Sith Lord, Count Dooku. 316 | There are heroes on both sides. 317 | Evil is everywhere. 318 | In a stunning move, the 319 | fiendish droid leader, General 320 | Grievous, has swept into the 321 | Republic capital and kidnapped 322 | Chancellor Palpatine, leader of 323 | the Galactic Senate. 324 | As the Separatist Droid Army 325 | attempts to flee the besieged 326 | capital with their valuable 327 | hostage, two Jedi Knights lead a 328 | desperate mission to rescue the 329 | captive Chancellor....', 'George Lucas', 'Rick McCallum', '2005-05-19'); 330 | INSERT INTO public.films 331 | VALUES 332 | (3, 'Return of the Jedi', 6, 'Luke Skywalker has returned to 333 | his home planet of Tatooine in 334 | an attempt to rescue his 335 | friend Han Solo from the 336 | clutches of the vile gangster 337 | Jabba the Hutt. 338 | Little does Luke know that the 339 | GALACTIC EMPIRE has secretly 340 | begun construction on a new 341 | armored space station even 342 | more powerful than the first 343 | dreaded Death Star. 344 | When completed, this ultimate 345 | weapon will spell certain doom 346 | for the small band of rebels 347 | struggling to restore freedom 348 | to the galaxy...', 'Richard Marquand', 'Howard G. Kazanjian, George Lucas, Rick McCallum', '1983-05-25'); 349 | INSERT INTO public.films 350 | VALUES 351 | (2, 'The Empire Strikes Back', 5, 'It is a dark time for the 352 | Rebellion. Although the Death 353 | Star has been destroyed, 354 | Imperial troops have driven the 355 | Rebel forces from their hidden 356 | base and pursued them across 357 | the galaxy. 358 | Evading the dreaded Imperial 359 | Starfleet, a group of freedom 360 | fighters led by Luke Skywalker 361 | has established a new secret 362 | base on the remote ice world 363 | of Hoth. 364 | The evil lord Darth Vader, 365 | obsessed with finding young 366 | Skywalker, has dispatched 367 | thousands of remote probes into 368 | the far reaches of space....', 'Irvin Kershner', 'Gary Kurtz, Rick McCallum', '1980-05-17'); 369 | INSERT INTO public.films 370 | VALUES 371 | (7, 'The Force Awakens', 7, 'Luke Skywalker has vanished. 372 | In his absence, the sinister 373 | FIRST ORDER has risen from 374 | the ashes of the Empire 375 | and will not rest until 376 | Skywalker, the last Jedi, 377 | has been destroyed. 378 | 379 | With the support of the 380 | REPUBLIC, General Leia Organa 381 | leads a brave RESISTANCE. 382 | She is desperate to find her 383 | brother Luke and gain his 384 | help in restoring peace and 385 | justice to the galaxy. 386 | 387 | Leia has sent her most daring 388 | pilot on a secret mission 389 | to Jakku, where an old ally 390 | has discovered a clue to 391 | Luke''s whereabouts....', 'J. J. Abrams', 'Kathleen Kennedy, J. J. Abrams, Bryan Burk', '2015-12-11'); 392 | 393 | 394 | -- 395 | -- TOC entry 4124 (class 0 OID 4163875) 396 | -- Dependencies: 229 397 | -- Data for Name: planets; Type: TABLE DATA; Schema: Owner: - 398 | -- 399 | 400 | INSERT INTO public.planets 401 | VALUES 402 | (2, 'Alderaan', 24, 364, 12500, 'temperate', '1 standard', 'grasslands, mountains', '40', 2000000000); 403 | INSERT INTO public.planets 404 | VALUES 405 | (3, 'Yavin IV', 24, 4818, 10200, 'temperate, tropical', '1 standard', 'jungle, rainforests', '8', 1000); 406 | INSERT INTO public.planets 407 | VALUES 408 | (4, 'Hoth', 23, 549, 7200, 'frozen', '1.1 standard', 'tundra, ice caves, mountain ranges', '100', NULL); 409 | INSERT INTO public.planets 410 | VALUES 411 | (5, 'Dagobah', 23, 341, 8900, 'murky', 'N/A', 'swamp, jungles', '8', NULL); 412 | INSERT INTO public.planets 413 | VALUES 414 | (6, 'Bespin', 12, 5110, 118000, 'temperate', '1.5 (surface), 1 standard (Cloud City)', 'gas giant', '0', 6000000); 415 | INSERT INTO public.planets 416 | VALUES 417 | (7, 'Endor', 18, 402, 4900, 'temperate', '0.85 standard', 'forests, mountains, lakes', '8', 30000000); 418 | INSERT INTO public.planets 419 | VALUES 420 | (8, 'Naboo', 26, 312, 12120, 'temperate', '1 standard', 'grassy hills, swamps, forests, mountains', '12', 4500000000); 421 | INSERT INTO public.planets 422 | VALUES 423 | (9, 'Coruscant', 24, 368, 12240, 'temperate', '1 standard', 'cityscape, mountains', NULL, 1000000000000); 424 | INSERT INTO public.planets 425 | VALUES 426 | (10, 'Kamino', 27, 463, 19720, 'temperate', '1 standard', 'ocean', '100', 1000000000); 427 | INSERT INTO public.planets 428 | VALUES 429 | (11, 'Geonosis', 30, 256, 11370, 'temperate, arid', '0.9 standard', 'rock, desert, mountain, barren', '5', 100000000000); 430 | INSERT INTO public.planets 431 | VALUES 432 | (12, 'Utapau', 27, 351, 12900, 'temperate, arid, windy', '1 standard', 'scrublands, savanna, canyons, sinkholes', '0.9', 95000000); 433 | INSERT INTO public.planets 434 | VALUES 435 | (13, 'Mustafar', 36, 412, 4200, 'hot', '1 standard', 'volcanoes, lava rivers, mountains, caves', '0', 20000); 436 | INSERT INTO public.planets 437 | VALUES 438 | (14, 'Kashyyyk', 26, 381, 12765, 'tropical', '1 standard', 'jungle, forests, lakes, rivers', '60', 45000000); 439 | INSERT INTO public.planets 440 | VALUES 441 | (15, 'Polis Massa', 24, 590, 0, 'artificial temperate ', '0.56 standard', 'airless asteroid', '0', 1000000); 442 | INSERT INTO public.planets 443 | VALUES 444 | (16, 'Mygeeto', 12, 167, 10088, 'frigid', '1 standard', 'glaciers, mountains, ice canyons', NULL, 19000000); 445 | INSERT INTO public.planets 446 | VALUES 447 | (17, 'Felucia', 34, 231, 9100, 'hot, humid', '0.75 standard', 'fungus forests', NULL, 8500000); 448 | INSERT INTO public.planets 449 | VALUES 450 | (18, 'Cato Neimoidia', 25, 278, 0, 'temperate, moist', '1 standard', 'mountains, fields, forests, rock arches', NULL, 10000000); 451 | INSERT INTO public.planets 452 | VALUES 453 | (19, 'Saleucami', 26, 392, 14920, 'hot', NULL, 'caves, desert, mountains, volcanoes', NULL, 1400000000); 454 | INSERT INTO public.planets 455 | VALUES 456 | (20, 'Stewjon', NULL, NULL, 0, 'temperate', '1 standard', 'grass', NULL, NULL); 457 | INSERT INTO public.planets 458 | VALUES 459 | (21, 'Eriadu', 24, 360, 13490, 'polluted', '1 standard', 'cityscape', NULL, 22000000000); 460 | INSERT INTO public.planets 461 | VALUES 462 | (22, 'Corellia', 25, 329, 11000, 'temperate', '1 standard', 'plains, urban, hills, forests', '70', 3000000000); 463 | INSERT INTO public.planets 464 | VALUES 465 | (23, 'Rodia', 29, 305, 7549, 'hot', '1 standard', 'jungles, oceans, urban, swamps', '60', 1300000000); 466 | INSERT INTO public.planets 467 | VALUES 468 | (24, 'Nal Hutta', 87, 413, 12150, 'temperate', '1 standard', 'urban, oceans, swamps, bogs', NULL, 7000000000); 469 | INSERT INTO public.planets 470 | VALUES 471 | (25, 'Dantooine', 25, 378, 9830, 'temperate', '1 standard', 'oceans, savannas, mountains, grasslands', NULL, 1000); 472 | INSERT INTO public.planets 473 | VALUES 474 | (26, 'Bestine IV', 26, 680, 6400, 'temperate', NULL, 'rocky islands, oceans', '98', 62000000); 475 | INSERT INTO public.planets 476 | VALUES 477 | (27, 'Ord Mantell', 26, 334, 14050, 'temperate', '1 standard', 'plains, seas, mesas', '10', 4000000000); 478 | INSERT INTO public.planets 479 | VALUES 480 | (28, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); 481 | INSERT INTO public.planets 482 | VALUES 483 | (29, 'Trandosha', 25, 371, 0, 'arid', '0.62 standard', 'mountains, seas, grasslands, deserts', NULL, 42000000); 484 | INSERT INTO public.planets 485 | VALUES 486 | (30, 'Socorro', 20, 326, 0, 'arid', '1 standard', 'deserts, mountains', NULL, 300000000); 487 | INSERT INTO public.planets 488 | VALUES 489 | (31, 'Mon Cala', 21, 398, 11030, 'temperate', '1', 'oceans, reefs, islands', '100', 27000000000); 490 | INSERT INTO public.planets 491 | VALUES 492 | (32, 'Chandrila', 20, 368, 13500, 'temperate', '1', 'plains, forests', '40', 1200000000); 493 | INSERT INTO public.planets 494 | VALUES 495 | (33, 'Sullust', 20, 263, 12780, 'superheated', '1', 'mountains, volcanoes, rocky deserts', '5', 18500000000); 496 | INSERT INTO public.planets 497 | VALUES 498 | (34, 'Toydaria', 21, 184, 7900, 'temperate', '1', 'swamps, lakes', NULL, 11000000); 499 | INSERT INTO public.planets 500 | VALUES 501 | (35, 'Malastare', 26, 201, 18880, 'arid, temperate, tropical', '1.56', 'swamps, deserts, jungles, mountains', NULL, 2000000000); 502 | INSERT INTO public.planets 503 | VALUES 504 | (36, 'Dathomir', 24, 491, 10480, 'temperate', '0.9', 'forests, deserts, savannas', NULL, 5200); 505 | INSERT INTO public.planets 506 | VALUES 507 | (37, 'Ryloth', 30, 305, 10600, 'temperate, arid, subartic', '1', 'mountains, valleys, deserts, tundra', '5', 1500000000); 508 | INSERT INTO public.planets 509 | VALUES 510 | (38, 'Aleen Minor', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 511 | INSERT INTO public.planets 512 | VALUES 513 | (39, 'Vulpter', 22, 391, 14900, 'temperate, artic', '1', 'urban, barren', NULL, 421000000); 514 | INSERT INTO public.planets 515 | VALUES 516 | (40, 'Troiken', NULL, NULL, NULL, NULL, NULL, 'desert, tundra, rainforests, mountains', NULL, NULL); 517 | INSERT INTO public.planets 518 | VALUES 519 | (41, 'Tund', 48, 1770, 12190, NULL, NULL, 'barren, ash', NULL, 0); 520 | INSERT INTO public.planets 521 | VALUES 522 | (42, 'Haruun Kal', 25, 383, 10120, 'temperate', '0.98', 'toxic cloudsea, plateaus, volcanoes', NULL, 705300); 523 | INSERT INTO public.planets 524 | VALUES 525 | (43, 'Cerea', 27, 386, NULL, 'temperate', '1', 'verdant', '20', 450000000); 526 | INSERT INTO public.planets 527 | VALUES 528 | (44, 'Glee Anselm', 33, 206, 15600, 'tropical, temperate', '1', 'lakes, islands, swamps, seas', '80', 500000000); 529 | INSERT INTO public.planets 530 | VALUES 531 | (45, 'Iridonia', 29, 413, NULL, NULL, NULL, 'rocky canyons, acid pools', NULL, NULL); 532 | INSERT INTO public.planets 533 | VALUES 534 | (46, 'Tholoth', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 535 | INSERT INTO public.planets 536 | VALUES 537 | (47, 'Iktotch', 22, 481, NULL, 'arid, rocky, windy', '1', 'rocky', NULL, NULL); 538 | INSERT INTO public.planets 539 | VALUES 540 | (48, 'Quermia', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 541 | INSERT INTO public.planets 542 | VALUES 543 | (49, 'Dorin', 22, 409, 13400, 'temperate', '1', NULL, NULL, NULL); 544 | INSERT INTO public.planets 545 | VALUES 546 | (50, 'Champala', 27, 318, NULL, 'temperate', '1', 'oceans, rainforests, plateaus', NULL, 3500000000); 547 | INSERT INTO public.planets 548 | VALUES 549 | (51, 'Mirial', NULL, NULL, NULL, NULL, NULL, 'deserts', NULL, NULL); 550 | INSERT INTO public.planets 551 | VALUES 552 | (52, 'Serenno', NULL, NULL, NULL, NULL, NULL, 'rainforests, rivers, mountains', NULL, NULL); 553 | INSERT INTO public.planets 554 | VALUES 555 | (53, 'Concord Dawn', NULL, NULL, NULL, NULL, NULL, 'jungles, forests, deserts', NULL, NULL); 556 | INSERT INTO public.planets 557 | VALUES 558 | (54, 'Zolan', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 559 | INSERT INTO public.planets 560 | VALUES 561 | (55, 'Ojom', NULL, NULL, NULL, 'frigid', NULL, 'oceans, glaciers', '100', 500000000); 562 | INSERT INTO public.planets 563 | VALUES 564 | (56, 'Skako', 27, 384, NULL, 'temperate', '1', 'urban, vines', NULL, 500000000000); 565 | INSERT INTO public.planets 566 | VALUES 567 | (57, 'Muunilinst', 28, 412, 13800, 'temperate', '1', 'plains, forests, hills, mountains', '25', 5000000000); 568 | INSERT INTO public.planets 569 | VALUES 570 | (58, 'Shili', NULL, NULL, NULL, 'temperate', '1', 'cities, savannahs, seas, plains', NULL, NULL); 571 | INSERT INTO public.planets 572 | VALUES 573 | (59, 'Kalee', 23, 378, 13850, 'arid, temperate, tropical', '1', 'rainforests, cliffs, canyons, seas', NULL, 4000000000); 574 | INSERT INTO public.planets 575 | VALUES 576 | (60, 'Umbara', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 577 | INSERT INTO public.planets 578 | VALUES 579 | (1, 'Tatooine', 23, 304, 10465, 'arid', '1 standard', 'desert', '1', 200000); 580 | INSERT INTO public.planets 581 | VALUES 582 | (61, 'Jakku', NULL, NULL, NULL, NULL, NULL, 'deserts', NULL, NULL); 583 | 584 | -- 585 | -- TOC entry 4126 (class 0 OID 4163886) 586 | -- Dependencies: 231 587 | -- Data for Name: species; Type: TABLE DATA; Schema: Owner: - 588 | -- 589 | 590 | INSERT INTO public.species 591 | VALUES 592 | (5, 'Hutt', 'gastropod', '300', '1000', 'n/a', 'green, brown, tan', 'yellow, red', 'Huttese', 24); 593 | INSERT INTO public.species 594 | VALUES 595 | (6, 'Yoda''s species', 'mammal', '66', '900', 'brown, white', 'green, yellow', 'brown, green, yellow', 'Galactic basic', 28); 596 | INSERT INTO public.species 597 | VALUES 598 | (7, 'Trandoshan', 'reptile', '200', 'unknown', 'none', 'brown, green', 'yellow, orange', 'Dosh', 29); 599 | INSERT INTO public.species 600 | VALUES 601 | (8, 'Mon Calamari', 'amphibian', '160', 'unknown', 'none', 'red, blue, brown, magenta', 'yellow', 'Mon Calamarian', 31); 602 | INSERT INTO public.species 603 | VALUES 604 | (9, 'Ewok', 'mammal', '100', 'unknown', 'white, brown, black', 'brown', 'orange, brown', 'Ewokese', 7); 605 | INSERT INTO public.species 606 | VALUES 607 | (10, 'Sullustan', 'mammal', '180', 'unknown', 'none', 'pale', 'black', 'Sullutese', 33); 608 | INSERT INTO public.species 609 | VALUES 610 | (11, 'Neimodian', 'unknown', '180', 'unknown', 'none', 'grey, green', 'red, pink', 'Neimoidia', 18); 611 | INSERT INTO public.species 612 | VALUES 613 | (12, 'Gungan', 'amphibian', '190', 'unknown', 'none', 'brown, green', 'orange', 'Gungan basic', 8); 614 | INSERT INTO public.species 615 | VALUES 616 | (13, 'Toydarian', 'mammal', '120', '91', 'none', 'blue, green, grey', 'yellow', 'Toydarian', 34); 617 | INSERT INTO public.species 618 | VALUES 619 | (14, 'Dug', 'mammal', '100', 'unknown', 'none', 'brown, purple, grey, red', 'yellow, blue', 'Dugese', 35); 620 | INSERT INTO public.species 621 | VALUES 622 | (15, 'Twi''lek', 'mammals', '200', 'unknown', 'none', 'orange, yellow, blue, green, pink, purple, tan', 'blue, brown, orange, pink', 'Twi''leki', 37); 623 | INSERT INTO public.species 624 | VALUES 625 | (16, 'Aleena', 'reptile', '80', '79', 'none', 'blue, gray', 'unknown', 'Aleena', 38); 626 | INSERT INTO public.species 627 | VALUES 628 | (17, 'Vulptereen', 'unknown', '100', 'unknown', 'none', 'grey', 'yellow', 'vulpterish', 39); 629 | INSERT INTO public.species 630 | VALUES 631 | (18, 'Xexto', 'unknown', '125', 'unknown', 'none', 'grey, yellow, purple', 'black', 'Xextese', 40); 632 | INSERT INTO public.species 633 | VALUES 634 | (19, 'Toong', 'unknown', '200', 'unknown', 'none', 'grey, green, yellow', 'orange', 'Tundan', 41); 635 | INSERT INTO public.species 636 | VALUES 637 | (20, 'Cerean', 'mammal', '200', 'unknown', 'red, blond, black, white', 'pale pink', 'hazel', 'Cerean', 43); 638 | INSERT INTO public.species 639 | VALUES 640 | (21, 'Nautolan', 'amphibian', '180', '70', 'none', 'green, blue, brown, red', 'black', 'Nautila', 44); 641 | INSERT INTO public.species 642 | VALUES 643 | (22, 'Zabrak', 'mammal', '180', 'unknown', 'black', 'pale, brown, red, orange, yellow', 'brown, orange', 'Zabraki', 45); 644 | INSERT INTO public.species 645 | VALUES 646 | (23, 'Tholothian', 'mammal', 'unknown', 'unknown', 'unknown', 'dark', 'blue, indigo', 'unknown', 46); 647 | INSERT INTO public.species 648 | VALUES 649 | (24, 'Iktotchi', 'unknown', '180', 'unknown', 'none', 'pink', 'orange', 'Iktotchese', 47); 650 | INSERT INTO public.species 651 | VALUES 652 | (25, 'Quermian', 'mammal', '240', '86', 'none', 'white', 'yellow', 'Quermian', 48); 653 | INSERT INTO public.species 654 | VALUES 655 | (26, 'Kel Dor', 'unknown', '180', '70', 'none', 'peach, orange, red', 'black, silver', 'Kel Dor', 49); 656 | INSERT INTO public.species 657 | VALUES 658 | (27, 'Chagrian', 'amphibian', '190', 'unknown', 'none', 'blue', 'blue', 'Chagria', 50); 659 | INSERT INTO public.species 660 | VALUES 661 | (28, 'Geonosian', 'insectoid', '178', 'unknown', 'none', 'green, brown', 'green, hazel', 'Geonosian', 11); 662 | INSERT INTO public.species 663 | VALUES 664 | (29, 'Mirialan', 'mammal', '180', 'unknown', 'black, brown', 'yellow, green', 'blue, green, red, yellow, brown, orange', 'Mirialan', 51); 665 | INSERT INTO public.species 666 | VALUES 667 | (30, 'Clawdite', 'reptilian', '180', '70', 'none', 'green, yellow', 'yellow', 'Clawdite', 54); 668 | INSERT INTO public.species 669 | VALUES 670 | (31, 'Besalisk', 'amphibian', '178', '75', 'none', 'brown', 'yellow', 'besalisk', 55); 671 | INSERT INTO public.species 672 | VALUES 673 | (32, 'Kaminoan', 'amphibian', '220', '80', 'none', 'grey, blue', 'black', 'Kaminoan', 10); 674 | INSERT INTO public.species 675 | VALUES 676 | (33, 'Skakoan', 'mammal', 'unknown', 'unknown', 'none', 'grey, green', 'unknown', 'Skakoan', 56); 677 | INSERT INTO public.species 678 | VALUES 679 | (34, 'Muun', 'mammal', '190', '100', 'none', 'grey, white', 'black', 'Muun', 57); 680 | INSERT INTO public.species 681 | VALUES 682 | (35, 'Togruta', 'mammal', '180', '94', 'none', 'red, white, orange, yellow, green, blue', 'red, orange, yellow, green, blue, black', 'Togruti', 58); 683 | INSERT INTO public.species 684 | VALUES 685 | (36, 'Kaleesh', 'reptile', '170', '80', 'none', 'brown, orange, tan', 'yellow', 'Kaleesh', 59); 686 | INSERT INTO public.species 687 | VALUES 688 | (37, 'Pau''an', 'mammal', '190', '700', 'none', 'grey', 'black', 'Utapese', 12); 689 | INSERT INTO public.species 690 | VALUES 691 | (3, 'Wookiee', 'mammal', '210', '400', 'black, brown', 'gray', 'blue, green, yellow, brown, golden, red', 'Shyriiwook', 14); 692 | INSERT INTO public.species 693 | VALUES 694 | (2, 'Droid', 'artificial', 'n/a', 'indefinite', 'n/a', 'n/a', 'n/a', 'n/a', NULL); 695 | INSERT INTO public.species 696 | VALUES 697 | (1, 'Human', 'mammal', '180', '120', 'blonde, brown, black, red', 'caucasian, black, asian, hispanic', 'brown, blue, green, hazel, grey, amber', 'Galactic Basic', 9); 698 | INSERT INTO public.species 699 | VALUES 700 | (4, 'Rodian', 'sentient', '170', 'unknown', 'n/a', 'green, blue', 'black', 'Galactic Basic', 23); 701 | 702 | 703 | -- 704 | -- TOC entry 4118 (class 0 OID 4163845) 705 | -- Dependencies: 223 706 | -- Data for Name: people; Type: TABLE DATA; Schema: Owner: - 707 | -- 708 | 709 | INSERT INTO public.people 710 | VALUES 711 | (1, 'Luke Skywalker', '77', 'blond', 'fair', 'blue', '19BBY', 'male', 1, 1, 172); 712 | INSERT INTO public.people 713 | VALUES 714 | (2, 'C-3PO', '75', 'n/a', 'gold', 'yellow', '112BBY', 'n/a', 2, 1, 167); 715 | INSERT INTO public.people 716 | VALUES 717 | (3, 'R2-D2', '32', 'n/a', 'white, blue', 'red', '33BBY', 'n/a', 2, 8, 96); 718 | INSERT INTO public.people 719 | VALUES 720 | (4, 'Darth Vader', '136', 'none', 'white', 'yellow', '41.9BBY', 'male', 1, 1, 202); 721 | INSERT INTO public.people 722 | VALUES 723 | (5, 'Leia Organa', '49', 'brown', 'light', 'brown', '19BBY', 'female', 1, 2, 150); 724 | INSERT INTO public.people 725 | VALUES 726 | (6, 'Owen Lars', '120', 'brown, grey', 'light', 'blue', '52BBY', 'male', 1, 1, 178); 727 | INSERT INTO public.people 728 | VALUES 729 | (7, 'Beru Whitesun lars', '75', 'brown', 'light', 'blue', '47BBY', 'female', 1, 1, 165); 730 | INSERT INTO public.people 731 | VALUES 732 | (8, 'R5-D4', '32', 'n/a', 'white, red', 'red', NULL, 'n/a', 2, 1, 97); 733 | INSERT INTO public.people 734 | VALUES 735 | (9, 'Biggs Darklighter', '84', 'black', 'light', 'brown', '24BBY', 'male', 1, 1, 183); 736 | INSERT INTO public.people 737 | VALUES 738 | (10, 'Obi-Wan Kenobi', '77', 'auburn, white', 'fair', 'blue-gray', '57BBY', 'male', 1, 20, 182); 739 | INSERT INTO public.people 740 | VALUES 741 | (11, 'Anakin Skywalker', '84', 'blond', 'fair', 'blue', '41.9BBY', 'male', 1, 1, 188); 742 | INSERT INTO public.people 743 | VALUES 744 | (12, 'Wilhuff Tarkin', NULL, 'auburn, grey', 'fair', 'blue', '64BBY', 'male', 1, 21, 180); 745 | INSERT INTO public.people 746 | VALUES 747 | (13, 'Chewbacca', '112', 'brown', NULL, 'blue', '200BBY', 'male', 3, 14, 228); 748 | INSERT INTO public.people 749 | VALUES 750 | (14, 'Han Solo', '80', 'brown', 'fair', 'brown', '29BBY', 'male', 1, 22, 180); 751 | INSERT INTO public.people 752 | VALUES 753 | (15, 'Greedo', '74', 'n/a', 'green', 'black', '44BBY', 'male', 4, 23, 173); 754 | INSERT INTO public.people 755 | VALUES 756 | (16, 'Jabba Desilijic Tiure', '1,358', 'n/a', 'green-tan, brown', 'orange', '600BBY', 'hermaphrodite', 5, 24, 175); 757 | INSERT INTO public.people 758 | VALUES 759 | (18, 'Wedge Antilles', '77', 'brown', 'fair', 'hazel', '21BBY', 'male', 1, 22, 170); 760 | INSERT INTO public.people 761 | VALUES 762 | (19, 'Jek Tono Porkins', '110', 'brown', 'fair', 'blue', NULL, 'male', 1, 26, 180); 763 | INSERT INTO public.people 764 | VALUES 765 | (20, 'Yoda', '17', 'white', 'green', 'brown', '896BBY', 'male', 6, 28, 66); 766 | INSERT INTO public.people 767 | VALUES 768 | (21, 'Palpatine', '75', 'grey', 'pale', 'yellow', '82BBY', 'male', 1, 8, 170); 769 | INSERT INTO public.people 770 | VALUES 771 | (22, 'Boba Fett', '78.2', 'black', 'fair', 'brown', '31.5BBY', 'male', 1, 10, 183); 772 | INSERT INTO public.people 773 | VALUES 774 | (23, 'IG-88', '140', 'none', 'metal', 'red', '15BBY', 'none', 2, 28, 200); 775 | INSERT INTO public.people 776 | VALUES 777 | (24, 'Bossk', '113', 'none', 'green', 'red', '53BBY', 'male', 7, 29, 190); 778 | INSERT INTO public.people 779 | VALUES 780 | (25, 'Lando Calrissian', '79', 'black', 'dark', 'brown', '31BBY', 'male', 1, 30, 177); 781 | INSERT INTO public.people 782 | VALUES 783 | (26, 'Lobot', '79', 'none', 'light', 'blue', '37BBY', 'male', 1, 6, 175); 784 | INSERT INTO public.people 785 | VALUES 786 | (27, 'Ackbar', '83', 'none', 'brown mottle', 'orange', '41BBY', 'male', 8, 31, 180); 787 | INSERT INTO public.people 788 | VALUES 789 | (28, 'Mon Mothma', NULL, 'auburn', 'fair', 'blue', '48BBY', 'female', 1, 32, 150); 790 | INSERT INTO public.people 791 | VALUES 792 | (29, 'Arvel Crynyd', NULL, 'brown', 'fair', 'brown', NULL, 'male', 1, 28, NULL); 793 | INSERT INTO public.people 794 | VALUES 795 | (30, 'Wicket Systri Warrick', '20', 'brown', 'brown', 'brown', '8BBY', 'male', 9, 7, 88); 796 | INSERT INTO public.people 797 | VALUES 798 | (31, 'Nien Nunb', '68', 'none', 'grey', 'black', NULL, 'male', 10, 33, 160); 799 | INSERT INTO public.people 800 | VALUES 801 | (32, 'Qui-Gon Jinn', '89', 'brown', 'fair', 'blue', '92BBY', 'male', 1, 28, 193); 802 | INSERT INTO public.people 803 | VALUES 804 | (33, 'Nute Gunray', '90', 'none', 'mottled green', 'red', NULL, 'male', 11, 18, 191); 805 | INSERT INTO public.people 806 | VALUES 807 | (34, 'Finis Valorum', NULL, 'blond', 'fair', 'blue', '91BBY', 'male', 1, 9, 170); 808 | INSERT INTO public.people 809 | VALUES 810 | (36, 'Jar Jar Binks', '66', 'none', 'orange', 'orange', '52BBY', 'male', 12, 8, 196); 811 | INSERT INTO public.people 812 | VALUES 813 | (37, 'Roos Tarpals', '82', 'none', 'grey', 'orange', NULL, 'male', 12, 8, 224); 814 | INSERT INTO public.people 815 | VALUES 816 | (38, 'Rugor Nass', NULL, 'none', 'green', 'orange', NULL, 'male', 12, 8, 206); 817 | INSERT INTO public.people 818 | VALUES 819 | (39, 'Ric Olié', NULL, 'brown', 'fair', 'blue', NULL, 'male', NULL, 8, 183); 820 | INSERT INTO public.people 821 | VALUES 822 | (40, 'Watto', NULL, 'black', 'blue, grey', 'yellow', NULL, 'male', 13, 34, 137); 823 | INSERT INTO public.people 824 | VALUES 825 | (41, 'Sebulba', '40', 'none', 'grey, red', 'orange', NULL, 'male', 14, 35, 112); 826 | INSERT INTO public.people 827 | VALUES 828 | (42, 'Quarsh Panaka', NULL, 'black', 'dark', 'brown', '62BBY', 'male', NULL, 8, 183); 829 | INSERT INTO public.people 830 | VALUES 831 | (43, 'Shmi Skywalker', NULL, 'black', 'fair', 'brown', '72BBY', 'female', 1, 1, 163); 832 | INSERT INTO public.people 833 | VALUES 834 | (44, 'Darth Maul', '80', 'none', 'red', 'yellow', '54BBY', 'male', 22, 36, 175); 835 | INSERT INTO public.people 836 | VALUES 837 | (45, 'Bib Fortuna', NULL, 'none', 'pale', 'pink', NULL, 'male', 15, 37, 180); 838 | INSERT INTO public.people 839 | VALUES 840 | (46, 'Ayla Secura', '55', 'none', 'blue', 'hazel', '48BBY', 'female', 15, 37, 178); 841 | INSERT INTO public.people 842 | VALUES 843 | (48, 'Dud Bolt', '45', 'none', 'blue, grey', 'yellow', NULL, 'male', 17, 39, 94); 844 | INSERT INTO public.people 845 | VALUES 846 | (49, 'Gasgano', NULL, 'none', 'white, blue', 'black', NULL, 'male', 18, 40, 122); 847 | INSERT INTO public.people 848 | VALUES 849 | (50, 'Ben Quadinaros', '65', 'none', 'grey, green, yellow', 'orange', NULL, 'male', 19, 41, 163); 850 | INSERT INTO public.people 851 | VALUES 852 | (51, 'Mace Windu', '84', 'none', 'dark', 'brown', '72BBY', 'male', 1, 42, 188); 853 | INSERT INTO public.people 854 | VALUES 855 | (52, 'Ki-Adi-Mundi', '82', 'white', 'pale', 'yellow', '92BBY', 'male', 20, 43, 198); 856 | INSERT INTO public.people 857 | VALUES 858 | (53, 'Kit Fisto', '87', 'none', 'green', 'black', NULL, 'male', 21, 44, 196); 859 | INSERT INTO public.people 860 | VALUES 861 | (54, 'Eeth Koth', NULL, 'black', 'brown', 'brown', NULL, 'male', 22, 45, 171); 862 | INSERT INTO public.people 863 | VALUES 864 | (55, 'Adi Gallia', '50', 'none', 'dark', 'blue', NULL, 'female', 23, 9, 184); 865 | INSERT INTO public.people 866 | VALUES 867 | (56, 'Saesee Tiin', NULL, 'none', 'pale', 'orange', NULL, 'male', 24, 47, 188); 868 | INSERT INTO public.people 869 | VALUES 870 | (57, 'Yarael Poof', NULL, 'none', 'white', 'yellow', NULL, 'male', 25, 48, 264); 871 | INSERT INTO public.people 872 | VALUES 873 | (58, 'Plo Koon', '80', 'none', 'orange', 'black', '22BBY', 'male', 26, 49, 188); 874 | INSERT INTO public.people 875 | VALUES 876 | (59, 'Mas Amedda', NULL, 'none', 'blue', 'blue', NULL, 'male', 27, 50, 196); 877 | INSERT INTO public.people 878 | VALUES 879 | (60, 'Gregar Typho', '85', 'black', 'dark', 'brown', NULL, 'male', 1, 8, 185); 880 | INSERT INTO public.people 881 | VALUES 882 | (61, 'Cordé', NULL, 'brown', 'light', 'brown', NULL, 'female', 1, 8, 157); 883 | INSERT INTO public.people 884 | VALUES 885 | (62, 'Cliegg Lars', NULL, 'brown', 'fair', 'blue', '82BBY', 'male', 1, 1, 183); 886 | INSERT INTO public.people 887 | VALUES 888 | (63, 'Poggle the Lesser', '80', 'none', 'green', 'yellow', NULL, 'male', 28, 11, 183); 889 | INSERT INTO public.people 890 | VALUES 891 | (64, 'Luminara Unduli', '56.2', 'black', 'yellow', 'blue', '58BBY', 'female', 29, 51, 170); 892 | INSERT INTO public.people 893 | VALUES 894 | (65, 'Barriss Offee', '50', 'black', 'yellow', 'blue', '40BBY', 'female', 29, 51, 166); 895 | INSERT INTO public.people 896 | VALUES 897 | (66, 'Dormé', NULL, 'brown', 'light', 'brown', NULL, 'female', 1, 8, 165); 898 | INSERT INTO public.people 899 | VALUES 900 | (67, 'Dooku', '80', 'white', 'fair', 'brown', '102BBY', 'male', 1, 52, 193); 901 | INSERT INTO public.people 902 | VALUES 903 | (68, 'Bail Prestor Organa', NULL, 'black', 'tan', 'brown', '67BBY', 'male', 1, 2, 191); 904 | INSERT INTO public.people 905 | VALUES 906 | (69, 'Jango Fett', '79', 'black', 'tan', 'brown', '66BBY', 'male', 1, 53, 183); 907 | INSERT INTO public.people 908 | VALUES 909 | (70, 'Zam Wesell', '55', 'blonde', 'fair, green, yellow', 'yellow', NULL, 'female', 30, 54, 168); 910 | INSERT INTO public.people 911 | VALUES 912 | (71, 'Dexter Jettster', '102', 'none', 'brown', 'yellow', NULL, 'male', 31, 55, 198); 913 | INSERT INTO public.people 914 | VALUES 915 | (72, 'Lama Su', '88', 'none', 'grey', 'black', NULL, 'male', 32, 10, 229); 916 | INSERT INTO public.people 917 | VALUES 918 | (73, 'Taun We', NULL, 'none', 'grey', 'black', NULL, 'female', 32, 10, 213); 919 | INSERT INTO public.people 920 | VALUES 921 | (74, 'Jocasta Nu', NULL, 'white', 'fair', 'blue', NULL, 'female', 1, 9, 167); 922 | INSERT INTO public.people 923 | VALUES 924 | (47, 'Ratts Tyerell', '15', 'none', 'grey, blue', NULL, NULL, 'male', 16, 38, 79); 925 | INSERT INTO public.people 926 | VALUES 927 | (75, 'R4-P17', NULL, 'none', 'silver, red', 'red, blue', NULL, 'female', NULL, 28, 96); 928 | INSERT INTO public.people 929 | VALUES 930 | (76, 'Wat Tambor', '48', 'none', 'green, grey', NULL, NULL, 'male', 33, 56, 193); 931 | INSERT INTO public.people 932 | VALUES 933 | (77, 'San Hill', NULL, 'none', 'grey', 'gold', NULL, 'male', 34, 57, 191); 934 | INSERT INTO public.people 935 | VALUES 936 | (78, 'Shaak Ti', '57', 'none', 'red, blue, white', 'black', NULL, 'female', 35, 58, 178); 937 | INSERT INTO public.people 938 | VALUES 939 | (79, 'Grievous', '159', 'none', 'brown, white', 'green, yellow', NULL, 'male', 36, 59, 216); 940 | INSERT INTO public.people 941 | VALUES 942 | (80, 'Tarfful', '136', 'brown', 'brown', 'blue', NULL, 'male', 3, 14, 234); 943 | INSERT INTO public.people 944 | VALUES 945 | (81, 'Raymus Antilles', '79', 'brown', 'light', 'brown', NULL, 'male', 1, 2, 188); 946 | INSERT INTO public.people 947 | VALUES 948 | (82, 'Sly Moore', '48', 'none', 'pale', 'white', NULL, 'female', NULL, 60, 178); 949 | INSERT INTO public.people 950 | VALUES 951 | (83, 'Tion Medon', '80', 'none', 'grey', 'black', NULL, 'male', 37, 12, 206); 952 | INSERT INTO public.people 953 | VALUES 954 | (84, 'Finn', NULL, 'black', 'dark', 'dark', NULL, 'male', 1, 28, NULL); 955 | INSERT INTO public.people 956 | VALUES 957 | (85, 'Rey', NULL, 'brown', 'light', 'hazel', NULL, 'female', 1, 28, NULL); 958 | INSERT INTO public.people 959 | VALUES 960 | (86, 'Poe Dameron', NULL, 'brown', 'light', 'brown', NULL, 'male', 1, 28, NULL); 961 | INSERT INTO public.people 962 | VALUES 963 | (87, 'BB8', NULL, 'none', 'none', 'black', NULL, 'none', 2, 28, NULL); 964 | INSERT INTO public.people 965 | VALUES 966 | (88, 'Captain Phasma', NULL, NULL, NULL, NULL, NULL, 'female', NULL, 28, NULL); 967 | INSERT INTO public.people 968 | VALUES 969 | (35, 'Padmé Amidala', '45', 'brown', 'light', 'brown', '46BBY', 'female', 1, 8, 165); 970 | 971 | -- 972 | -- TOC entry 4128 (class 0 OID 4163897) 973 | -- Dependencies: 233 974 | -- Data for Name: vessels; Type: TABLE DATA; Schema: Owner: - 975 | -- 976 | 977 | INSERT INTO public.vessels 978 | VALUES 979 | (4, 'Sand Crawler', 'Corellia Mining Corporation', 'Digger Crawler', 'vehicle', 'wheeled', 150000, '36.8', '30', 46, 30, '50000', '2 months'); 980 | INSERT INTO public.vessels 981 | VALUES 982 | (6, 'T-16 skyhopper', 'Incom Corporation', 'T-16 skyhopper', 'vehicle', 'repulsorcraft', 14500, '10.4', '1200', 1, 1, '50', '0'); 983 | INSERT INTO public.vessels 984 | VALUES 985 | (7, 'X-34 landspeeder', 'SoroSuub Corporation', 'X-34 landspeeder', 'vehicle', 'repulsorcraft', 10550, '3.4', '250', 1, 1, '5', NULL); 986 | INSERT INTO public.vessels 987 | VALUES 988 | (8, 'TIE/LN starfighter', 'Sienar Fleet Systems', 'Twin Ion Engine/Ln Starfighter', 'vehicle', 'starfighter', NULL, '6.4', '1200', 1, 0, '65', '2 days'); 989 | INSERT INTO public.vessels 990 | VALUES 991 | (14, 'Snowspeeder', 'Incom corporation', 't-47 airspeeder', 'vehicle', 'airspeeder', NULL, '4.5', '650', 2, 0, '10', 'none'); 992 | INSERT INTO public.vessels 993 | VALUES 994 | (16, 'TIE bomber', 'Sienar Fleet Systems', 'TIE/sa bomber', 'vehicle', 'space/planetary bomber', NULL, '7.8', '850', 1, 0, 'none', '2 days'); 995 | INSERT INTO public.vessels 996 | VALUES 997 | (18, 'AT-AT', 'Kuat Drive Yards, Imperial Department of Military Research', 'All Terrain Armored Transport', 'vehicle', 'assault walker', NULL, '20', '60', 5, 40, '1000', NULL); 998 | INSERT INTO public.vessels 999 | VALUES 1000 | (19, 'AT-ST', 'Kuat Drive Yards, Imperial Department of Military Research', 'All Terrain Scout Transport', 'vehicle', 'walker', NULL, '2', '90', 2, 0, '200', 'none'); 1001 | INSERT INTO public.vessels 1002 | VALUES 1003 | (20, 'Storm IV Twin-Pod cloud car', 'Bespin Motors', 'Storm IV Twin-Pod', 'vehicle', 'repulsorcraft', 75000, '7', '1500', 2, 0, '10', '1 day'); 1004 | INSERT INTO public.vessels 1005 | VALUES 1006 | (24, 'Sail barge', 'Ubrikkian Industries Custom Vehicle Division', 'Modified Luxury Sail Barge', 'vehicle', 'sail barge', 285000, '30', '100', 26, 500, '2000000', 'Live food tanks'); 1007 | INSERT INTO public.vessels 1008 | VALUES 1009 | (25, 'Bantha-II cargo skiff', 'Ubrikkian Industries', 'Bantha-II', 'vehicle', 'repulsorcraft cargo skiff', 8000, '9.5', '250', 5, 16, '135000', '1 day'); 1010 | INSERT INTO public.vessels 1011 | VALUES 1012 | (26, 'TIE/IN interceptor', 'Sienar Fleet Systems', 'Twin Ion Engine Interceptor', 'vehicle', 'starfighter', NULL, '9.6', '1250', 1, 0, '75', '2 days'); 1013 | INSERT INTO public.vessels 1014 | VALUES 1015 | (30, 'Imperial Speeder Bike', 'Aratech Repulsor Company', '74-Z speeder bike', 'vehicle', 'speeder', 8000, '3', '360', 1, 1, '4', '1 day'); 1016 | INSERT INTO public.vessels 1017 | VALUES 1018 | (33, 'Vulture Droid', 'Haor Chall Engineering, Baktoid Armor Workshop', 'Vulture-class droid starfighter', 'vehicle', 'starfighter', NULL, '3.5', '1200', 0, 0, '0', 'none'); 1019 | INSERT INTO public.vessels 1020 | VALUES 1021 | (34, 'Multi-Troop Transport', 'Baktoid Armor Workshop', 'Multi-Troop Transport', 'vehicle', 'repulsorcraft', 138000, '31', '35', 4, 112, '12000', NULL); 1022 | INSERT INTO public.vessels 1023 | VALUES 1024 | (35, 'Armored Assault Tank', 'Baktoid Armor Workshop', 'Armoured Assault Tank', 'vehicle', 'repulsorcraft', NULL, '9.75', '55', 4, 6, NULL, NULL); 1025 | INSERT INTO public.vessels 1026 | VALUES 1027 | (36, 'Single Trooper Aerial Platform', 'Baktoid Armor Workshop', 'Single Trooper Aerial Platform', 'vehicle', 'repulsorcraft', 2500, '2', '400', 1, 0, 'none', 'none'); 1028 | INSERT INTO public.vessels 1029 | VALUES 1030 | (37, 'C-9979 landing craft', 'Haor Chall Engineering', 'C-9979 landing craft', 'vehicle', 'landing craft', 200000, '210', '587', 140, 284, '1800000', '1 day'); 1031 | INSERT INTO public.vessels 1032 | VALUES 1033 | (38, 'Tribubble bongo', 'Otoh Gunga Bongameken Cooperative', 'Tribubble bongo', 'vehicle', 'submarine', NULL, '15', '85', 1, 2, '1600', NULL); 1034 | INSERT INTO public.vessels 1035 | VALUES 1036 | (42, 'Sith speeder', 'Razalon', 'FC-20 speeder bike', 'vehicle', 'speeder', 4000, '1.5', '180', 1, 0, '2', NULL); 1037 | INSERT INTO public.vessels 1038 | VALUES 1039 | (44, 'Zephyr-G swoop bike', 'Mobquet Swoops and Speeders', 'Zephyr-G swoop bike', 'vehicle', 'repulsorcraft', 5750, '3.68', '350', 1, 1, '200', 'none'); 1040 | INSERT INTO public.vessels 1041 | VALUES 1042 | (45, 'Koro-2 Exodrive airspeeder', 'Desler Gizh Outworld Mobility Corporation', 'Koro-2 Exodrive airspeeder', 'vehicle', 'airspeeder', NULL, '6.6', '800', 1, 1, '80', NULL); 1043 | INSERT INTO public.vessels 1044 | VALUES 1045 | (46, 'XJ-6 airspeeder', 'Narglatch AirTech prefabricated kit', 'XJ-6 airspeeder', 'vehicle', 'airspeeder', NULL, '6.23', '720', 1, 1, NULL, NULL); 1046 | INSERT INTO public.vessels 1047 | VALUES 1048 | (50, 'LAAT/i', 'Rothana Heavy Engineering', 'Low Altitude Assault Transport/infrantry', 'vehicle', 'gunship', NULL, '17.4', '620', 6, 30, '170', NULL); 1049 | INSERT INTO public.vessels 1050 | VALUES 1051 | (51, 'LAAT/c', 'Rothana Heavy Engineering', 'Low Altitude Assault Transport/carrier', 'vehicle', 'gunship', NULL, '28.82', '620', 1, 0, '40000', NULL); 1052 | INSERT INTO public.vessels 1053 | VALUES 1054 | (60, 'Tsmeu-6 personal wheel bike', 'Z-Gomot Ternbuell Guppat Corporation', 'Tsmeu-6 personal wheel bike', 'vehicle', 'wheeled walker', 15000, '3.5', '330', 1, 1, '10', 'none'); 1055 | INSERT INTO public.vessels 1056 | VALUES 1057 | (62, 'Emergency Firespeeder', NULL, 'Fire suppression speeder', 'vehicle', 'fire suppression ship', NULL, NULL, NULL, 2, NULL, NULL, NULL); 1058 | INSERT INTO public.vessels 1059 | VALUES 1060 | (67, 'Droid tri-fighter', 'Colla Designs, Phlac-Arphocc Automata Industries', 'tri-fighter', 'vehicle', 'droid starfighter', 20000, '5.4', '1180', 1, 0, '0', 'none'); 1061 | INSERT INTO public.vessels 1062 | VALUES 1063 | (69, 'Oevvaor jet catamaran', 'Appazanna Engineering Works', 'Oevvaor jet catamaran', 'vehicle', 'airspeeder', 12125, '15.1', '420', 2, 2, '50', '3 days'); 1064 | INSERT INTO public.vessels 1065 | VALUES 1066 | (70, 'Raddaugh Gnasp fluttercraft', 'Appazanna Engineering Works', 'Raddaugh Gnasp fluttercraft', 'vehicle', 'air speeder', 14750, '7', '310', 2, 0, '20', 'none'); 1067 | INSERT INTO public.vessels 1068 | VALUES 1069 | (71, 'Clone turbo tank', 'Kuat Drive Yards', 'HAVw A6 Juggernaut', 'vehicle', 'wheeled walker', 350000, '49.4', '160', 20, 300, '30000', '20 days'); 1070 | INSERT INTO public.vessels 1071 | VALUES 1072 | (72, 'Corporate Alliance tank droid', 'Techno Union', 'NR-N99 Persuader-class droid enforcer', 'vehicle', 'droid tank', 49000, '10.96', '100', 0, 4, 'none', 'none'); 1073 | INSERT INTO public.vessels 1074 | VALUES 1075 | (73, 'Droid gunship', 'Baktoid Fleet Ordnance, Haor Chall Engineering', 'HMP droid gunship', 'vehicle', 'airspeeder', 60000, '12.3', '820', 0, 0, '0', 'none'); 1076 | INSERT INTO public.vessels 1077 | VALUES 1078 | (76, 'AT-RT', 'Kuat Drive Yards', 'All Terrain Recon Transport', 'vehicle', 'walker', 40000, '3.2', '90', 1, 0, '20', '1 day'); 1079 | INSERT INTO public.vessels 1080 | VALUES 1081 | (53, 'AT-TE', 'Rothana Heavy Engineering, Kuat Drive Yards', 'All Terrain Tactical Enforcer', 'vehicle', 'walker', NULL, '13.2', '60', 6, 36, '10000', '21 days'); 1082 | INSERT INTO public.vessels 1083 | VALUES 1084 | (54, 'SPHA', 'Rothana Heavy Engineering', 'Self-Propelled Heavy Artillery', 'vehicle', 'walker', NULL, '140', '35', 25, 30, '500', '7 days'); 1085 | INSERT INTO public.vessels 1086 | VALUES 1087 | (55, 'Flitknot speeder', 'Huppla Pasa Tisc Shipwrights Collective', 'Flitknot speeder', 'vehicle', 'speeder', 8000, '2', '634', 1, 0, NULL, NULL); 1088 | INSERT INTO public.vessels 1089 | VALUES 1090 | (56, 'Neimoidian shuttle', 'Haor Chall Engineering', 'Sheathipede-class transport shuttle', 'vehicle', 'transport', NULL, '20', '880', 2, 6, '1000', '7 days'); 1091 | INSERT INTO public.vessels 1092 | VALUES 1093 | (57, 'Geonosian starfighter', 'Huppla Pasa Tisc Shipwrights Collective', 'Nantex-class territorial defense', 'vehicle', 'starfighter', NULL, '9.8', '20000', 1, 0, NULL, NULL); 1094 | INSERT INTO public.vessels 1095 | VALUES 1096 | (15, 'Executor', 'Kuat Drive Yards, Fondor Shipyards', 'Executor-class star dreadnought', 'starship', 'Star dreadnought', 1143350000, '19000', 'n/a', 279144, 38000, '250000000', '6 years'); 1097 | INSERT INTO public.vessels 1098 | VALUES 1099 | (5, 'Sentinel-class landing craft', 'Sienar Fleet Systems, Cyngus Spaceworks', 'Sentinel-class landing craft', 'starship', 'landing craft', 240000, '38', '1000', 5, 75, '180000', '1 month'); 1100 | INSERT INTO public.vessels 1101 | VALUES 1102 | (9, 'Death Star', 'Imperial Department of Military Research, Sienar Fleet Systems', 'DS-1 Orbital Battle Station', 'starship', 'Deep Space Mobile Battlestation', 1000000000000, '120000', 'n/a', 342953, 843342, '1000000000000', '3 years'); 1103 | INSERT INTO public.vessels 1104 | VALUES 1105 | (10, 'Millennium Falcon', 'Corellian Engineering Corporation', 'YT-1300 light freighter', 'starship', 'Light freighter', 100000, '34.37', '1050', 4, 6, '100000', '2 months'); 1106 | INSERT INTO public.vessels 1107 | VALUES 1108 | (11, 'Y-wing', 'Koensayr Manufacturing', 'BTL Y-wing', 'starship', 'assault starfighter', 134999, '14', '1000km', 2, 0, '110', '1 week'); 1109 | INSERT INTO public.vessels 1110 | VALUES 1111 | (12, 'X-wing', 'Incom Corporation', 'T-65 X-wing', 'starship', 'Starfighter', 149999, '12.5', '1050', 1, 0, '110', '1 week'); 1112 | INSERT INTO public.vessels 1113 | VALUES 1114 | (13, 'TIE Advanced x1', 'Sienar Fleet Systems', 'Twin Ion Engine Advanced x1', 'starship', 'Starfighter', NULL, '9.2', '1200', 1, 0, '150', '5 days'); 1115 | INSERT INTO public.vessels 1116 | VALUES 1117 | (21, 'Slave 1', 'Kuat Systems Engineering', 'Firespray-31-class patrol and attack', 'starship', 'Patrol craft', NULL, '21.5', '1000', 1, 6, '70000', '1 month'); 1118 | INSERT INTO public.vessels 1119 | VALUES 1120 | (22, 'Imperial shuttle', 'Sienar Fleet Systems', 'Lambda-class T-4a shuttle', 'starship', 'Armed government transport', 240000, '20', '850', 6, 20, '80000', '2 months'); 1121 | INSERT INTO public.vessels 1122 | VALUES 1123 | (23, 'EF76 Nebulon-B escort frigate', 'Kuat Drive Yards', 'EF76 Nebulon-B escort frigate', 'starship', 'Escort ship', 8500000, '300', '800', 854, 75, '6000000', '2 years'); 1124 | INSERT INTO public.vessels 1125 | VALUES 1126 | (27, 'Calamari Cruiser', 'Mon Calamari shipyards', 'MC80 Liberty type Star Cruiser', 'starship', 'Star Cruiser', 104000000, '1200', 'n/a', 5400, 1200, NULL, '2 years'); 1127 | INSERT INTO public.vessels 1128 | VALUES 1129 | (28, 'A-wing', 'Alliance Underground Engineering, Incom Corporation', 'RZ-1 A-wing Interceptor', 'starship', 'Starfighter', 175000, '9.6', '1300', 1, 0, '40', '1 week'); 1130 | INSERT INTO public.vessels 1131 | VALUES 1132 | (29, 'B-wing', 'Slayn & Korpil', 'A/SF-01 B-wing starfighter', 'starship', 'Assault Starfighter', 220000, '16.9', '950', 1, 0, '45', '1 week'); 1133 | INSERT INTO public.vessels 1134 | VALUES 1135 | (31, 'Republic Cruiser', 'Corellian Engineering Corporation', 'Consular-class cruiser', 'starship', 'Space cruiser', NULL, '115', '900', 9, 16, NULL, NULL); 1136 | INSERT INTO public.vessels 1137 | VALUES 1138 | (39, 'Naboo fighter', 'Theed Palace Space Vessel Engineering Corps', 'N-1 starfighter', 'starship', 'Starfighter', 200000, '11', '1100', 1, 0, '65', '7 days'); 1139 | INSERT INTO public.vessels 1140 | VALUES 1141 | (40, 'Naboo Royal Starship', 'Theed Palace Space Vessel Engineering Corps, Nubia Star Drives', 'J-type 327 Nubian royal starship', 'starship', 'yacht', NULL, '76', '920', 8, NULL, NULL, NULL); 1142 | INSERT INTO public.vessels 1143 | VALUES 1144 | (41, 'Scimitar', 'Republic Sienar Systems', 'Star Courier', 'starship', 'Space Transport', 55000000, '26.5', '1180', 1, 6, '2500000', '30 days'); 1145 | INSERT INTO public.vessels 1146 | VALUES 1147 | (43, 'J-type diplomatic barge', 'Theed Palace Space Vessel Engineering Corps, Nubia Star Drives', 'J-type diplomatic barge', 'starship', 'Diplomatic barge', 2000000, '39', '2000', 5, 10, NULL, '1 year'); 1148 | INSERT INTO public.vessels 1149 | VALUES 1150 | (47, 'AA-9 Coruscant freighter', 'Botajef Shipyards', 'Botajef AA-9 Freighter-Liner', 'starship', 'freighter', NULL, '390', NULL, NULL, 30000, NULL, NULL); 1151 | INSERT INTO public.vessels 1152 | VALUES 1153 | (48, 'Jedi starfighter', 'Kuat Systems Engineering', 'Delta-7 Aethersprite-class interceptor', 'starship', 'Starfighter', 180000, '8', '1150', 1, 0, '60', '7 days'); 1154 | INSERT INTO public.vessels 1155 | VALUES 1156 | (49, 'H-type Nubian yacht', 'Theed Palace Space Vessel Engineering Corps', 'H-type Nubian yacht', 'starship', 'yacht', NULL, '47.9', '8000', 4, NULL, NULL, NULL); 1157 | INSERT INTO public.vessels 1158 | VALUES 1159 | (3, 'Star Destroyer', 'Kuat Drive Yards', 'Imperial I-class Star Destroyer', 'starship', 'Star Destroyer', 150000000, '1,600', '975', 47060, 0, '36000000', '2 years'); 1160 | INSERT INTO public.vessels 1161 | VALUES 1162 | (59, 'Trade Federation cruiser', 'Rendili StarDrive, Free Dac Volunteers Engineering corps.', 'Providence-class carrier/destroyer', 'starship', 'capital ship', 125000000, '1088', '1050', 600, 48247, '50000000', '4 years'); 1163 | INSERT INTO public.vessels 1164 | VALUES 1165 | (61, 'Theta-class T-2c shuttle', 'Cygnus Spaceworks', 'Theta-class T-2c shuttle', 'starship', 'transport', 1000000, '18.5', '2000', 5, 16, '50000', '56 days'); 1166 | INSERT INTO public.vessels 1167 | VALUES 1168 | (77, 'T-70 X-wing fighter', 'Incom', 'T-70 X-wing fighter', 'starship', 'fighter', NULL, NULL, NULL, 1, NULL, NULL, NULL); 1169 | INSERT INTO public.vessels 1170 | VALUES 1171 | (17, 'Rebel transport', 'Gallofree Yards, Inc.', 'GR-75 medium transport', 'starship', 'Medium transport', NULL, '90', '650', 6, 90, '19000000', '6 months'); 1172 | INSERT INTO public.vessels 1173 | VALUES 1174 | (32, 'Droid control ship', 'Hoersch-Kessel Drive, Inc.', 'Lucrehulk-class Droid Control Ship', 'starship', 'Droid control ship', NULL, '3170', 'n/a', 175, 139000, '4000000000', '500 days'); 1175 | INSERT INTO public.vessels 1176 | VALUES 1177 | (52, 'Republic Assault ship', 'Rothana Heavy Engineering', 'Acclamator I-class assault ship', 'starship', 'assault ship', NULL, '752', NULL, 700, 16000, '11250000', '2 years'); 1178 | INSERT INTO public.vessels 1179 | VALUES 1180 | (58, 'Solar Sailer', 'Huppla Pasa Tisc Shipwrights Collective', 'Punworcca 116-class interstellar sloop', 'starship', 'yacht', 35700, '15.2', '1600', 3, 11, '240', '7 days'); 1181 | INSERT INTO public.vessels 1182 | VALUES 1183 | (63, 'Republic attack cruiser', 'Kuat Drive Yards, Allanteen Six shipyards', 'Senator-class Star Destroyer', 'starship', 'star destroyer', 59000000, '1137', '975', 7400, 2000, '20000000', '2 years'); 1184 | INSERT INTO public.vessels 1185 | VALUES 1186 | (64, 'Naboo star skiff', 'Theed Palace Space Vessel Engineering Corps/Nubia Star Drives, Incorporated', 'J-type star skiff', 'starship', 'yacht', NULL, '29.2', '1050', 3, 3, NULL, NULL); 1187 | INSERT INTO public.vessels 1188 | VALUES 1189 | (65, 'Jedi Interceptor', 'Kuat Systems Engineering', 'Eta-2 Actis-class light interceptor', 'starship', 'starfighter', 320000, '5.47', '1500', 1, 0, '60', '2 days'); 1190 | INSERT INTO public.vessels 1191 | VALUES 1192 | (66, 'arc-170', 'Incom Corporation, Subpro Corporation', 'Aggressive Reconnaissance-170 starfighte', 'starship', 'starfighter', 155000, '14.5', '1000', 3, 0, '110', '5 days'); 1193 | INSERT INTO public.vessels 1194 | VALUES 1195 | (74, 'Belbullab-22 starfighter', 'Feethan Ottraw Scalable Assemblies', 'Belbullab-22 starfighter', 'starship', 'starfighter', 168000, '6.71', '1100', 1, 0, '140', '7 days'); 1196 | INSERT INTO public.vessels 1197 | VALUES 1198 | (75, 'V-wing', 'Kuat Systems Engineering', 'Alpha-3 Nimbus-class V-wing starfighter', 'starship', 'starfighter', 102500, '7.9', '1050', 1, 0, '60', '15 hours'); 1199 | INSERT INTO public.vessels 1200 | VALUES 1201 | (2, 'CR90 corvette', 'Corellian Engineering Corporation', 'CR90 corvette', 'starship', 'corvette', 3500000, '150', '950', 165, 600, '3000000', '1 year'); 1202 | INSERT INTO public.vessels 1203 | VALUES 1204 | (68, 'Banking clan frigate', 'Hoersch-Kessel Drive, Inc, Gwori Revolutionary Industries', 'Munificent-class star frigate', 'starship', 'cruiser', 57000000, '825', NULL, 200, NULL, '40000000', '2 years'); 1205 | 1206 | 1207 | 1208 | -- 1209 | -- TOC entry 4138 (class 0 OID 4163940) 1210 | -- Dependencies: 243 1211 | -- Data for Name: starship_specs; Type: TABLE DATA; Schema: Owner: - 1212 | -- 1213 | 1214 | INSERT INTO public.starship_specs 1215 | VALUES 1216 | (1, '2.0', '40', 15); 1217 | INSERT INTO public.starship_specs 1218 | VALUES 1219 | (2, '1.0', '70', 5); 1220 | INSERT INTO public.starship_specs 1221 | VALUES 1222 | (3, '4.0', '10', 9); 1223 | INSERT INTO public.starship_specs 1224 | VALUES 1225 | (4, '0.5', '75', 10); 1226 | INSERT INTO public.starship_specs 1227 | VALUES 1228 | (5, '1.0', '80', 11); 1229 | INSERT INTO public.starship_specs 1230 | VALUES 1231 | (6, '1.0', '100', 12); 1232 | INSERT INTO public.starship_specs 1233 | VALUES 1234 | (7, '1.0', '105', 13); 1235 | INSERT INTO public.starship_specs 1236 | VALUES 1237 | (8, '3.0', '70', 21); 1238 | INSERT INTO public.starship_specs 1239 | VALUES 1240 | (9, '1.0', '50', 22); 1241 | INSERT INTO public.starship_specs 1242 | VALUES 1243 | (10, '2.0', '40', 23); 1244 | INSERT INTO public.starship_specs 1245 | VALUES 1246 | (11, '1.0', '60', 27); 1247 | INSERT INTO public.starship_specs 1248 | VALUES 1249 | (12, '1.0', '120', 28); 1250 | INSERT INTO public.starship_specs 1251 | VALUES 1252 | (13, '2.0', '91', 29); 1253 | INSERT INTO public.starship_specs 1254 | VALUES 1255 | (14, '2.0', NULL, 31); 1256 | INSERT INTO public.starship_specs 1257 | VALUES 1258 | (15, '1.0', NULL, 39); 1259 | INSERT INTO public.starship_specs 1260 | VALUES 1261 | (16, '1.8', NULL, 40); 1262 | INSERT INTO public.starship_specs 1263 | VALUES 1264 | (17, '1.5', NULL, 41); 1265 | INSERT INTO public.starship_specs 1266 | VALUES 1267 | (18, '0.7', NULL, 43); 1268 | INSERT INTO public.starship_specs 1269 | VALUES 1270 | (19, NULL, NULL, 47); 1271 | INSERT INTO public.starship_specs 1272 | VALUES 1273 | (20, '1.0', NULL, 48); 1274 | INSERT INTO public.starship_specs 1275 | VALUES 1276 | (21, '0.9', NULL, 49); 1277 | INSERT INTO public.starship_specs 1278 | VALUES 1279 | (22, '2.0', '60', 3); 1280 | INSERT INTO public.starship_specs 1281 | VALUES 1282 | (23, '1.5', NULL, 59); 1283 | INSERT INTO public.starship_specs 1284 | VALUES 1285 | (24, '1.0', NULL, 61); 1286 | INSERT INTO public.starship_specs 1287 | VALUES 1288 | (25, NULL, NULL, 77); 1289 | INSERT INTO public.starship_specs 1290 | VALUES 1291 | (26, '4.0', '20', 17); 1292 | INSERT INTO public.starship_specs 1293 | VALUES 1294 | (27, '2.0', NULL, 32); 1295 | INSERT INTO public.starship_specs 1296 | VALUES 1297 | (28, '0.6', NULL, 52); 1298 | INSERT INTO public.starship_specs 1299 | VALUES 1300 | (29, '1.5', NULL, 58); 1301 | INSERT INTO public.starship_specs 1302 | VALUES 1303 | (30, '1.0', NULL, 63); 1304 | INSERT INTO public.starship_specs 1305 | VALUES 1306 | (31, '0.5', NULL, 64); 1307 | INSERT INTO public.starship_specs 1308 | VALUES 1309 | (32, '1.0', NULL, 65); 1310 | INSERT INTO public.starship_specs 1311 | VALUES 1312 | (33, '1.0', '100', 66); 1313 | INSERT INTO public.starship_specs 1314 | VALUES 1315 | (34, '6', NULL, 74); 1316 | INSERT INTO public.starship_specs 1317 | VALUES 1318 | (35, '1.0', NULL, 75); 1319 | INSERT INTO public.starship_specs 1320 | VALUES 1321 | (36, '2.0', '60', 2); 1322 | INSERT INTO public.starship_specs 1323 | VALUES 1324 | (37, '1.0', NULL, 68); 1325 | 1326 | 1327 | -- 1328 | -- TOC entry 4122 (class 0 OID 4163867) 1329 | -- Dependencies: 227 1330 | -- Data for Name: people_in_films; Type: TABLE DATA; Schema: Owner: - 1331 | -- 1332 | 1333 | INSERT INTO public.people_in_films 1334 | VALUES 1335 | (1, 1, 1); 1336 | INSERT INTO public.people_in_films 1337 | VALUES 1338 | (2, 2, 1); 1339 | INSERT INTO public.people_in_films 1340 | VALUES 1341 | (3, 3, 1); 1342 | INSERT INTO public.people_in_films 1343 | VALUES 1344 | (4, 4, 1); 1345 | INSERT INTO public.people_in_films 1346 | VALUES 1347 | (5, 5, 1); 1348 | INSERT INTO public.people_in_films 1349 | VALUES 1350 | (6, 6, 1); 1351 | INSERT INTO public.people_in_films 1352 | VALUES 1353 | (7, 7, 1); 1354 | INSERT INTO public.people_in_films 1355 | VALUES 1356 | (8, 8, 1); 1357 | INSERT INTO public.people_in_films 1358 | VALUES 1359 | (9, 9, 1); 1360 | INSERT INTO public.people_in_films 1361 | VALUES 1362 | (10, 10, 1); 1363 | INSERT INTO public.people_in_films 1364 | VALUES 1365 | (11, 12, 1); 1366 | INSERT INTO public.people_in_films 1367 | VALUES 1368 | (12, 13, 1); 1369 | INSERT INTO public.people_in_films 1370 | VALUES 1371 | (13, 14, 1); 1372 | INSERT INTO public.people_in_films 1373 | VALUES 1374 | (14, 15, 1); 1375 | INSERT INTO public.people_in_films 1376 | VALUES 1377 | (15, 16, 1); 1378 | INSERT INTO public.people_in_films 1379 | VALUES 1380 | (16, 18, 1); 1381 | INSERT INTO public.people_in_films 1382 | VALUES 1383 | (17, 19, 1); 1384 | INSERT INTO public.people_in_films 1385 | VALUES 1386 | (18, 81, 1); 1387 | INSERT INTO public.people_in_films 1388 | VALUES 1389 | (19, 2, 5); 1390 | INSERT INTO public.people_in_films 1391 | VALUES 1392 | (20, 3, 5); 1393 | INSERT INTO public.people_in_films 1394 | VALUES 1395 | (21, 6, 5); 1396 | INSERT INTO public.people_in_films 1397 | VALUES 1398 | (22, 7, 5); 1399 | INSERT INTO public.people_in_films 1400 | VALUES 1401 | (23, 10, 5); 1402 | INSERT INTO public.people_in_films 1403 | VALUES 1404 | (24, 11, 5); 1405 | INSERT INTO public.people_in_films 1406 | VALUES 1407 | (25, 20, 5); 1408 | INSERT INTO public.people_in_films 1409 | VALUES 1410 | (26, 21, 5); 1411 | INSERT INTO public.people_in_films 1412 | VALUES 1413 | (27, 22, 5); 1414 | INSERT INTO public.people_in_films 1415 | VALUES 1416 | (28, 33, 5); 1417 | INSERT INTO public.people_in_films 1418 | VALUES 1419 | (29, 36, 5); 1420 | INSERT INTO public.people_in_films 1421 | VALUES 1422 | (30, 40, 5); 1423 | INSERT INTO public.people_in_films 1424 | VALUES 1425 | (31, 43, 5); 1426 | INSERT INTO public.people_in_films 1427 | VALUES 1428 | (32, 46, 5); 1429 | INSERT INTO public.people_in_films 1430 | VALUES 1431 | (33, 51, 5); 1432 | INSERT INTO public.people_in_films 1433 | VALUES 1434 | (34, 52, 5); 1435 | INSERT INTO public.people_in_films 1436 | VALUES 1437 | (35, 53, 5); 1438 | INSERT INTO public.people_in_films 1439 | VALUES 1440 | (36, 58, 5); 1441 | INSERT INTO public.people_in_films 1442 | VALUES 1443 | (37, 59, 5); 1444 | INSERT INTO public.people_in_films 1445 | VALUES 1446 | (38, 60, 5); 1447 | INSERT INTO public.people_in_films 1448 | VALUES 1449 | (39, 61, 5); 1450 | INSERT INTO public.people_in_films 1451 | VALUES 1452 | (40, 62, 5); 1453 | INSERT INTO public.people_in_films 1454 | VALUES 1455 | (41, 63, 5); 1456 | INSERT INTO public.people_in_films 1457 | VALUES 1458 | (42, 64, 5); 1459 | INSERT INTO public.people_in_films 1460 | VALUES 1461 | (43, 65, 5); 1462 | INSERT INTO public.people_in_films 1463 | VALUES 1464 | (44, 66, 5); 1465 | INSERT INTO public.people_in_films 1466 | VALUES 1467 | (45, 67, 5); 1468 | INSERT INTO public.people_in_films 1469 | VALUES 1470 | (46, 68, 5); 1471 | INSERT INTO public.people_in_films 1472 | VALUES 1473 | (47, 69, 5); 1474 | INSERT INTO public.people_in_films 1475 | VALUES 1476 | (48, 70, 5); 1477 | INSERT INTO public.people_in_films 1478 | VALUES 1479 | (49, 71, 5); 1480 | INSERT INTO public.people_in_films 1481 | VALUES 1482 | (50, 72, 5); 1483 | INSERT INTO public.people_in_films 1484 | VALUES 1485 | (51, 73, 5); 1486 | INSERT INTO public.people_in_films 1487 | VALUES 1488 | (52, 74, 5); 1489 | INSERT INTO public.people_in_films 1490 | VALUES 1491 | (53, 75, 5); 1492 | INSERT INTO public.people_in_films 1493 | VALUES 1494 | (54, 76, 5); 1495 | INSERT INTO public.people_in_films 1496 | VALUES 1497 | (55, 77, 5); 1498 | INSERT INTO public.people_in_films 1499 | VALUES 1500 | (56, 78, 5); 1501 | INSERT INTO public.people_in_films 1502 | VALUES 1503 | (57, 82, 5); 1504 | INSERT INTO public.people_in_films 1505 | VALUES 1506 | (58, 35, 5); 1507 | INSERT INTO public.people_in_films 1508 | VALUES 1509 | (59, 2, 4); 1510 | INSERT INTO public.people_in_films 1511 | VALUES 1512 | (60, 3, 4); 1513 | INSERT INTO public.people_in_films 1514 | VALUES 1515 | (61, 10, 4); 1516 | INSERT INTO public.people_in_films 1517 | VALUES 1518 | (62, 11, 4); 1519 | INSERT INTO public.people_in_films 1520 | VALUES 1521 | (63, 16, 4); 1522 | INSERT INTO public.people_in_films 1523 | VALUES 1524 | (64, 20, 4); 1525 | INSERT INTO public.people_in_films 1526 | VALUES 1527 | (65, 21, 4); 1528 | INSERT INTO public.people_in_films 1529 | VALUES 1530 | (66, 32, 4); 1531 | INSERT INTO public.people_in_films 1532 | VALUES 1533 | (67, 33, 4); 1534 | INSERT INTO public.people_in_films 1535 | VALUES 1536 | (68, 34, 4); 1537 | INSERT INTO public.people_in_films 1538 | VALUES 1539 | (69, 36, 4); 1540 | INSERT INTO public.people_in_films 1541 | VALUES 1542 | (70, 37, 4); 1543 | INSERT INTO public.people_in_films 1544 | VALUES 1545 | (71, 38, 4); 1546 | INSERT INTO public.people_in_films 1547 | VALUES 1548 | (72, 39, 4); 1549 | INSERT INTO public.people_in_films 1550 | VALUES 1551 | (73, 40, 4); 1552 | INSERT INTO public.people_in_films 1553 | VALUES 1554 | (74, 41, 4); 1555 | INSERT INTO public.people_in_films 1556 | VALUES 1557 | (75, 42, 4); 1558 | INSERT INTO public.people_in_films 1559 | VALUES 1560 | (76, 43, 4); 1561 | INSERT INTO public.people_in_films 1562 | VALUES 1563 | (77, 44, 4); 1564 | INSERT INTO public.people_in_films 1565 | VALUES 1566 | (78, 46, 4); 1567 | INSERT INTO public.people_in_films 1568 | VALUES 1569 | (79, 48, 4); 1570 | INSERT INTO public.people_in_films 1571 | VALUES 1572 | (80, 49, 4); 1573 | INSERT INTO public.people_in_films 1574 | VALUES 1575 | (81, 50, 4); 1576 | INSERT INTO public.people_in_films 1577 | VALUES 1578 | (82, 51, 4); 1579 | INSERT INTO public.people_in_films 1580 | VALUES 1581 | (83, 52, 4); 1582 | INSERT INTO public.people_in_films 1583 | VALUES 1584 | (84, 53, 4); 1585 | INSERT INTO public.people_in_films 1586 | VALUES 1587 | (85, 54, 4); 1588 | INSERT INTO public.people_in_films 1589 | VALUES 1590 | (86, 55, 4); 1591 | INSERT INTO public.people_in_films 1592 | VALUES 1593 | (87, 56, 4); 1594 | INSERT INTO public.people_in_films 1595 | VALUES 1596 | (88, 57, 4); 1597 | INSERT INTO public.people_in_films 1598 | VALUES 1599 | (89, 58, 4); 1600 | INSERT INTO public.people_in_films 1601 | VALUES 1602 | (90, 59, 4); 1603 | INSERT INTO public.people_in_films 1604 | VALUES 1605 | (91, 47, 4); 1606 | INSERT INTO public.people_in_films 1607 | VALUES 1608 | (92, 35, 4); 1609 | INSERT INTO public.people_in_films 1610 | VALUES 1611 | (93, 1, 6); 1612 | INSERT INTO public.people_in_films 1613 | VALUES 1614 | (94, 2, 6); 1615 | INSERT INTO public.people_in_films 1616 | VALUES 1617 | (95, 3, 6); 1618 | INSERT INTO public.people_in_films 1619 | VALUES 1620 | (96, 4, 6); 1621 | INSERT INTO public.people_in_films 1622 | VALUES 1623 | (97, 5, 6); 1624 | INSERT INTO public.people_in_films 1625 | VALUES 1626 | (98, 6, 6); 1627 | INSERT INTO public.people_in_films 1628 | VALUES 1629 | (99, 7, 6); 1630 | INSERT INTO public.people_in_films 1631 | VALUES 1632 | (100, 10, 6); 1633 | INSERT INTO public.people_in_films 1634 | VALUES 1635 | (101, 11, 6); 1636 | INSERT INTO public.people_in_films 1637 | VALUES 1638 | (102, 12, 6); 1639 | INSERT INTO public.people_in_films 1640 | VALUES 1641 | (103, 13, 6); 1642 | INSERT INTO public.people_in_films 1643 | VALUES 1644 | (104, 20, 6); 1645 | INSERT INTO public.people_in_films 1646 | VALUES 1647 | (105, 21, 6); 1648 | INSERT INTO public.people_in_films 1649 | VALUES 1650 | (106, 33, 6); 1651 | INSERT INTO public.people_in_films 1652 | VALUES 1653 | (107, 46, 6); 1654 | INSERT INTO public.people_in_films 1655 | VALUES 1656 | (108, 51, 6); 1657 | INSERT INTO public.people_in_films 1658 | VALUES 1659 | (109, 52, 6); 1660 | INSERT INTO public.people_in_films 1661 | VALUES 1662 | (110, 53, 6); 1663 | INSERT INTO public.people_in_films 1664 | VALUES 1665 | (111, 54, 6); 1666 | INSERT INTO public.people_in_films 1667 | VALUES 1668 | (112, 55, 6); 1669 | INSERT INTO public.people_in_films 1670 | VALUES 1671 | (113, 56, 6); 1672 | INSERT INTO public.people_in_films 1673 | VALUES 1674 | (114, 58, 6); 1675 | INSERT INTO public.people_in_films 1676 | VALUES 1677 | (115, 63, 6); 1678 | INSERT INTO public.people_in_films 1679 | VALUES 1680 | (116, 64, 6); 1681 | INSERT INTO public.people_in_films 1682 | VALUES 1683 | (117, 67, 6); 1684 | INSERT INTO public.people_in_films 1685 | VALUES 1686 | (118, 68, 6); 1687 | INSERT INTO public.people_in_films 1688 | VALUES 1689 | (119, 75, 6); 1690 | INSERT INTO public.people_in_films 1691 | VALUES 1692 | (120, 78, 6); 1693 | INSERT INTO public.people_in_films 1694 | VALUES 1695 | (121, 79, 6); 1696 | INSERT INTO public.people_in_films 1697 | VALUES 1698 | (122, 80, 6); 1699 | INSERT INTO public.people_in_films 1700 | VALUES 1701 | (123, 81, 6); 1702 | INSERT INTO public.people_in_films 1703 | VALUES 1704 | (124, 82, 6); 1705 | INSERT INTO public.people_in_films 1706 | VALUES 1707 | (125, 83, 6); 1708 | INSERT INTO public.people_in_films 1709 | VALUES 1710 | (126, 35, 6); 1711 | INSERT INTO public.people_in_films 1712 | VALUES 1713 | (127, 1, 3); 1714 | INSERT INTO public.people_in_films 1715 | VALUES 1716 | (128, 2, 3); 1717 | INSERT INTO public.people_in_films 1718 | VALUES 1719 | (129, 3, 3); 1720 | INSERT INTO public.people_in_films 1721 | VALUES 1722 | (130, 4, 3); 1723 | INSERT INTO public.people_in_films 1724 | VALUES 1725 | (131, 5, 3); 1726 | INSERT INTO public.people_in_films 1727 | VALUES 1728 | (132, 10, 3); 1729 | INSERT INTO public.people_in_films 1730 | VALUES 1731 | (133, 13, 3); 1732 | INSERT INTO public.people_in_films 1733 | VALUES 1734 | (134, 14, 3); 1735 | INSERT INTO public.people_in_films 1736 | VALUES 1737 | (135, 16, 3); 1738 | INSERT INTO public.people_in_films 1739 | VALUES 1740 | (136, 18, 3); 1741 | INSERT INTO public.people_in_films 1742 | VALUES 1743 | (137, 20, 3); 1744 | INSERT INTO public.people_in_films 1745 | VALUES 1746 | (138, 21, 3); 1747 | INSERT INTO public.people_in_films 1748 | VALUES 1749 | (139, 22, 3); 1750 | INSERT INTO public.people_in_films 1751 | VALUES 1752 | (140, 25, 3); 1753 | INSERT INTO public.people_in_films 1754 | VALUES 1755 | (141, 27, 3); 1756 | INSERT INTO public.people_in_films 1757 | VALUES 1758 | (142, 28, 3); 1759 | INSERT INTO public.people_in_films 1760 | VALUES 1761 | (143, 29, 3); 1762 | INSERT INTO public.people_in_films 1763 | VALUES 1764 | (144, 30, 3); 1765 | INSERT INTO public.people_in_films 1766 | VALUES 1767 | (145, 31, 3); 1768 | INSERT INTO public.people_in_films 1769 | VALUES 1770 | (146, 45, 3); 1771 | INSERT INTO public.people_in_films 1772 | VALUES 1773 | (147, 1, 2); 1774 | INSERT INTO public.people_in_films 1775 | VALUES 1776 | (148, 2, 2); 1777 | INSERT INTO public.people_in_films 1778 | VALUES 1779 | (149, 3, 2); 1780 | INSERT INTO public.people_in_films 1781 | VALUES 1782 | (150, 4, 2); 1783 | INSERT INTO public.people_in_films 1784 | VALUES 1785 | (151, 5, 2); 1786 | INSERT INTO public.people_in_films 1787 | VALUES 1788 | (152, 10, 2); 1789 | INSERT INTO public.people_in_films 1790 | VALUES 1791 | (153, 13, 2); 1792 | INSERT INTO public.people_in_films 1793 | VALUES 1794 | (154, 14, 2); 1795 | INSERT INTO public.people_in_films 1796 | VALUES 1797 | (155, 18, 2); 1798 | INSERT INTO public.people_in_films 1799 | VALUES 1800 | (156, 20, 2); 1801 | INSERT INTO public.people_in_films 1802 | VALUES 1803 | (157, 21, 2); 1804 | INSERT INTO public.people_in_films 1805 | VALUES 1806 | (158, 22, 2); 1807 | INSERT INTO public.people_in_films 1808 | VALUES 1809 | (159, 23, 2); 1810 | INSERT INTO public.people_in_films 1811 | VALUES 1812 | (160, 24, 2); 1813 | INSERT INTO public.people_in_films 1814 | VALUES 1815 | (161, 25, 2); 1816 | INSERT INTO public.people_in_films 1817 | VALUES 1818 | (162, 26, 2); 1819 | INSERT INTO public.people_in_films 1820 | VALUES 1821 | (163, 1, 7); 1822 | INSERT INTO public.people_in_films 1823 | VALUES 1824 | (164, 3, 7); 1825 | INSERT INTO public.people_in_films 1826 | VALUES 1827 | (165, 5, 7); 1828 | INSERT INTO public.people_in_films 1829 | VALUES 1830 | (166, 13, 7); 1831 | INSERT INTO public.people_in_films 1832 | VALUES 1833 | (167, 14, 7); 1834 | INSERT INTO public.people_in_films 1835 | VALUES 1836 | (168, 27, 7); 1837 | INSERT INTO public.people_in_films 1838 | VALUES 1839 | (169, 84, 7); 1840 | INSERT INTO public.people_in_films 1841 | VALUES 1842 | (170, 85, 7); 1843 | INSERT INTO public.people_in_films 1844 | VALUES 1845 | (171, 86, 7); 1846 | INSERT INTO public.people_in_films 1847 | VALUES 1848 | (172, 87, 7); 1849 | INSERT INTO public.people_in_films 1850 | VALUES 1851 | (173, 88, 7); 1852 | 1853 | 1854 | -- 1855 | -- TOC entry 4134 (class 0 OID 4163924) 1856 | -- Dependencies: 239 1857 | -- Data for Name: pilots; Type: TABLE DATA; Schema: Owner: - 1858 | -- 1859 | 1860 | INSERT INTO public.pilots 1861 | VALUES 1862 | (1, 1, 14); 1863 | INSERT INTO public.pilots 1864 | VALUES 1865 | (2, 18, 14); 1866 | INSERT INTO public.pilots 1867 | VALUES 1868 | (3, 13, 19); 1869 | INSERT INTO public.pilots 1870 | VALUES 1871 | (4, 1, 30); 1872 | INSERT INTO public.pilots 1873 | VALUES 1874 | (5, 5, 30); 1875 | INSERT INTO public.pilots 1876 | VALUES 1877 | (6, 10, 38); 1878 | INSERT INTO public.pilots 1879 | VALUES 1880 | (7, 32, 38); 1881 | INSERT INTO public.pilots 1882 | VALUES 1883 | (8, 44, 42); 1884 | INSERT INTO public.pilots 1885 | VALUES 1886 | (9, 11, 44); 1887 | INSERT INTO public.pilots 1888 | VALUES 1889 | (10, 70, 45); 1890 | INSERT INTO public.pilots 1891 | VALUES 1892 | (11, 11, 46); 1893 | INSERT INTO public.pilots 1894 | VALUES 1895 | (12, 79, 60); 1896 | INSERT INTO public.pilots 1897 | VALUES 1898 | (13, 67, 55); 1899 | INSERT INTO public.pilots 1900 | VALUES 1901 | (14, 13, 10); 1902 | INSERT INTO public.pilots 1903 | VALUES 1904 | (15, 14, 10); 1905 | INSERT INTO public.pilots 1906 | VALUES 1907 | (16, 25, 10); 1908 | INSERT INTO public.pilots 1909 | VALUES 1910 | (17, 31, 10); 1911 | INSERT INTO public.pilots 1912 | VALUES 1913 | (18, 1, 12); 1914 | INSERT INTO public.pilots 1915 | VALUES 1916 | (19, 9, 12); 1917 | INSERT INTO public.pilots 1918 | VALUES 1919 | (20, 18, 12); 1920 | INSERT INTO public.pilots 1921 | VALUES 1922 | (21, 19, 12); 1923 | INSERT INTO public.pilots 1924 | VALUES 1925 | (22, 4, 13); 1926 | INSERT INTO public.pilots 1927 | VALUES 1928 | (23, 22, 21); 1929 | INSERT INTO public.pilots 1930 | VALUES 1931 | (24, 1, 22); 1932 | INSERT INTO public.pilots 1933 | VALUES 1934 | (25, 13, 22); 1935 | INSERT INTO public.pilots 1936 | VALUES 1937 | (26, 14, 22); 1938 | INSERT INTO public.pilots 1939 | VALUES 1940 | (27, 29, 28); 1941 | INSERT INTO public.pilots 1942 | VALUES 1943 | (28, 11, 39); 1944 | INSERT INTO public.pilots 1945 | VALUES 1946 | (29, 60, 39); 1947 | INSERT INTO public.pilots 1948 | VALUES 1949 | (30, 35, 39); 1950 | INSERT INTO public.pilots 1951 | VALUES 1952 | (31, 39, 40); 1953 | INSERT INTO public.pilots 1954 | VALUES 1955 | (32, 44, 41); 1956 | INSERT INTO public.pilots 1957 | VALUES 1958 | (33, 10, 48); 1959 | INSERT INTO public.pilots 1960 | VALUES 1961 | (34, 58, 48); 1962 | INSERT INTO public.pilots 1963 | VALUES 1964 | (35, 35, 49); 1965 | INSERT INTO public.pilots 1966 | VALUES 1967 | (36, 10, 59); 1968 | INSERT INTO public.pilots 1969 | VALUES 1970 | (37, 11, 59); 1971 | INSERT INTO public.pilots 1972 | VALUES 1973 | (38, 86, 77); 1974 | INSERT INTO public.pilots 1975 | VALUES 1976 | (39, 10, 64); 1977 | INSERT INTO public.pilots 1978 | VALUES 1979 | (40, 35, 64); 1980 | INSERT INTO public.pilots 1981 | VALUES 1982 | (41, 10, 65); 1983 | INSERT INTO public.pilots 1984 | VALUES 1985 | (42, 11, 65); 1986 | INSERT INTO public.pilots 1987 | VALUES 1988 | (43, 10, 74); 1989 | INSERT INTO public.pilots 1990 | VALUES 1991 | (44, 79, 74); 1992 | 1993 | 1994 | 1995 | 1996 | -- 1997 | -- TOC entry 4132 (class 0 OID 4163916) 1998 | -- Dependencies: 237 1999 | -- Data for Name: planets_in_films; Type: TABLE DATA; Schema: Owner: - 2000 | -- 2001 | 2002 | INSERT INTO public.planets_in_films 2003 | VALUES 2004 | (1, 1, 2); 2005 | INSERT INTO public.planets_in_films 2006 | VALUES 2007 | (2, 1, 3); 2008 | INSERT INTO public.planets_in_films 2009 | VALUES 2010 | (3, 1, 1); 2011 | INSERT INTO public.planets_in_films 2012 | VALUES 2013 | (4, 5, 8); 2014 | INSERT INTO public.planets_in_films 2015 | VALUES 2016 | (5, 5, 9); 2017 | INSERT INTO public.planets_in_films 2018 | VALUES 2019 | (6, 5, 10); 2020 | INSERT INTO public.planets_in_films 2021 | VALUES 2022 | (7, 5, 11); 2023 | INSERT INTO public.planets_in_films 2024 | VALUES 2025 | (8, 5, 1); 2026 | INSERT INTO public.planets_in_films 2027 | VALUES 2028 | (9, 4, 8); 2029 | INSERT INTO public.planets_in_films 2030 | VALUES 2031 | (10, 4, 9); 2032 | INSERT INTO public.planets_in_films 2033 | VALUES 2034 | (11, 4, 1); 2035 | INSERT INTO public.planets_in_films 2036 | VALUES 2037 | (12, 6, 2); 2038 | INSERT INTO public.planets_in_films 2039 | VALUES 2040 | (13, 6, 5); 2041 | INSERT INTO public.planets_in_films 2042 | VALUES 2043 | (14, 6, 8); 2044 | INSERT INTO public.planets_in_films 2045 | VALUES 2046 | (15, 6, 9); 2047 | INSERT INTO public.planets_in_films 2048 | VALUES 2049 | (16, 6, 12); 2050 | INSERT INTO public.planets_in_films 2051 | VALUES 2052 | (17, 6, 13); 2053 | INSERT INTO public.planets_in_films 2054 | VALUES 2055 | (18, 6, 14); 2056 | INSERT INTO public.planets_in_films 2057 | VALUES 2058 | (19, 6, 15); 2059 | INSERT INTO public.planets_in_films 2060 | VALUES 2061 | (20, 6, 16); 2062 | INSERT INTO public.planets_in_films 2063 | VALUES 2064 | (21, 6, 17); 2065 | INSERT INTO public.planets_in_films 2066 | VALUES 2067 | (22, 6, 18); 2068 | INSERT INTO public.planets_in_films 2069 | VALUES 2070 | (23, 6, 19); 2071 | INSERT INTO public.planets_in_films 2072 | VALUES 2073 | (24, 6, 1); 2074 | INSERT INTO public.planets_in_films 2075 | VALUES 2076 | (25, 3, 5); 2077 | INSERT INTO public.planets_in_films 2078 | VALUES 2079 | (26, 3, 7); 2080 | INSERT INTO public.planets_in_films 2081 | VALUES 2082 | (27, 3, 8); 2083 | INSERT INTO public.planets_in_films 2084 | VALUES 2085 | (28, 3, 9); 2086 | INSERT INTO public.planets_in_films 2087 | VALUES 2088 | (29, 3, 1); 2089 | INSERT INTO public.planets_in_films 2090 | VALUES 2091 | (30, 2, 4); 2092 | INSERT INTO public.planets_in_films 2093 | VALUES 2094 | (31, 2, 5); 2095 | INSERT INTO public.planets_in_films 2096 | VALUES 2097 | (32, 2, 6); 2098 | INSERT INTO public.planets_in_films 2099 | VALUES 2100 | (33, 2, 27); 2101 | INSERT INTO public.planets_in_films 2102 | VALUES 2103 | (34, 7, 61); 2104 | 2105 | 2106 | 2107 | 2108 | -- 2109 | -- TOC entry 4130 (class 0 OID 4163908) 2110 | -- Dependencies: 235 2111 | -- Data for Name: species_in_films; Type: TABLE DATA; Schema: Owner: - 2112 | -- 2113 | 2114 | INSERT INTO public.species_in_films 2115 | VALUES 2116 | (1, 1, 5); 2117 | INSERT INTO public.species_in_films 2118 | VALUES 2119 | (2, 1, 3); 2120 | INSERT INTO public.species_in_films 2121 | VALUES 2122 | (3, 1, 2); 2123 | INSERT INTO public.species_in_films 2124 | VALUES 2125 | (4, 1, 1); 2126 | INSERT INTO public.species_in_films 2127 | VALUES 2128 | (5, 1, 4); 2129 | INSERT INTO public.species_in_films 2130 | VALUES 2131 | (6, 5, 32); 2132 | INSERT INTO public.species_in_films 2133 | VALUES 2134 | (7, 5, 33); 2135 | INSERT INTO public.species_in_films 2136 | VALUES 2137 | (8, 5, 2); 2138 | INSERT INTO public.species_in_films 2139 | VALUES 2140 | (9, 5, 35); 2141 | INSERT INTO public.species_in_films 2142 | VALUES 2143 | (10, 5, 6); 2144 | INSERT INTO public.species_in_films 2145 | VALUES 2146 | (11, 5, 1); 2147 | INSERT INTO public.species_in_films 2148 | VALUES 2149 | (12, 5, 12); 2150 | INSERT INTO public.species_in_films 2151 | VALUES 2152 | (13, 5, 34); 2153 | INSERT INTO public.species_in_films 2154 | VALUES 2155 | (14, 5, 13); 2156 | INSERT INTO public.species_in_films 2157 | VALUES 2158 | (15, 5, 15); 2159 | INSERT INTO public.species_in_films 2160 | VALUES 2161 | (16, 5, 28); 2162 | INSERT INTO public.species_in_films 2163 | VALUES 2164 | (17, 5, 29); 2165 | INSERT INTO public.species_in_films 2166 | VALUES 2167 | (18, 5, 30); 2168 | INSERT INTO public.species_in_films 2169 | VALUES 2170 | (19, 5, 31); 2171 | INSERT INTO public.species_in_films 2172 | VALUES 2173 | (20, 4, 1); 2174 | INSERT INTO public.species_in_films 2175 | VALUES 2176 | (21, 4, 2); 2177 | INSERT INTO public.species_in_films 2178 | VALUES 2179 | (22, 4, 6); 2180 | INSERT INTO public.species_in_films 2181 | VALUES 2182 | (23, 4, 11); 2183 | INSERT INTO public.species_in_films 2184 | VALUES 2185 | (24, 4, 12); 2186 | INSERT INTO public.species_in_films 2187 | VALUES 2188 | (25, 4, 13); 2189 | INSERT INTO public.species_in_films 2190 | VALUES 2191 | (26, 4, 14); 2192 | INSERT INTO public.species_in_films 2193 | VALUES 2194 | (27, 4, 15); 2195 | INSERT INTO public.species_in_films 2196 | VALUES 2197 | (28, 4, 16); 2198 | INSERT INTO public.species_in_films 2199 | VALUES 2200 | (29, 4, 17); 2201 | INSERT INTO public.species_in_films 2202 | VALUES 2203 | (30, 4, 18); 2204 | INSERT INTO public.species_in_films 2205 | VALUES 2206 | (31, 4, 19); 2207 | INSERT INTO public.species_in_films 2208 | VALUES 2209 | (32, 4, 20); 2210 | INSERT INTO public.species_in_films 2211 | VALUES 2212 | (33, 4, 21); 2213 | INSERT INTO public.species_in_films 2214 | VALUES 2215 | (34, 4, 22); 2216 | INSERT INTO public.species_in_films 2217 | VALUES 2218 | (35, 4, 23); 2219 | INSERT INTO public.species_in_films 2220 | VALUES 2221 | (36, 4, 24); 2222 | INSERT INTO public.species_in_films 2223 | VALUES 2224 | (37, 4, 25); 2225 | INSERT INTO public.species_in_films 2226 | VALUES 2227 | (38, 4, 26); 2228 | INSERT INTO public.species_in_films 2229 | VALUES 2230 | (39, 4, 27); 2231 | INSERT INTO public.species_in_films 2232 | VALUES 2233 | (40, 6, 19); 2234 | INSERT INTO public.species_in_films 2235 | VALUES 2236 | (41, 6, 33); 2237 | INSERT INTO public.species_in_films 2238 | VALUES 2239 | (42, 6, 2); 2240 | INSERT INTO public.species_in_films 2241 | VALUES 2242 | (43, 6, 3); 2243 | INSERT INTO public.species_in_films 2244 | VALUES 2245 | (44, 6, 36); 2246 | INSERT INTO public.species_in_films 2247 | VALUES 2248 | (45, 6, 37); 2249 | INSERT INTO public.species_in_films 2250 | VALUES 2251 | (46, 6, 6); 2252 | INSERT INTO public.species_in_films 2253 | VALUES 2254 | (47, 6, 1); 2255 | INSERT INTO public.species_in_films 2256 | VALUES 2257 | (48, 6, 34); 2258 | INSERT INTO public.species_in_films 2259 | VALUES 2260 | (49, 6, 15); 2261 | INSERT INTO public.species_in_films 2262 | VALUES 2263 | (50, 6, 35); 2264 | INSERT INTO public.species_in_films 2265 | VALUES 2266 | (51, 6, 20); 2267 | INSERT INTO public.species_in_films 2268 | VALUES 2269 | (52, 6, 23); 2270 | INSERT INTO public.species_in_films 2271 | VALUES 2272 | (53, 6, 24); 2273 | INSERT INTO public.species_in_films 2274 | VALUES 2275 | (54, 6, 25); 2276 | INSERT INTO public.species_in_films 2277 | VALUES 2278 | (55, 6, 26); 2279 | INSERT INTO public.species_in_films 2280 | VALUES 2281 | (56, 6, 27); 2282 | INSERT INTO public.species_in_films 2283 | VALUES 2284 | (57, 6, 28); 2285 | INSERT INTO public.species_in_films 2286 | VALUES 2287 | (58, 6, 29); 2288 | INSERT INTO public.species_in_films 2289 | VALUES 2290 | (59, 6, 30); 2291 | INSERT INTO public.species_in_films 2292 | VALUES 2293 | (60, 3, 1); 2294 | INSERT INTO public.species_in_films 2295 | VALUES 2296 | (61, 3, 2); 2297 | INSERT INTO public.species_in_films 2298 | VALUES 2299 | (62, 3, 3); 2300 | INSERT INTO public.species_in_films 2301 | VALUES 2302 | (63, 3, 5); 2303 | INSERT INTO public.species_in_films 2304 | VALUES 2305 | (64, 3, 6); 2306 | INSERT INTO public.species_in_films 2307 | VALUES 2308 | (65, 3, 8); 2309 | INSERT INTO public.species_in_films 2310 | VALUES 2311 | (66, 3, 9); 2312 | INSERT INTO public.species_in_films 2313 | VALUES 2314 | (67, 3, 10); 2315 | INSERT INTO public.species_in_films 2316 | VALUES 2317 | (68, 3, 15); 2318 | INSERT INTO public.species_in_films 2319 | VALUES 2320 | (69, 2, 6); 2321 | INSERT INTO public.species_in_films 2322 | VALUES 2323 | (70, 2, 7); 2324 | INSERT INTO public.species_in_films 2325 | VALUES 2326 | (71, 2, 3); 2327 | INSERT INTO public.species_in_films 2328 | VALUES 2329 | (72, 2, 2); 2330 | INSERT INTO public.species_in_films 2331 | VALUES 2332 | (73, 2, 1); 2333 | INSERT INTO public.species_in_films 2334 | VALUES 2335 | (74, 7, 3); 2336 | INSERT INTO public.species_in_films 2337 | VALUES 2338 | (75, 7, 2); 2339 | INSERT INTO public.species_in_films 2340 | VALUES 2341 | (76, 7, 1); 2342 | 2343 | 2344 | select setval('public.people__id_seq', 89, false); 2345 | select setval('public.planets__id_seq', 62, false); 2346 | select setval('public.vessels__id_seq', 78, false); 2347 | select setval('public.species__id_seq', 38, false); 2348 | select setval('public.films__id_seq', 8, false); 2349 | select setval('public.people_in_films__id_seq', 174, false); 2350 | select setval('public.planets_in_films__id_seq', 35, false); 2351 | select setval('public.species_in_films__id_seq', 77, false); 2352 | select setval('public.pilots__id_seq', 45, false); 2353 | select setval('public.starship_specs__id_seq', 39, false); -------------------------------------------------------------------------------- /test-suite/delete-test.ts: -------------------------------------------------------------------------------- 1 | import { Dorm } from '../lib/query-builder.ts'; 2 | import { assertEquals, assertNotEquals } from '../deps.ts'; 3 | import { config } from '../deps.ts'; 4 | /* 5 | *@select 6 | *Invalid 7 | *Testing for DELETE method 8 | *Single row deleting 9 | *Multiple rows deleting 10 | *All rows deleting (the whole table update) 11 | */ 12 | 13 | /*-------- CONNECTING TO THE DATABASE --------*/ 14 | const env = config(); 15 | // create .env file and add your database inside it. using followin variables USERNAME, PASSWORD, SERVER 16 | const URL = `postgres://${env.USERNAME}:${env.PASSWORD}@${env.SERVER}:5432/${env.USERNAME}`; 17 | 18 | const database = URL; // Or you can add your url here 19 | const dorm = new Dorm(database); 20 | 21 | /*-------- CREATING NEW DATA TO PERFORM ALL DELETE TASK --------*/ 22 | const initialSetup1 = await dorm 23 | .insert([ 24 | { 25 | username: 'Golden_Retreiver', 26 | email: 'iamagooddog@dogs.com', 27 | }, 28 | { 29 | username: 'Superman', 30 | email: 'superman@superman.com', 31 | }, 32 | { 33 | username: 'MrBing', 34 | email: 'chandlerbing@bings.com', 35 | }, 36 | { 37 | username: 'Golden_Retreiver', 38 | email: 'iamagooddog@dogs.com', 39 | }, 40 | { 41 | username: 'Superman', 42 | email: 'superman@superman.com', 43 | }, 44 | { 45 | username: 'MrBing', 46 | email: 'chandlerbing@bings.com', 47 | }, 48 | ]) 49 | .table('dropthis') 50 | .returning() 51 | .then((data: any) => data.rows) 52 | .catch((e) => e); 53 | 54 | const initialSetup3 = `INSERT INTO 55 | dropthis 56 | (username, email) 57 | VALUES 58 | ('dorm Member 1', 'chandlerbing@bings.com'), 59 | ('dorm Member 2', 'chandlerbing@bings.com'), 60 | ('dorm Member 3', 'chandlerbing@bings.com'), 61 | ('dorm Member 4', 'chandlerbing@bings.com'), 62 | ('dorm Member 5', 'chandlerbing@bings.com');`; 63 | const insertToUser = await dorm.raw(initialSetup3); 64 | /*------------ CREATING TESTING ID------------*/ 65 | var updateId = 2; 66 | 67 | /* -------------------------------------------------------------------------- */ 68 | /* QUERY VALIDATION TEST */ 69 | /* -------------------------------------------------------------------------- */ 70 | Deno.test(`all queries to be valid in "DELETE" method:`, ()=> { 71 | const tableName = 'users'; 72 | const condition = `user_id = ${updateId}` 73 | const test = dorm 74 | .delete() 75 | .from(tableName) 76 | .where(condition) 77 | .returning(); 78 | assertEquals(test.info.action.type , "DELETE", 'Error:Type should be updated to DELETE'); 79 | assertEquals(test.info.action.table , tableName, `Error:Table should be updated to ${tableName}`); 80 | assertEquals(test.info.filter.where , true, `Error:where should be updated to true`); 81 | assertEquals(test.info.returning.active , true, 'Error:Returning should be updated'); 82 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning should be pdated'); 83 | 84 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 85 | const testQuery = test.toString(); 86 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 87 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 88 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 89 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 90 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 91 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 92 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 93 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 94 | }) 95 | 96 | 97 | 98 | 99 | /* -------------------------------------------------------------------------- */ 100 | /* SINGLE ROW QUERY IN DELETE */ 101 | /* -------------------------------------------------------------------------- */ 102 | const deleteOneQuery = await dorm 103 | .delete('dropthis') 104 | .where(`_id = ${updateId}`) 105 | .returning() 106 | .then((data:any)=> { 107 | return data.rows; 108 | }) 109 | .catch((e:any) => { 110 | console.log('Error: ', e) 111 | }); 112 | 113 | 114 | 115 | Deno.test(`single-row query in "DELETE" method:`, ()=> { 116 | const tableName = 'userprofile'; 117 | const condition = `user_id = ${updateId}` 118 | const test = dorm 119 | .delete() 120 | .from(tableName) 121 | .where(condition) 122 | .returning(); 123 | assertEquals(Array.isArray(deleteOneQuery),true ,'Error:Delete query is not completed!'); 124 | assertEquals(test.info.action.type , 'DELETE', 'Error:Type is not updated to DELETE'); 125 | assertEquals(test.info.action.table , tableName, 'Error:Table is not updated to userprofile'); 126 | assertEquals(test.info.filter.where , true, `Error:where is not updated to true`); 127 | assertEquals(test.info.returning.active , true, 'Error:Returning is not updated'); 128 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 129 | 130 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 131 | const testQuery = test.toString(); 132 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 133 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 134 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 135 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 136 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 137 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 138 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 139 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 140 | }); 141 | 142 | 143 | /* -------------------------------------------------------------------------- */ 144 | /* MULTIPLE ROWS QUERY IN DELETE METHOD */ 145 | /* -------------------------------------------------------------------------- */ 146 | 147 | const deleteMultipleQuery = await dorm 148 | .delete() 149 | .from('dropthis') 150 | .where(`_id = ${updateId+1}`) 151 | .returning() 152 | .then((data:any)=> { 153 | return data; 154 | }).catch((e:any) => e); 155 | 156 | 157 | Deno.test(`multiple-rows query in "DELETE" method:`, ()=> { 158 | const tableName = 'users'; 159 | const condition = `user_id > ${updateId}` 160 | const test = dorm 161 | .delete() 162 | .from(tableName) 163 | .where(condition) 164 | .returning(); 165 | assertEquals(test.info.action.type , 'DELETE', 'Error:Type is not updated to DELETE'); 166 | assertEquals(test.info.action.table , tableName, 'Error:Table is not updated to userprofile'); 167 | assertEquals(test.info.filter.where , true, `Error:where is not updated to true`); 168 | assertEquals(test.info.returning.active , true, 'Error:Returning is not updated'); 169 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 170 | 171 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 172 | 173 | test.toString() 174 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 175 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 176 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 177 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 178 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 179 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 180 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 181 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 182 | }); 183 | 184 | /* -------------------------------------------------------------------------- */ 185 | /* DELETING ALL ROWS IN DELETE */ 186 | /* -------------------------------------------------------------------------- */ 187 | 188 | const deleteAllQuery = await dorm 189 | .delete() 190 | .from('dropthis') 191 | .returning() 192 | .then((data:any)=> { 193 | return data; 194 | }).catch((e:any) => e); 195 | 196 | 197 | Deno.test(`all rows cannot be deleted in "DELETE" method:`, ()=> { 198 | const tableName = 'users'; 199 | const condition = `` 200 | const test = dorm 201 | .delete() 202 | .from(tableName) 203 | .where(condition) 204 | .returning(); 205 | assertEquals(deleteAllQuery,'No delete without where (use deleteAll to delete all rows)','Error:Multiple DELETE query is not completed!'); 206 | assertEquals(test.info.action.type , 'DELETE', 'Error:Type is not updated to DELETE'); 207 | assertEquals(test.info.action.table , tableName, 'Error:Table is not updated to userprofile'); 208 | assertEquals(test.info.filter.where , true, `Error:where is not updated to true`); 209 | assertEquals(test.info.returning.active , true, 'Error:Returning is not updated'); 210 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 211 | 212 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 213 | 214 | const reset = (arg:Dorm) => { 215 | arg.callOrder = []; 216 | 217 | arg.error = { 218 | id: 0, 219 | message: '', 220 | }; 221 | 222 | arg.info = { 223 | action: { 224 | type: null, 225 | table: null, 226 | columns: '*', 227 | values: [], 228 | valuesParam: '', 229 | }, 230 | join: [], 231 | filter: { 232 | where: false, 233 | condition: null, 234 | }, 235 | returning: { 236 | active: false, 237 | columns: '*', 238 | }, 239 | }; 240 | } 241 | reset(test); 242 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 243 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 244 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 245 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 246 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 247 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 248 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 249 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 250 | }); 251 | -------------------------------------------------------------------------------- /test-suite/drop-test.ts: -------------------------------------------------------------------------------- 1 | import { Dorm } from '../lib/query-builder.ts'; 2 | import { assertEquals, assertNotEquals } from '../deps.ts'; 3 | import { config } from '../deps.ts'; 4 | export { query, poolConnect } from '../lib/db-connectors/pg-connector.ts'; 5 | /* 6 | *@select 7 | *Invalid 8 | *Testing for DELETE method 9 | *Single row deleting 10 | *Multiple rows deleting 11 | *All rows deleting (the whole table update) 12 | */ 13 | 14 | /*-------- CONNECTING TO THE DATABASE --------*/ 15 | 16 | const env = config(); 17 | // create .env file and add your database inside it. using followin variables USERNAME, PASSWORD, SERVER 18 | const URL = `postgres://${env.USERNAME}:${env.PASSWORD}@${env.SERVER}:5432/${env.USERNAME}`; 19 | 20 | const database = URL; // Or you can add your url here 21 | const dorm = new Dorm(database); 22 | 23 | /*------------ CREATING TESTING ID------------*/ 24 | var updateId = 2; 25 | 26 | /*------------ TESTING DROP METHOD ------------*/ 27 | const idropThis = await dorm 28 | .drop() 29 | .from('dropthis') 30 | .then((data: any) => { 31 | return data.rows; 32 | }) 33 | .catch((e) => e); 34 | 35 | /* -------------------------------------------------------------------------- */ 36 | /* VALIDATION TEST IN DROP */ 37 | /* -------------------------------------------------------------------------- */ 38 | 39 | Deno.test(`all queries to be valid in "DROP" method:`, ()=> { 40 | const tableName = 'dropthis'; 41 | const test = dorm 42 | .drop() 43 | .from(tableName) 44 | .returning(); 45 | assertEquals(idropThis,[],'Error:INVALID query found!!!! It should return an error for invalid query request from Postgres.'); 46 | assertEquals(test.info.action.type , 'DROP', 'Error:Type should be updated to DROP'); 47 | assertEquals(test.info.action.table , tableName, `Error:Table should be updated to ${tableName}`); 48 | assertEquals(test.info.returning.active , true, 'Error:Returning should be updated to true'); 49 | 50 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 51 | test.toString(); 52 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 53 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 54 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 55 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 56 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 57 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 58 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 59 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 60 | }); 61 | 62 | /* ---------------------- RECREATING THE DROPPED TABLE ---------------------- */ 63 | 64 | const initialSetup2 = `CREATE TABLE public.dropthis("_id" serial PRIMARY KEY,"username" VARCHAR ( 150 ) NULL,"email" VARCHAR ( 255 ) NULL)WITH (OIDS=FALSE);`; 65 | const tableToDrop = await dorm.raw(initialSetup2); 66 | -------------------------------------------------------------------------------- /test-suite/insert-test.ts: -------------------------------------------------------------------------------- 1 | import { Dorm } from '../lib/query-builder.ts'; 2 | import { assertEquals, assertNotEquals } from '../deps.ts'; 3 | import { config } from '../deps.ts'; 4 | 5 | /* 6 | *@insert 7 | *Invalid 8 | *Testing for INSERT method 9 | *Single row inserting 10 | *Multiple rows inserting 11 | */ 12 | 13 | /*----------------- CONNECTING TO THE DATABASE -----------------*/ 14 | 15 | const env = config(); 16 | // create .env file and add your database inside it. using followin variables USERNAME, PASSWORD, SERVER 17 | const URL = `postgres://${env.USERNAME}:${env.PASSWORD}@${env.SERVER}:5432/${env.USERNAME}`; 18 | 19 | const database = URL; // Or you can add your url here 20 | const dorm = new Dorm(database); 21 | 22 | /*------------ CREATING TESTING ID------------*/ 23 | var updateId = 2; 24 | 25 | 26 | const insertQuery = await dorm 27 | .insert([{'username':'newDogs', email: 'newdog@dog.com' }]) 28 | .table('dropthis') 29 | .returning() 30 | .then((data: any) => { 31 | return data; 32 | }) 33 | const insertSelectQuery1 = await dorm 34 | .select() 35 | .table('dropthis') 36 | .then((data: any) => { 37 | return data.rows; 38 | }) 39 | 40 | /* -------------------------------------------------------------------------- */ 41 | /* VALIDATION OF INSERT METHOD */ 42 | /* -------------------------------------------------------------------------- */ 43 | 44 | Deno.test(`all queries to be valid in "INSERT" method:`, () => { 45 | assertNotEquals(insertQuery, undefined, 'Error:the method should return a query result.') 46 | assertNotEquals(insertQuery, insertSelectQuery1, `Expected value: ${insertQuery} not to be equal to Received:${insertSelectQuery1}`) 47 | }); 48 | 49 | const invalidInsert = await dorm 50 | .insert([{'user':'newDogs'}]) 51 | .delete('dropthis') 52 | .table('dropthis') 53 | .where('_id=1') 54 | .then((data: any) => { 55 | return data.rows; 56 | }).catch((e:any)=> {return e}) 57 | 58 | Deno.test(`all invalid queries should not work in "INSERT" method:`,() => { 59 | assertEquals(invalidInsert, 'No multiple actions', `Error:INVALID query found!!!! It should return an error for invalid query request from Postgres.`) 60 | }) 61 | 62 | /* -------------------------------------------------------------------------- */ 63 | /* SINGLE ROW QUERY IN INSERT METHOD */ 64 | /* -------------------------------------------------------------------------- */ 65 | Deno.test(`single-row query in "INSERT" method:`, () => { 66 | const columnName = [{'username':'singleLady'}]; 67 | const tableName = 'users'; 68 | const returning = '*' 69 | const test = dorm 70 | .insert(columnName) 71 | .from(`${tableName}`) 72 | .returning(returning); 73 | assertEquals(test.info.action.type , 'INSERT', `Error:type is not updated to SELECT`); 74 | assertEquals(test.info.action.table , tableName, `Error:table is not updated to ${tableName}`); 75 | 76 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 77 | const testQuery = test.toString(); 78 | assertEquals(testQuery , `INSERT INTO users (username) VALUES ($1) RETURNING *`, 'Error:Querybuilder is returning unparametrized query string!!'); 79 | assertEquals(test.info.action.type , null, 'Error:Type is not reset after query'); 80 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset after query'); 81 | assertEquals(test.info.action.table , null, 'Error:Table is not reset after query'); 82 | assertEquals(test.info.action.values , [], 'Error:Value is not reset after query'); 83 | }); 84 | 85 | /* -------------------------------------------------------------------------- */ 86 | /* MULTIPLE ROWS QUERY IN INSERT METHOD */ 87 | /* -------------------------------------------------------------------------- */ 88 | Deno.test(`multiple-rows query in "INSERT" method:`, () => { 89 | const columnNames = [ 90 | { 91 | 'username':'Golden_Retreiver', 92 | 'password': 'golDenR', 93 | 'email':'iamagooddog@dogs.com', 94 | 'created_on': 'NOW()' 95 | }, 96 | { 97 | 'username':'Superman', 98 | 'password':'IamnotHuman', 99 | 'email':'superman@superman.com', 100 | 'created_on': 'NOW()' 101 | }, 102 | { 103 | 'username':'MrBing', 104 | 'password':'BingbingBing', 105 | 'email':'chandlerbing@bings.com', 106 | 'created_on': 'NOW()' 107 | } 108 | ]; 109 | const tableName = 'userprofile'; 110 | const test = dorm 111 | .insert(columnNames) 112 | .table(tableName) 113 | assertEquals(test.info.action.type , 'INSERT', 'Type is not updated to INSERT'); 114 | assertEquals(test.info.action.table , tableName, `Error:table is not updated to ${tableName}`); 115 | 116 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 117 | 118 | test.toString(); 119 | assertEquals(test.info.action.type , null, 'Error:Type is not reset after query'); 120 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset after query'); 121 | assertEquals(test.info.action.table , null, 'Error:Table is not reset after query'); 122 | assertEquals(test.info.action.values , [], 'Error:Value is not reset after query'); 123 | }); 124 | -------------------------------------------------------------------------------- /test-suite/join-test.ts: -------------------------------------------------------------------------------- 1 | import { Dorm } from '../lib/query-builder.ts'; 2 | import { assertEquals, assertNotEquals } from '../deps.ts'; 3 | import { config } from '../deps.ts'; 4 | 5 | /* 6 | *@join 7 | *Testing for JOIN method 8 | *Single table join inserting 9 | *Multiple table joins inserting 10 | * 11 | */ 12 | 13 | /*----------------- CONNECTING TO THE DATABASE -----------------*/ 14 | 15 | const env = config(); 16 | 17 | // create .env file and add your database inside it. using followin variables USERNAME, PASSWORD, SERVER 18 | 19 | const URL = `postgres://${env.USERNAME}:${env.PASSWORD}@${env.SERVER}:5432/${env.USERNAME}`; 20 | 21 | const database = URL; // Or you can add your url here 22 | const dorm = new Dorm(database); 23 | 24 | /*------------ TESTING INSERT METHOD ------------*/ 25 | 26 | /* -------------------------------------------------------------------------- */ 27 | /* TWO TABLE JOIN METHOD */ 28 | /* -------------------------------------------------------------------------- */ 29 | 30 | let fromTry: any; 31 | try { 32 | fromTry = await dorm 33 | .select() 34 | .from('people') 35 | .join('people_in_films') 36 | .on('people._id = people_in_films.person_id'); 37 | } catch (err) { 38 | console.log('Error:', err); 39 | } 40 | 41 | const fromRaw = await dorm.rawrr( 42 | `SELECT * FROM people LEFT OUTER JOIN people_in_films ON people._id = people_in_films.person_id` 43 | ); 44 | 45 | Deno.test(`Query completion for single Join in JOIN method:`, () => { 46 | assertEquals( 47 | Array.isArray(fromTry.rows), 48 | true, 49 | 'JOIN query is not completed' 50 | ); 51 | }); 52 | 53 | Deno.test(`dORM query vs raw query for single Join in JOIN method:`, () => { 54 | assertEquals( 55 | fromRaw.rows, 56 | fromTry.rows, 57 | 'JOIN query and RAW query should be equal.' 58 | ); 59 | }); 60 | 61 | /* -------------------------------------------------------------------------- */ 62 | /* MULTIPLE TABLE JOINS METHOD */ 63 | /* -------------------------------------------------------------------------- */ 64 | 65 | const multiJoinQuery1: any = await dorm 66 | .select() 67 | .from('people') 68 | .join('people_in_films') 69 | .on('people._id = people_in_films.person_id') 70 | .leftJoin('films') 71 | .on('people_in_films.film_id = films._id') 72 | .then((data: any) => { 73 | return data.rows; 74 | }) 75 | .catch((err) => { 76 | console.log('Error:', err); 77 | }); 78 | 79 | const fromRaw2 = await dorm.rawrr( 80 | `SELECT * FROM people LEFT OUTER JOIN "people_in_films" ON people._id = "people_in_films".person_id LEFT OUTER JOIN films ON "people_in_films".film_id = films._id` 81 | ); 82 | 83 | Deno.test(`Query completion for two Joins in JOIN method:`, () => { 84 | assertEquals( 85 | Array.isArray(multiJoinQuery1), 86 | true, 87 | 'JOIN query is not completed' 88 | ); 89 | }); 90 | 91 | Deno.test(`dORM query vs raw query for two Joins in JOIN method:`, () => { 92 | assertEquals( 93 | fromRaw2.rows, 94 | multiJoinQuery1, 95 | 'JOIN query and RAW query should be equal.' 96 | ); 97 | }); 98 | 99 | /* -------------------------------------------------------------------------- */ 100 | /* WITHOUT ON */ 101 | /* -------------------------------------------------------------------------- */ 102 | 103 | const multiJoinQuery2: any = await dorm 104 | .select() 105 | .from('people') 106 | .join('people_in_films') 107 | .then((data: any) => { 108 | return data; 109 | }) 110 | .catch((err) => { 111 | console.log('Error:', err); 112 | }); 113 | // console.log('multiJoinQuery2: ', multiJoinQuery2 ) 114 | Deno.test( 115 | `Query cannot complete without "ON" condition for two Joins in JOIN method:`, 116 | () => { 117 | assertEquals(multiJoinQuery2, undefined, 'JOIN query is not completed'); 118 | } 119 | ); 120 | 121 | /* -------------------------------------------------------------------------- */ 122 | /* FLEXIBLITY TEST ON JOINS */ 123 | /* -------------------------------------------------------------------------- */ 124 | 125 | const multiJoinQuery3: any = await dorm 126 | .select() 127 | .from('people') 128 | .on('people._id = people_in_films.person_id') 129 | .on('people_in_films.film_id = films._id') 130 | .where('people_in_films._id < 3') 131 | .join('people_in_films') 132 | .leftJoin('films') 133 | .then((data: any) => { 134 | return data.rows[0]; 135 | }) 136 | .catch((err) => { 137 | console.log('Error:', err); 138 | }); 139 | Deno.test( 140 | `Query cannot complete without "ON" condition for two Joins in JOIN method:`, 141 | () => { 142 | assertEquals(multiJoinQuery3.name, "Luke Skywalker", 'JOIN query is not completed'); 143 | } 144 | ); 145 | -------------------------------------------------------------------------------- /test-suite/main-test.ts: -------------------------------------------------------------------------------- 1 | import { Dorm } from '../lib/query-builder.ts'; 2 | import { assertEquals, assertNotEquals} from "../deps.ts"; 3 | import { config } from '../deps.ts'; 4 | 5 | /* ------------------------------ TESTING SCOPE ----------------------------- */ 6 | 7 | /* 8 | * @basic_cases {Query Completion, Data update,} 9 | * @edge_cases {Invalid strings, multiple methods, postgre error return, error handling} 10 | */ 11 | 12 | const env = config(); 13 | // create .env file and add your database inside it. using followin variables USERNAME, PASSWORD, SERVER 14 | const URL = `postgres://${env.USERNAME}:${env.PASSWORD}@${env.SERVER}:5432/${env.USERNAME}`; 15 | 16 | const database = URL; // Or you can add your url here 17 | const dorm = new Dorm(database); 18 | 19 | /* --------------------------- CREATING TESTING ID -------------------------- */ 20 | 21 | var updateId = 2; 22 | 23 | 24 | /* -------------------------------------------------------------------------- */ 25 | /* MAKING INITIAL QUERIES FOR TESTS */ 26 | /* -------------------------------------------------------------------------- */ 27 | 28 | 29 | const initialSetup1 = await dorm 30 | .insert([ 31 | { 32 | 'username':'Golden_Retreiver', 33 | 'email':'iamagooddog@dogs.com', 34 | }, 35 | { 36 | 'username':'Superman', 37 | 'email':'superman@superman.com', 38 | }, 39 | { 40 | 'username':'MrBing', 41 | 'email':'chandlerbing@bings.com', 42 | }, 43 | { 44 | 'username':'Golden_Retreiver', 45 | 'email':'iamagooddog@dogs.com', 46 | }, 47 | { 48 | 'username':'Superman', 49 | 'email':'superman@superman.com', 50 | }, 51 | { 52 | 'username':'MrBing', 53 | 'email':'chandlerbing@bings.com', 54 | } 55 | ]) 56 | .table('dropthis') 57 | .returning() 58 | .then((data:any) => data.rows) 59 | .catch((e:any) => e); 60 | 61 | const initialSetup3 = `INSERT INTO 62 | dropthis 63 | (username, email) 64 | VALUES 65 | ('dorm Member 1', 'chandlerbing@bings.com'), 66 | ('dorm Member 2', 'chandlerbing@bings.com'), 67 | ('dorm Member 3', 'chandlerbing@bings.com'), 68 | ('dorm Member 4', 'chandlerbing@bings.com'), 69 | ('dorm Member 5', 'chandlerbing@bings.com');` 70 | const insertToUser = await dorm.raw(initialSetup3); 71 | 72 | 73 | /* -------------------------------------------------------------------------- */ 74 | /* PARAMETERIZED STRING TEST */ 75 | /* -------------------------------------------------------------------------- */ 76 | Deno.test(`parameterized all column and values in all methods:`, () => { 77 | const columnNames = [ 78 | { 79 | 'username':'Golden_Retreiver', 80 | 'password': 'golDenR', 81 | 'email':'iamagooddog@dogs.com', 82 | 'created_on': 'NOW()' 83 | }, 84 | { 85 | 'username':'Superman', 86 | 'password':'IamnotHuman', 87 | 'email':'superman@superman.com', 88 | 'created_on': 'NOW()' 89 | }, 90 | { 91 | 'username':'MrBing', 92 | 'password':'BingbingBing', 93 | 'email':'chandlerbing@bings.com', 94 | 'created_on': 'NOW()' 95 | } 96 | ]; 97 | const tableName = 'userprofile'; 98 | const test = dorm 99 | .insert(columnNames) 100 | .table(tableName) 101 | .toObj() 102 | 103 | console.log('test:', test.text) 104 | assertEquals(test, { 105 | text: "INSERT INTO userprofile (username, password, email, created_on) VALUES ($1, $2, $3, $4), ($5, $6, $7, $8), ($9, $10, $11, $12)", 106 | values: [ 107 | "Golden_Retreiver", 108 | "golDenR", 109 | "iamagooddog@dogs.com", 110 | "NOW()", 111 | "Superman", 112 | "IamnotHuman", 113 | "superman@superman.com", 114 | "NOW()", 115 | "MrBing", 116 | "BingbingBing", 117 | "chandlerbing@bings.com", 118 | "NOW()" 119 | ] 120 | }, 'Error:Querybuilder is returning unparametrized query string!!' ) 121 | }); 122 | 123 | 124 | /* -------------------------------------------------------------------------- */ 125 | /* SELECT METHOD */ 126 | /* -------------------------------------------------------------------------- */ 127 | 128 | /* ------------------------------ NORMAL SELECT ----------------------------- */ 129 | 130 | const selectQuery = await dorm 131 | .select() 132 | .from('people') 133 | .where('_id=1') 134 | .then((data: any) => { 135 | return data.rows; 136 | }) 137 | .catch((e:any)=> {throw e}) 138 | Deno.test(`connection to the database:`, () => { 139 | assertNotEquals(selectQuery,undefined, 'connect should be returning a query.'); 140 | }); 141 | Deno.test(`"SELECT" method:`, () => { 142 | assertNotEquals(selectQuery,undefined, `Error:the method should return a query result.`); 143 | }); 144 | 145 | /* ------------------------- INVALAID SELECT METHOD ------------------------- */ 146 | 147 | const invalidSelect = await dorm 148 | .select() 149 | .from('userprofile') 150 | .where('_id=1') 151 | .then((data: any) => { 152 | return data.rows; 153 | }).catch((e:any)=> {return false}) 154 | 155 | Deno.test(`all queries to be valid in "SELECT" method:`,() => { 156 | assertEquals(invalidSelect, false, `Error:INVALID query found!!!! It should return an error for invalid query request from Postgres.`) 157 | }) 158 | 159 | /* ----------------------- SINGLE COLUMN SELECT METHOD ---------------------- */ 160 | 161 | Deno.test(`single-column query in "SELECT" method:`, () => { 162 | const tableName = 'userprofile'; 163 | const condition = 'user_id = 2' 164 | 165 | const test = dorm.select().from('userprofile').where('user_id = 2'); 166 | assertEquals(test.info.action.type , 'SELECT', `Error:type is not updated to SELECT`); 167 | assertEquals(test.info.action.table , tableName, `Error:table is not updated to ${tableName}`); 168 | assertEquals(test.info.filter.where , true, `Error:where is not updated to true`); 169 | 170 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 171 | 172 | const testQuery = test.toString(); 173 | assertEquals(testQuery , `SELECT * FROM userprofile WHERE user_id = $1`, 'Error:Querybuilder is returning unparametrized query string!!'); 174 | assertEquals(test.info.action.type , null, 'Error:Type is not reset after query'); 175 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset after query'); 176 | assertEquals(test.info.action.table , null, 'Error:Table is not reset after query'); 177 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 178 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 179 | }) 180 | 181 | /* --------------------- MULTIPLE COLUMNS SELECT METHOD --------------------- */ 182 | 183 | Deno.test(`multiple-columns query in "SELECT" method:`, () => { 184 | const columnName = 'username, email'; 185 | const tableName = 'userprofile'; 186 | const condition = 'user_id = 1' 187 | 188 | const test = dorm.select(columnName).from(tableName).where(condition); 189 | assertEquals(test.info.action.type , 'SELECT', 'Error:Type is not updated to SELECT'); 190 | assertEquals(test.info.action.columns , columnName, `Error:column/columns are updated to ${columnName}`); 191 | assertEquals(test.info.filter.where , true, `Error:where is not updated to true`); 192 | 193 | 194 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 195 | 196 | const testQuery = test.toString(); 197 | assertEquals(testQuery , `SELECT username, email FROM userprofile WHERE user_id = $1`, 'Error:Querybuilder is returning unparametrized query string!!'); 198 | assertEquals(test.info.action.type , null, 'Error:Type is not reset after query'); 199 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 200 | assertEquals(test.info.action.table , null, 'Error:Table is not reset after query'); 201 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 202 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 203 | }) 204 | 205 | /* -------------------------------------------------------------------------- */ 206 | /* INSERT METHOD */ 207 | /* -------------------------------------------------------------------------- */ 208 | 209 | const insertQuery = await dorm 210 | .insert([{'username':'newDogs', 'email': 'newdog@dog.com' }]) 211 | .table('dropthis') 212 | .returning() 213 | .then((data: any) => { 214 | return data; 215 | }) 216 | const insertSelectQuery1 = await dorm 217 | .select() 218 | .table('dropthis') 219 | .then((data: any) => { 220 | return data.rows; 221 | }) 222 | 223 | /* ----------------------- VALIDATION OF INSERT METHOD ---------------------- */ 224 | 225 | Deno.test(`all queries to be valid in "INSERT" method:`, () => { 226 | assertNotEquals(insertQuery, undefined, 'Error:the method should return a query result.') 227 | assertNotEquals(insertQuery, insertSelectQuery1, `Expected value: ${insertQuery} not to be equal to Received:${insertSelectQuery1}`) 228 | }); 229 | 230 | const invalidInsert = await dorm 231 | .insert([{'user':'newDogs'}]) 232 | .delete('dropthis') 233 | .table('dropthis') 234 | .where('_id=1') 235 | .then((data: any) => { 236 | return data.rows; 237 | }).catch((e:any)=> {return e}) 238 | 239 | Deno.test(`all invalid queries should not work in "INSERT" method:`,() => { 240 | assertEquals(invalidInsert, 'No multiple actions', `Error:INVALID query found!!!! It should return an error for invalid query request from Postgres.`) 241 | }) 242 | 243 | /* -------------------- SINGLE ROW QUERY IN INSERT METHOD ------------------- */ 244 | 245 | Deno.test(`single-row query in "INSERT" method:`, () => { 246 | const columnName = [{'username':'singleLady'}]; 247 | const tableName = 'users'; 248 | const returning = '*' 249 | const test = dorm 250 | .insert(columnName) 251 | .from(`${tableName}`) 252 | .returning(returning); 253 | assertEquals(test.info.action.type , 'INSERT', `Error:type is not updated to SELECT`); 254 | assertEquals(test.info.action.table , tableName, `Error:table is not updated to ${tableName}`); 255 | 256 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 257 | const testQuery = test.toString(); 258 | assertEquals(testQuery , `INSERT INTO users (username) VALUES ($1) RETURNING *`, 'Error:Querybuilder is returning unparametrized query string!!'); 259 | assertEquals(test.info.action.type , null, 'Error:Type is not reset after query'); 260 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset after query'); 261 | assertEquals(test.info.action.table , null, 'Error:Table is not reset after query'); 262 | assertEquals(test.info.action.values , [], 'Error:Value is not reset after query'); 263 | }); 264 | 265 | /* ------------------ MULTIPLE ROWS QUERY IN INSERT METHOD ------------------ */ 266 | 267 | Deno.test(`multiple-rows query in "INSERT" method:`, () => { 268 | const columnNames = [ 269 | { 270 | 'username':'Golden_Retreiver', 271 | 'password': 'golDenR', 272 | 'email':'iamagooddog@dogs.com', 273 | 'created_on': 'NOW()' 274 | }, 275 | { 276 | 'username':'Superman', 277 | 'password':'IamnotHuman', 278 | 'email':'superman@superman.com', 279 | 'created_on': 'NOW()' 280 | }, 281 | { 282 | 'username':'MrBing', 283 | 'password':'BingbingBing', 284 | 'email':'chandlerbing@bings.com', 285 | 'created_on': 'NOW()' 286 | } 287 | ]; 288 | const tableName = 'userprofile'; 289 | const test = dorm 290 | .insert(columnNames) 291 | .table(tableName) 292 | assertEquals(test.info.action.type , 'INSERT', 'Type is not updated to INSERT'); 293 | assertEquals(test.info.action.table , tableName, `Error:table is not updated to ${tableName}`); 294 | 295 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 296 | 297 | test.toString(); 298 | assertEquals(test.info.action.type , null, 'Error:Type is not reset after query'); 299 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset after query'); 300 | assertEquals(test.info.action.table , null, 'Error:Table is not reset after query'); 301 | assertEquals(test.info.action.values , [], 'Error:Value is not reset after query'); 302 | }); 303 | 304 | 305 | /* -------------------------------------------------------------------------- */ 306 | /* UPDATE METHOD */ 307 | /* -------------------------------------------------------------------------- */ 308 | 309 | 310 | /* -------------------- SINGLE ROW QUERY IN UPDATE METHOD ------------------- */ 311 | 312 | const updateQuery = await dorm 313 | .update({'username':'updatedDogs', 'email': 'updated@dogs.com'}) 314 | .where(`_id = ${updateId}`) 315 | .table('dropthis') 316 | .returning() 317 | .then((data: any) => { 318 | return data.rows; 319 | }).catch((e:any) => e); 320 | 321 | const testUpdateQuery1 = await dorm 322 | .select() 323 | .table('dropthis') 324 | .where(`_id=${updateId}`) 325 | .then((data: any) => { 326 | 327 | return data.rows; 328 | }).catch((e:any) => e); 329 | 330 | 331 | Deno.test(`a single-row query in "UPDATE" method:`, () => { 332 | const test = dorm.update({'username':'newDogs', 'password': 'iLoveDogs'}).where(`user_id = ${updateId+1}`) 333 | .from('userprofile') 334 | .returning('username') 335 | assertEquals(updateQuery, testUpdateQuery1 , 'Error: the method should work more than one row'); 336 | assertEquals(test.info.action.type , 'UPDATE', 'Error:Type is not updated to UPDATE'); 337 | assertEquals(test.info.action.table , 'userprofile', 'Error:Table is not updated to userprofile'); 338 | assertEquals(test.info.returning.active , true, 'Error:Returning is not updated'); 339 | assertEquals(test.info.returning.columns , 'username', 'Error:Columns in Returning is not reset'); 340 | 341 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 342 | 343 | test.toString(); 344 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 345 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 346 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 347 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 348 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 349 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 350 | }); 351 | 352 | 353 | /* ------------------ MULTIPLE ROWS QUERY IN UPDATE METHOD ------------------ */ 354 | const testUpdateQuery2 = await dorm 355 | .select() 356 | .table('userprofile') 357 | .where(`user_id < ${updateId}`) 358 | .then((data: any) => { 359 | return data.rows; 360 | }).catch((e:any) => e); 361 | 362 | const multipleRowsQuery = await dorm 363 | .update({'username':'Dogs', 'email': 'iamnotagooddog@dogs.com'}) 364 | .table('dropthis') 365 | .where(`_id < ${updateId}`) 366 | .returning() 367 | .then((data: any) => { 368 | return data; 369 | }).catch((e:any) => e); 370 | 371 | 372 | Deno.test(`multiple-rows query in "UPDATE" method:`, () => { 373 | const test = dorm.update({'username':'Dogs', 'password': 'ihave8Dogs'}).where(`user_id <= ${updateId}`) 374 | .from('userprofile') 375 | .returning('username'); 376 | assertNotEquals(multipleRowsQuery, testUpdateQuery2, `Error:${updateId} rows was not updated `); 377 | assertEquals(test.info.action.type , 'UPDATE', 'Error:Type is not updated to UPDATE'); 378 | assertEquals(test.info.action.table , 'userprofile', 'Error:Table is not updated to userprofile'); 379 | assertEquals(test.info.returning.active , true, 'Error:Returning is not updated'); 380 | assertEquals(test.info.returning.columns , 'username', 'Error:Columns in Returning is not reset'); 381 | 382 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 383 | 384 | const testQuery = test.toString(); 385 | assertEquals(testQuery , `UPDATE userprofile SET username = $1, password = $2 WHERE user_id < = $3 RETURNING username`, 'Error:Querybuilder is returning unparametrized query string!!'); 386 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 387 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 388 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 389 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 390 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 391 | }); 392 | 393 | 394 | /* --------------- ALL ROWS TO BE UPDATED USING UPDATE METHOD --------------- */ 395 | 396 | const allRowsUpdateQuery = await dorm 397 | .update({'username':'restarted', 'email': 'iamagoodcat@cats.com'}) 398 | .table('dropthis') 399 | .returning() 400 | .then((data: any) => { 401 | return data.rows; 402 | }).catch((e:any) => e); 403 | 404 | Deno.test(`all rows query in "UPDATE" method:`, () => { 405 | const test = dorm.update({'username':'restarted', 'password': 'iamADog'}) 406 | .from('userprofile') 407 | .returning('username'); 408 | assertEquals(Array.isArray(allRowsUpdateQuery), true,'Error:The whole table was not updated'); 409 | assertEquals(test.info.action.type , 'UPDATE', 'Error:Type is not updated to UPDATE'); 410 | assertEquals(test.info.action.table , 'userprofile', 'Error:Table is not updated to userprofile'); 411 | assertEquals(test.info.returning.active , true, 'Error:Returning is not updated'); 412 | assertEquals(test.info.returning.columns , 'username', 'Error:Columns in Returning is not reset'); 413 | 414 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 415 | 416 | const testQuery = test.toString(); 417 | assertEquals(testQuery , `UPDATE userprofile SET username = $1, password = $2 RETURNING username`, 'Error:Querybuilder is returning unparametrized query string!!'); 418 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 419 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 420 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 421 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 422 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 423 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 424 | }); 425 | 426 | 427 | /* -------------------------------------------------------------------------- */ 428 | /* DELETE METHOD */ 429 | /* -------------------------------------------------------------------------- */ 430 | 431 | Deno.test(`all queries to be valid in "DELETE" method:`, ()=> { 432 | const tableName = 'users'; 433 | const condition = `user_id = ${updateId+2}` 434 | const test = dorm 435 | .delete() 436 | .from(tableName) 437 | .where(condition) 438 | .returning(); 439 | assertEquals(test.info.action.type , "DELETE", 'Error:Type should be updated to DELETE'); 440 | assertEquals(test.info.action.table , tableName, `Error:Table should be updated to ${tableName}`); 441 | assertEquals(test.info.filter.where , true, `Error:where should be updated to true`); 442 | assertEquals(test.info.returning.active , true, 'Error:Returning should be updated'); 443 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning should be pdated'); 444 | 445 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 446 | const testQuery = test.toString(); 447 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 448 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 449 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 450 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 451 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 452 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 453 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 454 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 455 | }) 456 | 457 | 458 | /* ----------------------- SINGLE ROW QUERY IN DELETE ----------------------- */ 459 | 460 | const deleteOneQuery = await dorm 461 | .delete('dropthis') 462 | .where(`_id = ${updateId}`) 463 | .returning() 464 | .then((data:any)=> { 465 | return data.rows; 466 | }) 467 | .catch((e:any) => { 468 | console.log('Error: ', e) 469 | }); 470 | 471 | 472 | Deno.test(`single-row query in "DELETE" method:`, ()=> { 473 | const tableName = 'userprofile'; 474 | const condition = `user_id = ${updateId+1}` 475 | const test = dorm 476 | .delete() 477 | .from(tableName) 478 | .where(condition) 479 | .returning(); 480 | assertEquals(Array.isArray(deleteOneQuery),true ,'Error:Delete query is not completed!'); 481 | assertEquals(test.info.action.type , 'DELETE', 'Error:Type is not updated to DELETE'); 482 | assertEquals(test.info.action.table , tableName, 'Error:Table is not updated to userprofile'); 483 | assertEquals(test.info.filter.where , true, `Error:where is not updated to true`); 484 | assertEquals(test.info.returning.active , true, 'Error:Returning is not updated'); 485 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 486 | 487 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 488 | const testQuery = test.toString(); 489 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 490 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 491 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 492 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 493 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 494 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 495 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 496 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 497 | }); 498 | 499 | 500 | 501 | /* ------------------ MULTIPLE ROWS QUERY IN DELETE METHOD ------------------ */ 502 | 503 | const deleteMultipleQuery = await dorm 504 | .delete() 505 | .from('dropthis') 506 | .where(`_id = ${updateId+1}`) 507 | .returning() 508 | .then((data:any)=> { 509 | return data; 510 | }).catch((e:any) => e); 511 | 512 | Deno.test(`multiple-rows query in "DELETE" method:`, ()=> { 513 | const tableName = 'users'; 514 | const condition = `user_id > ${updateId+2}` 515 | const test = dorm 516 | .delete() 517 | .from(tableName) 518 | .where(condition) 519 | .returning(); 520 | assertEquals(test.info.action.type , 'DELETE', 'Error:Type is not updated to DELETE'); 521 | assertEquals(test.info.action.table , tableName, 'Error:Table is not updated to userprofile'); 522 | assertEquals(test.info.filter.where , true, `Error:where is not updated to true`); 523 | assertEquals(test.info.returning.active , true, 'Error:Returning is not updated'); 524 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 525 | 526 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 527 | 528 | test.toString() 529 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 530 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 531 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 532 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 533 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 534 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 535 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 536 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 537 | }); 538 | 539 | /* ---------------------- DELETING ALL ROWS IN DELETE ---------------------- */ 540 | 541 | const deleteAllQuery = await dorm 542 | .delete() 543 | .from('dropthis') 544 | .returning() 545 | .then((data:any)=> { 546 | return data; 547 | }).catch((e:any) => e); 548 | 549 | Deno.test(`all rows cannot be deleted in "DELETE" method:`, ()=> { 550 | const tableName = 'users'; 551 | const condition = `` 552 | const test = dorm 553 | .delete() 554 | .from(tableName) 555 | .where(condition) 556 | .returning(); 557 | assertEquals(deleteAllQuery,'No delete without where (use deleteAll to delete all rows)','Error:Multiple DELETE query is not completed!'); 558 | assertEquals(test.info.action.type , 'DELETE', 'Error:Type is not updated to DELETE'); 559 | assertEquals(test.info.action.table , tableName, 'Error:Table is not updated to userprofile'); 560 | assertEquals(test.info.filter.where , true, `Error:where is not updated to true`); 561 | assertEquals(test.info.returning.active , true, 'Error:Returning is not updated'); 562 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 563 | 564 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 565 | 566 | const reset = (arg:Dorm) => { 567 | arg.callOrder = []; 568 | 569 | arg.error = { 570 | id: 0, 571 | message: '', 572 | }; 573 | 574 | arg.info = { 575 | action: { 576 | type: null, 577 | table: null, 578 | columns: '*', 579 | values: [], 580 | valuesParam: '', 581 | }, 582 | join: [], 583 | filter: { 584 | where: false, 585 | condition: null, 586 | }, 587 | returning: { 588 | active: false, 589 | columns: '*', 590 | }, 591 | }; 592 | } 593 | reset(test); 594 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 595 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 596 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 597 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 598 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 599 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 600 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 601 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 602 | }); 603 | 604 | 605 | 606 | /* -------------------------------------------------------------------------- */ 607 | /* DROP METHOD */ 608 | /* -------------------------------------------------------------------------- */ 609 | 610 | const idropThis = dorm 611 | .drop('dropthis') 612 | .then((data:any)=>{ 613 | return data; 614 | }).catch((e:any) => e); 615 | 616 | /* ------------------------- VALIDATION TEST IN DROP ------------------------ */ 617 | 618 | Deno.test(`all queries to be valid in "DROP" method:`, ()=> { 619 | const tableName = 'dropthis'; 620 | const test = dorm 621 | .drop() 622 | .from(tableName) 623 | .returning(); 624 | assertEquals(idropThis,[],'Error:INVALID query found!!!! It should return an error for invalid query request from Postgres.'); 625 | assertEquals(test.info.action.type , 'DROP', 'Error:Type should be updated to DROP'); 626 | assertEquals(test.info.action.table , tableName, `Error:Table should be updated to ${tableName}`); 627 | assertEquals(test.info.returning.active , true, 'Error:Returning should be updated to true'); 628 | 629 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 630 | test.toString(); 631 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 632 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 633 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 634 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 635 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 636 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 637 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 638 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 639 | }); 640 | 641 | /* ---------------------- RECREATING THE DROPPED TABLE ---------------------- */ 642 | 643 | const initialSetup2 = `CREATE TABLE public.dropthis("_id" serial PRIMARY KEY,"username" VARCHAR ( 150 ) NULL,"email" VARCHAR ( 255 ) NULL)WITH (OIDS=FALSE);` 644 | const tableToDrop = await dorm.raw(initialSetup2); 645 | 646 | /* -------------------------------------------------------------------------- */ 647 | /* Join Method */ 648 | /* -------------------------------------------------------------------------- */ 649 | 650 | let fromTry:any; 651 | try{ 652 | fromTry = await dorm 653 | .select() 654 | .from('people') 655 | .join('people_in_films') 656 | .on('people._id = people_in_films.person_id'); 657 | } 658 | catch(err){ 659 | console.log('Error:', err); 660 | } 661 | 662 | const fromRaw = await dorm.rawrr(`SELECT * FROM people LEFT OUTER JOIN people_in_films ON people._id = people_in_films.person_id`); 663 | 664 | /* ---------------------------- SINGLE JOIN TEST ---------------------------- */ 665 | 666 | Deno.test(`Query completion for single Join in JOIN method:`, () => { 667 | assertEquals(Array.isArray(fromTry.rows), true , 'JOIN query is not completed') 668 | }); 669 | 670 | Deno.test(`dORM query vs raw query for single Join in JOIN method:`, () => { 671 | assertEquals(fromRaw.rows, fromTry.rows, 'JOIN query and RAW query should be equal.') 672 | }); 673 | 674 | const multiJoinQuery1: any = await dorm 675 | .select() 676 | .from('people') 677 | .join('people_in_films') 678 | .on('people._id = people_in_films.person_id') 679 | .join('films') 680 | .on('people_in_films.film_id = films._id') 681 | .then((data:any)=> { 682 | return data.rows; 683 | }) 684 | .catch ((err:any) => { 685 | console.log('Error:', err) 686 | }) 687 | 688 | const fromRaw2 = await dorm.rawrr(`SELECT * FROM people LEFT OUTER JOIN "people_in_films" ON people._id = "people_in_films".person_id LEFT OUTER JOIN films ON "people_in_films".film_id = films._id`); 689 | 690 | 691 | /* --------------------------- MULTIPLE JOIN TEST --------------------------- */ 692 | 693 | Deno.test(`Query completion for two Joins in JOIN method:`, () => { 694 | assertEquals(Array.isArray(multiJoinQuery1), true , 'JOIN query is not completed') 695 | }); 696 | 697 | Deno.test(`dORM query vs raw query for two Joins in JOIN method:`, () => { 698 | assertEquals(fromRaw2.rows, multiJoinQuery1, 'JOIN query and RAW query should be equal.') 699 | }); 700 | 701 | /* ----------------------------- FLEXIBLITY TEST ---------------------------- */ 702 | 703 | const multiJoinQuery3: any = await dorm 704 | .select() 705 | .from('people') 706 | .on('people._id = people_in_films.person_id') 707 | .on('people_in_films.film_id = films._id') 708 | .where('people_in_films._id < 3') 709 | .join('people_in_films') 710 | .leftJoin('films') 711 | .then((data: any) => { 712 | return data.rows[0]; 713 | }) 714 | .catch((err) => { 715 | console.log('Error:', err); 716 | }); 717 | Deno.test( 718 | `Query cannot complete without "ON" condition for two Joins in JOIN method:`, 719 | () => { 720 | assertEquals(multiJoinQuery3.name, "Luke Skywalker", 'JOIN query is not completed'); 721 | } 722 | ); -------------------------------------------------------------------------------- /test-suite/select-test.ts: -------------------------------------------------------------------------------- 1 | import { Dorm } from '../lib/query-builder.ts'; 2 | import { assertEquals, assertNotEquals } from '../deps.ts'; 3 | import { config } from '../deps.ts'; 4 | 5 | /* 6 | * @select 7 | * Invalid 8 | * Testing for SELECT method 9 | * Single column selecting 10 | * Multiple columns selecting 11 | * Edge cases: 12 | * calling multiple actions/methods 13 | */ 14 | 15 | /*-------- CONNECTING TO THE DATABASE --------*/ 16 | 17 | const env = config(); 18 | // create .env file and add your database inside it. using followin variables USERNAME, PASSWORD, SERVER 19 | const URL = `postgres://${env.USERNAME}:${env.PASSWORD}@${env.SERVER}:5432/${env.USERNAME}`; 20 | 21 | const database = URL; // Or you can add your url here 22 | const dorm = new Dorm(database); 23 | 24 | /*------------ CREATING TESTING ID------------*/ 25 | var updateId = 2; 26 | 27 | /* -------------------------------------------------------------------------- */ 28 | /* QUERY VALIDATION TEST */ 29 | /* -------------------------------------------------------------------------- */ 30 | 31 | const selectQuery = await dorm 32 | .select() 33 | .from('people') 34 | .where('_id=1') 35 | .then((data: any) => { 36 | return data.rows; 37 | }) 38 | .catch((e:any)=> {throw e}) 39 | Deno.test(`connection to the database:`, () => { 40 | assertNotEquals(selectQuery,undefined, 'connect should be returning a query.'); 41 | }); 42 | Deno.test(`"SELECT" method:`, () => { 43 | assertNotEquals(selectQuery,undefined, `Error:the method should return a query result.`); 44 | }); 45 | 46 | 47 | /* -------------------------------------------------------------------------- */ 48 | /* MULTIPLE ACTION VALIDATION TEST */ 49 | /* -------------------------------------------------------------------------- */ 50 | 51 | const invalidSelect1 = await dorm 52 | .select() 53 | .from('people') 54 | .delete() 55 | .where('_id=1') 56 | .then((data: any) => { 57 | return data.rows; 58 | }) 59 | .catch((e) => { 60 | return e; 61 | }); 62 | 63 | Deno.test(`all queries to be valid in "SELECT" method:`, () => { 64 | assertEquals( 65 | invalidSelect1, 66 | 'No multiple actions', 67 | `Error:INVALID query found!!!! It should return an error for invalid query request from Postgres.` 68 | ); 69 | }); 70 | 71 | /* -------------------------------------------------------------------------- */ 72 | /* INVALID QUERY STRING TEST */ 73 | /* -------------------------------------------------------------------------- */ 74 | 75 | const invalidSelect = await dorm 76 | .select() 77 | .from('userprofile') 78 | .where('_id=1') 79 | .then((data: any) => { 80 | return data.rows; 81 | }).catch((e:any)=> {return false}) 82 | 83 | Deno.test(`all queries to be valid in "SELECT" method:`,() => { 84 | assertEquals(invalidSelect, false, `Error:INVALID query found!!!! It should return an error for invalid query request from Postgres.`) 85 | }) 86 | 87 | /* -------------------------------------------------------------------------- */ 88 | /* SINGLE COLUMN QUERY */ 89 | /* -------------------------------------------------------------------------- */ 90 | 91 | Deno.test(`single-column query in "SELECT" method:`, () => { 92 | const tableName = 'userprofile'; 93 | const condition = 'user_id = 2' 94 | 95 | const test = dorm.select().from('userprofile').where('user_id = 2'); 96 | assertEquals(test.info.action.type , 'SELECT', `Error:type is not updated to SELECT`); 97 | assertEquals(test.info.action.table , tableName, `Error:table is not updated to ${tableName}`); 98 | assertEquals(test.info.filter.where , true, `Error:where is not updated to true`); 99 | 100 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 101 | 102 | const testQuery = test.toString(); 103 | assertEquals(testQuery , `SELECT * FROM userprofile WHERE user_id = $1`, 'Error:Querybuilder is returning unparametrized query string!!'); 104 | assertEquals(test.info.action.type , null, 'Error:Type is not reset after query'); 105 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset after query'); 106 | assertEquals(test.info.action.table , null, 'Error:Table is not reset after query'); 107 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 108 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 109 | }) 110 | 111 | /* -------------------------------------------------------------------------- */ 112 | /* MULTIPLE COLUMNS QUERY TEST */ 113 | /* -------------------------------------------------------------------------- */ 114 | 115 | Deno.test(`multiple-columns query in "SELECT" method:`, () => { 116 | const columnName = 'username, email'; 117 | const tableName = 'userprofile'; 118 | const condition = 'user_id = 1' 119 | 120 | const test = dorm.select(columnName).from(tableName).where(condition); 121 | assertEquals(test.info.action.type , 'SELECT', 'Error:Type is not updated to SELECT'); 122 | assertEquals(test.info.action.columns , columnName, `Error:column/columns are updated to ${columnName}`); 123 | assertEquals(test.info.filter.where , true, `Error:where is not updated to true`); 124 | 125 | 126 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 127 | 128 | const testQuery = test.toString(); 129 | assertEquals(testQuery , `SELECT username, email FROM userprofile WHERE user_id = $1`, 'Error:Querybuilder is returning unparametrized query string!!'); 130 | assertEquals(test.info.action.type , null, 'Error:Type is not reset after query'); 131 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 132 | assertEquals(test.info.action.table , null, 'Error:Table is not reset after query'); 133 | assertEquals(test.info.filter.where , false, `Error:where is not reset after query`); 134 | assertEquals(test.info.filter.condition , null, `Error:condition is not reset after query`); 135 | }) -------------------------------------------------------------------------------- /test-suite/testing.md: -------------------------------------------------------------------------------- 1 | # Creating testing environment 2 | 3 | ## Please follow the instructions below prior to test this deno module: 4 | 5 | - [ ] Go to your terminal and verify that you can run the psql command: 6 | - [ ] Invoke `psql -d -f ./test-suite/db_test_starwars_create.sql`. This will open the connection to your database and execute the SQL statements that will create tables in your database and populate them with rows of data. Make sure you let the script run all the way through. It will take a minute or two. 7 | - [ ] please add your database url in the url in the file you want to run. 8 | _(will be updating this part after adding create table method.)_ 9 | 10 | ## Please create an .env file and add the followings: 11 | 12 | You can get your username, password and database_name from your database url as shown in the example: 13 | const URL = `postgres://${env.USERNAME}:${env.PASSWORD}@${env.SERVER}:5432/${env.USERNAME}`; 14 | `USERNAME = PASSWORD = SERVER = ` 15 | 16 | ## Running all tests at once: 17 | 18 | - Invoke `deno test --allow-net --allow-read --unstable ./test-suite/main-test.ts` in your terminal. Make sure to check deno version to be latest version to run the test. 19 | 20 | - [x] Parameterized query method 21 | - [x] Select method test 22 | - [x] Insert method test 23 | - [x] Update method test 24 | - [x] Delete method test 25 | - [x] Drop method test 26 | - [x] Join method test 27 | 28 | ### Select test file is completed. Testing includes the following: 29 | 30 | Invoke `deno test --allow-net --allow-read --unstable ./test-suite/select-test.ts` in your terminal. Make sure to check deno version to be latest version to run the test. 31 | 32 | - [x] Query Validation test 33 | - [x] Single-column query test 34 | - [x] Multiple-column query test 35 | - [x] The whole table select query test 36 | - [x] Multiple actions validation test 37 | 38 | ### Insert test file is completed. Testing includes the following: 39 | 40 | Invoke `deno test --allow-net --allow-read --unstable ./test-suite/insert-test.ts` in your terminal. Make sure to check deno version to be latest version to run the test. 41 | 42 | - [x] Query Validation test 43 | - [x] Single-row query test 44 | - [x] Multiple-rows query test 45 | 46 | ### Update test file is completed. Testing includes the following: 47 | 48 | Invoke `deno test --allow-net --allow-read --unstable ./test-suite/update-test.ts` in your terminal. Make sure to check deno version to be latest version to run the test. 49 | 50 | - [x] Single-row query test 51 | - [x] Multiple-rows query test 52 | - [x] The whole table update query test 53 | 54 | ### Delete test file is completed. Testing includes the following: 55 | 56 | Invoke `deno test --allow-net --allow-read --unstable ./test-suite/delete-test.ts` in your terminal. Make sure to check deno version to be latest version to run the test. 57 | 58 | - [x] Query Validation test 59 | - [x] Single-row delete query test 60 | - [x] Multiple-rows delete query test 61 | - [x] Delete all rows using dorm.delete() test 62 | 63 | ### Drop test file is completed. Testing includes the following: 64 | 65 | Invoke `deno test --allow-net --allow-read --unstable ./test-suite/drop-test.ts` in your terminal. Make sure to check deno version to be latest version to run the test. 66 | 67 | - [x] Query Validation test 68 | 69 | ### Join test file is completed. Testing includes the following: 70 | 71 | Invoke `deno test --allow-net --allow-read --unstable ./test-suite/join-test.ts` in your terminal. Make sure to check deno version to be latest version to run the test. 72 | 73 | - [x] Two table Join test 74 | - [x] Multiple-tables Join test 75 | - [x] Without on condition test 76 | - [x] Flexiblity Test 77 | -------------------------------------------------------------------------------- /test-suite/update-test.ts: -------------------------------------------------------------------------------- 1 | import { Dorm } from '../lib/query-builder.ts'; 2 | import { assertEquals, assertNotEquals } from '../deps.ts'; 3 | import { config } from '../deps.ts'; 4 | 5 | /* 6 | *@select 7 | *Invalid 8 | *Testing for UPDATE method 9 | *Single row updating 10 | *Multiple rows updating 11 | *All rows updating (the whole table update) 12 | */ 13 | 14 | /*-------- CONNECTING TO THE DATABASE --------*/ 15 | 16 | const env = config(); 17 | // create .env file and add your database inside it. using followin variables USERNAME, PASSWORD, SERVER 18 | const URL = `postgres://${env.USERNAME}:${env.PASSWORD}@${env.SERVER}:5432/${env.USERNAME}`; 19 | 20 | const database = URL; // Or you can add your url here 21 | const dorm = new Dorm(database); 22 | 23 | /*------------ CREATING TESTING ID------------*/ 24 | var updateId = 2; 25 | 26 | /* -------------------------------------------------------------------------- */ 27 | /* SINGLE ROW QUERY IN UPDATE METHOD */ 28 | /* -------------------------------------------------------------------------- */ 29 | 30 | const updateQuery = await dorm 31 | .update({'username':'updatedDogs', 'email': 'updated@dogs.com'}) 32 | .where(`_id = ${updateId}`) 33 | .table('dropthis') 34 | .returning() 35 | .then((data: any) => { 36 | return data.rows; 37 | }) 38 | .catch((e:any) => e); 39 | 40 | 41 | 42 | 43 | Deno.test(`a single-row query in "UPDATE" method:`, () => { 44 | const test = dorm.update({'username':'newDogs', 'password': 'iLoveDogs'}).where(`user_id = ${updateId+1}`) 45 | .from('userprofile') .returning(); 46 | 47 | assertEquals(updateQuery, [] , 'Error: the method should work more than one row'); 48 | assertEquals(test.info.action.type , 'UPDATE', 'Error:Type is not updated to UPDATE'); 49 | assertEquals(test.info.action.table , 'userprofile', 'Error:Table is not updated to userprofile'); 50 | assertEquals(test.info.returning.active , true, 'Error:Returning is not updated'); 51 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 52 | 53 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 54 | 55 | test.toString(); 56 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 57 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 58 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 59 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 60 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 61 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 62 | }); 63 | 64 | 65 | /* -------------------------------------------------------------------------- */ 66 | /* MULTIPLE ROWS QUERY IN UPDATE METHOD */ 67 | /* -------------------------------------------------------------------------- */ 68 | 69 | 70 | const multipleRowsQuery = await dorm 71 | .update({'username':'Dogs', 'email': 'iamnotagooddog@dogs.com'}) 72 | .table('dropthis') 73 | .where(`_id < ${updateId}`) 74 | .returning() 75 | .then((data: any) => { 76 | return data.rows; 77 | }).catch((e:any) => e); 78 | 79 | console.log('multipleRowsQuery:', multipleRowsQuery) 80 | 81 | Deno.test(`multiple-rows query in "UPDATE" method:`, () => { 82 | const test = dorm 83 | .update({'username':'Dogs', 'password': 'ihave8Dogs'}) 84 | .where(`user_id <= ${updateId}`) 85 | .table('userprofile') 86 | .returning(); 87 | assertEquals(Array.isArray(multipleRowsQuery), true, `Error:${updateId} rows was not updated `); 88 | assertEquals(test.info.action.type , 'UPDATE', 'Error:Type is not updated to UPDATE'); 89 | assertEquals(test.info.action.table , 'userprofile', 'Error:Table is not updated to userprofile'); 90 | assertEquals(test.info.returning.active , true, 'Error:Returning is not updated'); 91 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 92 | 93 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 94 | 95 | const testQuery = test.toString(); 96 | assertEquals(testQuery , `UPDATE userprofile SET username = $1, password = $2 WHERE user_id < = $3 RETURNING *`, 'Error:Querybuilder is returning unparametrized query string!!'); 97 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 98 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 99 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 100 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 101 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 102 | }); 103 | 104 | /* -------------------------------------------------------------------------- */ 105 | /* ALL ROWS TO BE UPDATED USING UPDATE METHOD */ 106 | /* -------------------------------------------------------------------------- */ 107 | 108 | const allRowsUpdateQuery = await dorm 109 | .update({'username':'restarted', 'email': 'iamagoodcat@cats.com'}) 110 | .table('dropthis') 111 | .returning() 112 | .then((data: any) => { 113 | return data.rows; 114 | }).catch((e:any) => e); 115 | 116 | 117 | Deno.test(`all rows query in "UPDATE" method:`, () => { 118 | const test = dorm.update({'username':'restarted', 'password': 'iamADog'}) 119 | .from('userprofile') 120 | .returning('username'); 121 | assertEquals(Array.isArray(allRowsUpdateQuery), true,'Error:The whole table was not updated'); 122 | assertEquals(test.info.action.type , 'UPDATE', 'Error:Type is not updated to UPDATE'); 123 | assertEquals(test.info.action.table , 'userprofile', 'Error:Table is not updated to userprofile'); 124 | assertEquals(test.info.returning.active , true, 'Error:Returning is not updated'); 125 | assertEquals(test.info.returning.columns , 'username', 'Error:Columns in Returning is not reset'); 126 | 127 | /* ------------------------ RESETTING INITIAL VALUES ------------------------ */ 128 | 129 | const testQuery = test.toString(); 130 | assertEquals(testQuery , `UPDATE userprofile SET username = $1, password = $2 RETURNING username`, 'Error:Querybuilder is returning unparametrized query string!!'); 131 | assertEquals(test.info.action.type , null, 'Error:Type is not reset'); 132 | assertEquals(test.info.action.columns , '*', 'Error:Columns are not reset'); 133 | assertEquals(test.info.action.values , [], 'Error:Values are not reset'); 134 | assertEquals(test.info.action.table , null, 'Error:Table is not reset'); 135 | assertEquals(test.info.returning.active , false, 'Error:Returning is not reset'); 136 | assertEquals(test.info.returning.columns , '*', 'Error:Columns in Returning is not reset'); 137 | }); 138 | --------------------------------------------------------------------------------