npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

sqliteorm

v0.0.1

Published

Another ORM for Node, supporting sqlite and postgres

Downloads

4

Readme

SQLiteORM

SQLiteORM is designed to be a database-agnostic ORM that interfaces nicely with various templating libraries and existing JavaScript code, with an eye towards being beautiful to read and write code for using CoffeeScript.

The API design is largely borrowed from Django's ORM; while not 100% similar the general theme should be familiar to anyone who has worked with Django before.

There are currently adapters for brianc's node-postgres and developmentseed's node-sqlite3.

What Does It Look Like?

The three major types of objects are namespaces (otherwise known as Scopes), Models, and QuerySets. Namespaces may contain one or more model definitions; these model definitions may refer to models from other namespaces. Namespaces are (currently) responsible for creation of database tables for their constituent models. The schema and metadata of a model may only be set within a namespace.

Let's take a look at what the average models.js file might look like:

var models = require('sqliteorm').models;

exports.ns = 
models.namespace('blog', function(ns) {
    var Post = ns.create('Post');

    Post.schema({
        // field definitions need not be explictly called,
        // uncalled fields will be instantiated with the default options.
        'title':models.CharField,
        'slug':models.CharField({regex:/^[\w\d\-_]*$/g, unique:true}),
        'pub_date':models.DateField({default:function() { return new Date(); }}),
        'description':models.TextField
    });

    Post.meta({
        'order_by':['-pub_date']
    });

    // models returned by `ns.create` are class constructor functions, just like in vanilla JS.
    // all instances of that model will have anything you throw onto their `prototype` available to them.
    Post.prototype.toString = function() {
        return '<Post: '+this.title+'>';
    };

    var Section = ns.create('Section');

    Section.schema({
        'post':models.ForeignKey(Post),
        'header':models.CharField({nullable:true, default:null}),
        'subhead':models.CharField({nullable:true, default:null}),
        'content':models.TextField,
        'ordering':models.PositiveIntegerField
    });

    Section.meta({
        'order_by':['ordering'],
        'unique_together':['ordering', 'post']
    });

    var Tag = ns.create('Tag');

    Tag.schema({
        'name':models.CharField({max_length:100}),
        'posts':models.ManyToMany(Post, {related_name:'tags'})
    });

    exports.Post = Post;
    exports.Section = Section;
    exports.Tag = Tag;
});

In this schema, a Post has many Sections, and Tags may be associated with many Posts. Note that models are just plain-old function constructors, like any JavaScript class. Also note that the namespace callback is executed immediately -- exporting models from within the namespace is encouraged. Outside of the namespace closure, the schema and meta methods will be unavailable and your models will be ready to use.

Querying Using Models

Building on the previous example, let's look at how we might query the above objects.

var models = require('./models'),
    Post = models.Post,
    Section = models.Section,
    Tag = models.Tag;

// Model classes are automatically assigned a `Manager` (available under 'Model._default_manager' as well as 'Model.objects') which is responsible for starting queries, like so:
_

// query all of the posts.
var posts = Post.objects.all()

// queries emit either 'data' or 'error', and nothing else.
// when 'data' is emitted, the query has completed.
posts.on('data', function(posts) {
    posts.forEach(function() {
        console.log('Got '+post);
    });
});

posts.on('error', function(err) {
    // handle your error, sir.
});

// you may also call posts as if it was a function taking a callback:
// no casting necessary.
posts(function(err, posts) {
    // do something with posts.
});

// you may filter on the fields available to 'post'.
// multiple arguments in one filter call will be 'AND'd together.
var other_posts = Post.objects.filter({title__contains:'something', slug:'something-else'});

// filters may be chained, and excluded.
// chained filters will be 'AND'd together as well.
// exclude will produce NOT(arg AND arg AND arg)
other_posts.filter({pub_date__lte:new Date()}).exclude({slug__startswith:'butts'});

// you may use a filter to delete objects as well:
other_posts.delete()

other_posts(function(err) {
    // if there's no 'err', your filter has run successfully
});

// if you only need one specific row, use 'get':

Post.objects.get({title:'something'})(function(err, post) {
    // if more than one 'Post' was returned, err will be an instance of Post.MultipleObjectsReturned.
    // if no 'Post's were returned, err will be an instance of Post.DoesNotExist, 

    // otherwise post will be a single Post object.

});


// creation is pretty easy as well:
var my_post = Post.objects.create({
    'title':'Introducing SQLiteORM',
    'slug':'introducing-sqliteorm',
    'pub_date':new Date(),
    'description':'SQLiteORM'
});

my_post.on('data', function(post) {
    // our post object exists!
});

// you may also use this format:
var post = new Post({
    'title':'Introducing SQLiteORM',
    'slug':'introducing-sqliteorm',
    'pub_date':new Date(),
    'description':'SQLiteORM'
});

post.save().on('data', function(post) {
    // my post!
});

// you may pass querysets to other querysets as arguments without waiting for them to return, as well:

section = Section.objects.create({
    'content':'whoa',
    'ordering':0,
    'post':Post.objects.create({
        'title':'Introducing SQLiteORM',
        'slug':'introducing-sqliteorm',
        'pub_date':new Date(),
        'description':'SQLiteORM'
    })
});

// errors from inner queries such as the above will be bubbled up through the 'section' queryset.

// you may query across related tables, as well:

section.objects.filter({post__title__contains:'hats'});

// or in reverse (the default reverse relation name is the name of the model with the foreign key, lowercased, plus '_set'):
Post.objects.filter({section_set__content:'whoa'});

// the above statement about being able to pass querysets applies to filtering, as well
Section.objects.filter({post:Post.objects.get({pk:3})})
Section.objects.filter({post__in:Post.objects.filter({title__contains:'something'})})

// related filtered works with M2M relations:
Tag.objects.filter({post__title:'Yeah!'})

// note that we configured the related name for Tags in the models above.
Post.objects.filter({tags__name__contains:'bowser'})

// filters may be limited and ordered:
// "give me three posts, ordered by title ASC, id DESC"
Post.objects.filter({pk:3}).order_by('title', '-id').limit(3)

// "give me 20 posts starting at 10."
Post.objects.filter({pk:3}).limit(10, 20);

Filters execute as soon as the current stack is exhausted.

License

new BSD