Ponder v0.1.0 has been released, alpha version out now! Use at your own Discretion!
Ponder
the Ponder logo: the Deno dinosaur pondering in front of two databases

Welcome to the documentation for Ponder. Click on any section to jump to the documentation.

Table Of Contents

Intro

Ponder is an ORM for PostGres using the Deno runtime. It eliminates the need for developers to spend valuable time writing complex SQL queries.

Features

How to add to your Project

To use, please import the Ponder URI. You now have access to all the methods on the "ponder" object!
import * as ponder from "https://deno.land/x/ponder/";
Copied!

Getting Started

Deno CLI version 1.25.0 or higher is required. Install or update.

To include Ponder in your next project, add this dependency:

import * as ponder from "https://deno.land/x/ponder/mod.ts";
Copied!

You'll now be able to connect Ponder to your Database. First, store your Database URI in your .env file. Then pull it into your working file and store it.

const DB_URI = Deno.env.get('DB_URI');
Copied!

You can connect to your DB using the built-in poolConnection method:

const ponderDB1 = await ponder.poolConnection(DB_URI);
Copied!

Now you are now able to run any of the built in functions off the ponderDB1 variable:

const inserted = await ponderDB1.insertIntoTable('people', ['name', 'hair_color'], ['Corey', 'red-brown']);
Copied!

A more in-depth Getting Started guide is available in the docs.

Connecting Your Database

Create a new instance of poolConnection passing in the database connection string. By default, the number of pool connections is set to three and lazy loading is enabled. Users may also specify the number of server connections and whether the loading type is lazy.

import { poolConnection } from'./deps.ts
Copied!
With default three connections and lazy loading:
const ponder = new poolConnection('PG_URI')
Copied!
With five connections and lazy loading disabled:
const ponder = new poolConnection('PG_URI', 5, false)
Copied!

BasicCRUD

Find a Table

findAllinOne(table: string): returns all data from all rows of a table. Returns an array with an object containing all data on the 'people' table
const data = await ponder.findAllinOne('people');
Copied!

Find a Column in a Table

findColumn(column: string, table: string): returns a specific column from a specified table. Stores values from age column from the people table in the const data:
const data = await ponder.findColumn('age', 'people');
Copied!

Find a Row in a Table

findRow(table: string, attr: string, value: string): returns rows matching specific criteria. Stores values from rows in the people table where their hair is brown in the const data:
const data = await ponder.findRow('people', 'hair', 'brown');
Copied!

Find a Cell in a Table

findCell(table: string, column: string, value: string): returns data from the first row matching specific criteria.
ponder.findCell('people', 'name', 'corey');
Copied!

Add a Row to a Table

insertIntoTable(table: string, columns: string[], values: string[]): add a new row to an existing table. Example adds a row to people table with specified values.
ponder.insertIntoTable('people', ['name', 'hair'], ['Sam', 'red']);
Copied!

Update a Column in a Table

updateTable( table: string,
column_name: string[],
newValue: string[],
columnToMeet: string[],
valueToMeet: string[],
operator?: string );
Updates columns on existing table. The properties columnToMeet and valueToMeet create the conditional statement that must be satisfied before the table is updated. Please note that update table updates the first matching table entry. The operator parameter takes the argument of either "or" or "not." If left blank, the default is "and."
ponder.updateTable(people, [hair_color, eye_color], ['blonde', 'hazel'], [name, birth_year], ['Anton', '1860'], 'or');
Copied!

Delete a row on a Table

deleteRow(table: string, column: string[], value: string[]): remove an entire row of data from a table.
ponder.deleteRow(hair_color, ['blonde', 'pink'], ['Clementine']);
Copied!

ManagingTables

Create Table

createTable(tableName: string, columns: any): use this method to create new tables. This method will only return a message that your table is in the database. The first parameter is a string that you'd like to use for your Table Name. The second parameter is an object. Each key of the object is a name of a column on your new table. The value will be an array of strings, where the first element is the SQL datatype, the second element is the length(optional), and third and any other elements would be column constraints you'd like to add like NULL or NOT NULL, etc.
ponder.createTable('Cats', {
    id: ["SERIAL"]
    areCute: ["VARCHAR", "20", "NOT NULL"]
    }); 
Copied!

Drop One Table

dropOneTable(tableName: string, cascade?: boolean): Deletes an entire table. Optional boolean to include CASCADE command (default is RESTRICT).
ponder.dropOneTable('Cats', true);
Copied!

Drop Multiple Tables

dropMultipleTables(tableNamesArray : string[], cascade?: boolean): deletes multiple tables. Optional boolean to include CASCADE command (default is RESTRICT).
ponder.dropMultipleTables(['Cats', 'People'], true);
Copied!

