Skip to content

Latest commit

 

History

History
152 lines (121 loc) · 7.9 KB

developerReadMe.md

File metadata and controls

152 lines (121 loc) · 7.9 KB

A Message for Future DenoGres Developers

Application Overview

Welcome to Denogres-4.0! Denogres is split into two main parts--the first being a PostgreSQL ORM for Deno and the second being a database visualization tool. You are currently in the repository for the Denogres-4.0 ORM. Within this repository is a sub-repository for the Denogres-3.0 GUI, which is not deployed. Here is the link for the repository for Denogres's currently deployed GUI, along with the website holding documentation for how to use the ORM.

We, the Denogres-4.0 team, focused our efforts on improving the ORM. We were unable to deploy the Denogres-3.0 GUI (written with React) in part because of compatibility issues between Deno, Vite, and Reactflow. Instead, we took the route of adding features to the Denogres-2.0 GUI and site (written with Fresh) taking Denogres 3.0's improvements as inspiration. Future iterators may decide to continue this work or deploy Denogres 3.0, in which case you'll find a more detailed readme in the denogres-gui directory in this respository.

Getting Started

Most of the code for the ORM can be found in the root directory and src directory. In the root directory, you'll find a mod.ts file that defines the behavior of the Denogres CLI (including denogres --init, --db-pull, etc.), as well as a deps.ts file where, following Deno best practices, we've imported and exported all dependencies for the rest of the application.

In the src directory, the class directory contains a crucial file, Model.ts, which defines the Model class from which all users' models are extended and therefore the main functionality of the ORM. Association.ts defines classes that establish relationships between tables, instantiated by methods on the Model class. For more detailed information on how all these methods work, there is a Model.md file in that directory as well.

Within the src directory, the functions directory contains most of the functionality for mod.ts. Including, most notibly, Db.ts, introspect.ts, dbPull.ts, and init.ts. Comments were left inside of these files to help future iterators quickly integtrate into the codebase.

Finally, the Test directory contains both new and existing unit and integration tests for the ORM. Running deno task test in the terminal will run all tests. Two of the most useful tests to run when adding features to the ORM may be model_test.ts, which contains unit tests for all Model methods, and model_integration_test.ts (in its own subdirectory).

In order to (locally) test any of the functionality related to database connection (including model integration tests), you'll need to create a .env file in the root directory with ENVIRONMENT (set to test for testing) and TEST_DB_URI set to an empty database (running in ElephantSQL or locally). Note that your test database will be torn down after running tests.

CI/CD

In order to establish a CI/CD pipeline using Github Actions, there is a .github directory with a development.yaml file, which defines steps to be run automatically by Github anytime a PR is made into the dev or main branches. These tests won't pass if deno fmt hasn't been run or if any of the tests in model_test.ts or model_integration_tests.ts fail. Note that in order to connect to a test database during CI/CD, a Docker service container is set up hosting a PostgreSQL instance (no need to connect your own db for this step).

Vendor & Import Map

What is vendor

The deno vendor built in tool is used to install all the src code of third party dependencies into a vendor directory. This improves security because now we can run Denogres with the flag --no-remote (disables fetching of remote dependencies) and we are free to edit the src code of vendored dependencies. Storing the src code of dependencies in the project directly like this comes with another security benefit, that the src code of the dependency is editable by the Denogres team. So if future teams discover vulnerabilities or bugs within dependencies, they can apply a monkey patch to the dependency instead of waiting for upstream changes by the development team behind the dependency.

How it is used in Denogres

The way the dependencies are currently imported throughout the application is that in the vendor folder, there is an import_map.json which is used as the entrypoint into the vendor folder. To access this entrypoint, "importMap": "./vendor/import_map.json" is added to the deno.json so Deno knows to look for imported dependencies from vendor. One caveat is that once vendor is used for third party dependencies, all dependencies necessary in the application need to be found in vendor. So in order to include new dependencies into the project, we have been rerunning the deno vendor with the --force flag which will overwrite the old content in vendor in case of file conflicts. For example if vendor didn't include https://deno.land/[email protected]/io/buffer.ts and https://deno.land/x/[email protected]/load.ts, to add both to vendor you would need to run:

deno vendor https://deno.land/[email protected]/io/buffer.ts https://deno.land/x/[email protected]/load.ts --force

As you can see deno vendor can take multiple command-line arguments which can either be a local file (deps.ts is the only file included because most of our dependencies are exported from that file to the rest of our application) or a url to where the dependency is hosted online. We opted for manually importing the rest of the url's instead of adding it to the deps.ts file because either the dependency relied on another dependency or the dependency when imported just imported the file (ex from ./Test/dbPing_test.ts : import 'https://deno.land/x/[email protected]/load.ts';).

troubleshooting vendor issues

If vendor is giving issues that cannot be solved immediately, removing "importMap": "./vendor/import_map.json" line in deno.json will disable vendor and dependency resolution will revert to Deno defaults.

It may be useful to regenerate the entire vendor directory (should not be done if it can be helped). The steps to do this with the current dependencies are:

  1. delete the vendor folder in the root directory and remove "importMap": "./vendor/import_map.json" from deno.json
  2. run this command in the terminal: deno vendor deps.ts https://deno.land/x/[email protected]/load.ts https://deno.land/[email protected]/node/module_all.ts

In-Progress

While testing was a main goal for Denogres-4.0, there is still room for improvement in fleshing out testing suites. In particular, outside of the unit and integration tests for the Model itself (see above), most other tests rely on functionality not being tested (for example, connecting to a database). These tests could be better isolated or replaced for more confidence.

Other ORM features still in progress include:

  • Adding a setter method to related models (see Association.ts)
  • Adding functionality to the manyToMany function to add a join table to the user's database (see the end of Model.ts)

To-Do

Here's a few ideas that could guide future iterators in development:

  • Parameterizing queries made by model methods for increased security
  • Finding a way to use Reactflow with Fresh, in order to create ERD diagrams for the user's database (this was done in Denogres-3.0 GUI at the expense of compatibility with Deno and Fresh)
  • Theoretically, it would be interesting to incorparate compatibility with other popular database management systems such as MySQL, but based on the structure of the model class (which uses Deno Postgres under the hood), this would be a large undertaking.

Deployment

The Denogres-2.0 GUI and documentation website/landing page are already deployed through Deno Deploy. Any changes made to the main branch of the DenoGres/Website repo (linked above) are automatically deployed.