Add Columns to an Existing Table

addColumns(tableToAlter : string, columns: any): Add one or more columns to an existing Table. The first parameter is a string of the Table Name you'd like to alter. The second parameter is an object. Each key of the object is a name of a column on your table. The value will be an array of strings, where the first element is the SQL datatype, the second element is the length(optional), and third and any other elements would be column constraints you'd like to add like NULL or NOT NULL, etc.
ponder.addColumns('programmers', {
    id: ["SERIAL"]
    howSmart: ["VARCHAR", "20", "NOT NULL"]
 });
Copied!

Drop Columns from a Table

dropColumns(tableName: string, columnsToDrop: any): Delete an entire column. The first argument is a string, the name of the table. The second argument is an object. The keys are the names of the columns you'd like to delete, the values are booleans (true for CASCADE, false for RESTRICT.)
ponder.dropColumns('programmers', columnsToDrop: {howSmart: true});
Copied!

Database Introspection

Ponder provides an introspect method to receive JavaScript representations of the data in your SQL Table. Because running the introspect method will create/write a new file in your file system, it is recommended to create a new file in your project root directory. Run this file using deno run to execute introspection. (If you keep your instrospect execution within another file, it may run repeated on the same database and will write unnecessary duplicates in your file system).
After importing ponder from your deps.ts file or from ponder directly, you'll need to first connect your database. After making a connection, all you need to do is invoke instrospect function:

ponder.introspect();
Copied!
You will see a new file called dataModels.ts in your root directory that contain models of your database tables!
For example the file might look like this: The class person extends Model and represents the "person" table in database:
import { Model } from './deps.ts' 

  export class person extends Model { 
  tableName = 'person' 
   static person_id = { 
      data_type: 'integer', 
      is_nullable: 'NO', 
      } 
   static name = { 
      data_type: 'character varying', 
      is_nullable: 'YES', 
      } 
   static hair_color = { 
      data_type: 'character varying', 
      is_nullable: 'YES', 
      } 
   static age = { 
      data_type: 'integer', 
      is_nullable: 'YES', 
      }  
    }
Copied!
Additionally, every class is accompanied with an interface.
export interface person { 
      name: string; 
      hair_color: string; 
      age: number; 
      height: number; 
      favorite_movie: string; 
      favorite_book: string; 
    } 
Copied!

Model Methods

Database introspection allows the user to interact with their database through object representations of the tables. Create an instance of the Model :
const newPerson = new person();
Copied!
Use dot notation to assign values to properties on new object. If the types are incorrect, or a value is added to a property that does not exist on model, an error will be thrown.
newPerson.name = 'Sara';
newPerson.hair_color = 'dark brown';
Copied!

Save new row to table

.save() After instantiating an instance of your model, invoke the .save() method on it to save it to you database. A new row will be added to the "person" table with the properties added above saved in their respective columns
newPerson.save();
Copied!

Update a row

.update() Note that once a primary key has been set, *you CANNOT update it* If you change properties on your instance and wish to update your database with the new values, invoke the .update() method. Change properties on instance:
newPerson.name = 'Johannes';
newPerson.hair_color = 'black';
newPerson.age = 22;
//Invoking update function makes these changes in database
newPerson.update();
    
Copied!

Search all entries in table

.search() Invoking .search() on an instance will return all the data from the table the instance is a part of. Stores all data from "people" table in variable:
newPerson.search();
Copied!

Delete from table

.delete() Deletes row from table:
newPerson.delete()
Copied!

Associations

Currently under development!

Ponder Command Line Interface (CLI)

Coming Soon! A feature for the future!

Making Contributions & Finding Bugs

To make contributions, create a fork of the dev branch. Please be sure to utilize the Deno Typescript linter. Ensure that any changes made are reflected in the documentation. Make a pull request to the Dev branch when you have finished making your changes, note that once submitted any changes made will be covered under the MIT license. Feel free to contact the maintainers with any questions or concerns.

Finding Bugs

If you come across any bugs or issues while using Ponder feel free to report by simply opening a new issue on our Github.

License

MIT License

Ponder

Copyright © 2022-2023 Corey McClendon-Brown, Stella Baek, Sara Brown, Sam Goldenberg, Matthew Connell

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About Ponder and its Creators

Matt Connell

Software Engineer

GitHub
LinkedIn

Sam Goldenberg

Software Engineer

GitHub
LinkedIn

Stella Baek

Software Engineer

GitHub
LinkedIn

Corey McClendon-Brown

Software Engineer

GitHub
LinkedIn

Sara Brown

Software Engineer


LinkedIn
Ponder
Simple ORM for PostGresSQL in Deno.
Community
Made by Ponder.