Skip to content

Commit

Permalink
Rewrote the API to use classes as the basis for instances
Browse files Browse the repository at this point in the history
This actually is a far bigger deal than it sounds like - it means that
you can provide your own instance implementation (or even just settle
for passing through the documents if you like) rather than relying on
our own one. Customizability here we come!
  • Loading branch information
notheotherben committed Apr 21, 2015
1 parent 1d18897 commit b757f4a
Show file tree
Hide file tree
Showing 17 changed files with 653 additions and 153 deletions.
36 changes: 17 additions & 19 deletions Iridium.njsproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,28 +48,25 @@
<TypeScriptCompile Include="lib\Plugins.ts" />
<TypeScriptCompile Include="lib\Schema.ts" />
<Content Include="test\mocha.opts" />
<Compile Include="test\bugs.js" />
<Compile Include="test\cache.js" />
<Compile Include="test\callbacks.js" />
<Compile Include="test\diff.js" />
<Compile Include="test\find.js" />
<Compile Include="test\findOne.js" />
<Compile Include="test\hooks.js" />
<Compile Include="test\insertion.js" />
<Compile Include="test\instance_db.js" />
<Compile Include="test\instance_helpers.js" />
<Compile Include="test\instance_setup.js" />
<Compile Include="test\model.js" />
<Compile Include="test\plugins.js" />
<TypeScriptCompile Include="test\Core.ts">
<SubType>Code</SubType>
<TestFramework>Mocha</TestFramework>
</TypeScriptCompile>
<TypeScriptCompile Include="test\Iridium.ts" />
<TypeScriptCompile Include="test\support\chai.ts" />
<TypeScriptCompile Include="_references.d.ts" />
<TypeScriptCompile Include="typings\chai-as-promised\chai-as-promised.d.ts" />
<TypeScriptCompile Include="typings\chai-fuzzy\chai-fuzzy.d.ts" />
<TypeScriptCompile Include="typings\chai\chai.d.ts" />
<TypeScriptCompile Include="typings\mocha\mocha.d.ts" />
<TypeScriptCompile Include="typings\tsd.d.ts" />
<TypeScriptCompile Include="lib\cacheControllers\IDDirector.ts" />
<TypeScriptCompile Include="lib\caches\MemoryCache.ts" />
<TypeScriptCompile Include="lib\caches\NoOpCache.ts" />
<TypeScriptCompile Include="lib\middleware\Express.ts" />
<TypeScriptCompile Include="lib\utils\Omnom.ts" />
<Content Include="test\support\config.json" />
<Compile Include="test\support\chai.js" />
<Compile Include="test\support\config.js" />
<Compile Include="test\support\config.ts" />
<TypeScriptCompile Include="typings\bluebird\bluebird.d.ts" />
<TypeScriptCompile Include="typings\concoction\concoction.d.ts" />
<TypeScriptCompile Include="typings\lodash\lodash.d.ts" />
Expand All @@ -79,30 +76,31 @@
</ItemGroup>
<ItemGroup>
<Folder Include="benchmarks" />
<Folder Include="dist\js\" />
<Folder Include="doc" />
<Folder Include="example" />
<Folder Include="lib" />
<Folder Include="lib\cacheControllers" />
<Folder Include="lib\caches" />
<Folder Include="lib\middleware" />
<Folder Include="lib\utils" />
<Folder Include="dist\" />
<Folder Include="test" />
<Folder Include="test\support" />
<Folder Include="typings" />
<Folder Include="typings\bluebird" />
<Folder Include="typings\chai-as-promised\" />
<Folder Include="typings\chai-fuzzy\" />
<Folder Include="typings\chai\" />
<Folder Include="typings\concoction" />
<Folder Include="typings\lodash" />
<Folder Include="typings\mocha\" />
<Folder Include="typings\mongodb" />
<Folder Include="typings\node" />
<Folder Include="typings\skmatc" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<!--Do not delete the following Import Project. While this appears to do nothing it is a marker for setting TypeScript properties before our import that depends on them.-->
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<TypeScriptGeneratesDeclarations>True</TypeScriptGeneratesDeclarations>
<TypeScriptOutDir>dist/js</TypeScriptOutDir>
<TypeScriptGeneratesDeclarations>False</TypeScriptGeneratesDeclarations>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="False" />
<Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsTools.targets" />
Expand Down
10 changes: 10 additions & 0 deletions _references.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/// <reference path="./typings/node/node.d.ts" />
/// <reference path="./typings/bluebird/bluebird.d.ts" />
/// <reference path="./typings/concoction/concoction.d.ts" />
/// <reference path="./typings/lodash/lodash.d.ts" />
/// <reference path="./typings/skmatc/skmatc.d.ts" />
/// <reference path="./typings/mongodb/mongodb.d.ts" />
/// <reference path="./typings/mocha/mocha.d.ts" />
/// <reference path="./typings/chai/chai.d.ts" />
/// <reference path="./typings/chai-fuzzy/chai-fuzzy.d.ts" />
/// <reference path="./typings/chai-as-promised/chai-as-promised.d.ts" />
42 changes: 33 additions & 9 deletions example/IntelliSense.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,49 @@

import Iridium = require('../index');
import Instance = require('../lib/Instance');

interface UserDoc {
username: string;
fullname: string;
email: string;
dateOfBirth: Date;
passwordHash: string;
}

interface IUser {
class User extends Iridium.Instance<UserDoc, User> implements UserDoc {
username: string;
fullname: string;
email: string;
dateOfBirth: Date;
passwordHash: string;

changePassword(newPassword: string) {
this.passwordHash = newPassword.toLowerCase();
}
}

interface IUserInstance extends IUser, Instance.IInstance<IUser, IUserInstance> {}
class MyDB extends Iridium.Core {
Users = new Iridium.Model<UserDoc, User>(this, User, "users", {
username: /^[a-z][a-z0-9_]{7,}$/,
fullname: String,
email: String,
dateOfBirth: Date,
passwordHash: String
}, {
indexes: [
{ email: 1 }
]
});

class MyDB extends Iridium {
Users = new Iridium.Model<IUser, IUserInstance>(this, "users", {
PlainUsers = new Iridium.Model<UserDoc, UserDoc>(this,(doc) => doc, "users", {
username: /^[a-z][a-z0-9_]{7,}$/,
fullname: String,
email: String,
dateOfBirth: Date,
passwordHash: String
}, {
indexes: [
{ email: 1 }
]
indexes: [
{ email: 1 }
]
});
}

Expand All @@ -39,7 +59,7 @@ db.connect().then(function () {
users[0].fullname;
});

db.Users.findOne().then(function (instance: IUserInstance) {
db.Users.findOne().then(function (instance) {
instance.save().then(function (i) {
i.remove().then(function (i) {
i.username = 'test';
Expand All @@ -51,4 +71,8 @@ db.connect().then(function () {
db.Users.count().then(function (count) {
count.toPrecision(2);
});

db.PlainUsers.get().then(function (plainUser) {
plainUser.username;
});
});
4 changes: 3 additions & 1 deletion lib/Configuration.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export interface Configuration {
export = Configuration;

interface Configuration {
host?: string;
port?: number;
database?: string;
Expand Down
82 changes: 30 additions & 52 deletions lib/Core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,17 @@ var MongoConnectAsyc = Promise.promisify(MongoDB.MongoClient.connect);
export = Core;

class Core {
private _models: { [key:string]:model.IModel<any, any>};
private _plugins: [IPlugin];
private _plugins: IPlugin[] = [];
private _url: string;
private _config: config.Configuration;
private _config: config;
private _connection: MongoDB.Db;
private _cache: cache = new noOpCache();

/**
* Gets the models registered with this Iridium Core
* @returns {{}}
*/
get models(): { [key:string]:model.IModel<any, any> } {
return this._models;
}


/**
* Gets the plugins registered with this Iridium Core
* @returns {[Iridium.Plugin]}
*/
get plugins(): [IPlugin] {
get plugins(): IPlugin[] {
return this._plugins;
}

Expand All @@ -56,7 +47,7 @@ class Core {
* Iridium Core.
* @returns {Iridium.Configuration}
*/
get settings(): config.Configuration {
get settings(): config {
return this._config;
}

Expand All @@ -76,10 +67,20 @@ class Core {
get url(): string {
if (this._url) return this._url;
var url: string = 'mongodb://';

if (this._config.username) {
url += this._config.username;
if (this._config.password)
url += ':' + this._config.password;
url += '@';
}

url += (this._config.host || 'localhost');
if (this._config.port)
url += ':' + this._config.port;

url += '/' + this._config.database;

return url;
}

Expand All @@ -94,27 +95,34 @@ class Core {
set cache(value: cache) {
this._cache = value;
}


/**
* Creates a new Iridium Core instance connected to the specified MongoDB instance
* @param {Iridium.IridiumConfiguration} config The config object defining the database to connect to
* @constructs Core
*/
constructor(config: config);
/**
* Creates a new Iridium Core instance connected to the specified MongoDB instance
* @param {String} url The URL of the MongoDB instance to connect to
* @param {Iridium.IridiumConfiguration} config The config object made available as settings
* @constructs Core
*/
constructor(url?: string, config?: config.Configuration) {
constructor(uri: string, config?: config);
constructor(uri: string | config, config?: config) {

var args = Array.prototype.slice.call(arguments, 0);
url = config = null;
uri = config = null;
for(var i = 0; i < args.length; i++) {
if(typeof args[i] == 'string')
url = args[i];
uri = args[i];
else if(typeof args[i] == 'object')
config = args[i];
}

if(!url && !config) throw new Error("Expected either a URI or config object to be supplied when initializing Iridium");
if(!uri && !config) throw new Error("Expected either a URI or config object to be supplied when initializing Iridium");

this._url = url;
this._url = <string>uri;
this._config = config;
}

Expand All @@ -123,38 +131,8 @@ class Core {
* @param {Iridium.Plugin} plugin The plugin to register with this Iridium Core
* @returns {Iridium.Core}
*/
register(plugin: IPlugin): Core;

/**
* Registers a new model with this Iridium Core
* @param {String} name The name which this model will be registered with
* @param {Iridium.Model} model The instantiated model to register on this Iridium Core
* @returns {Iridium.Core}
*/
register<TSchema, TInstance extends instance.IInstance<any, any>>(name: string, model: model.IModel<TSchema, TInstance>): Core;

/**
* Registers a new model with this Iridium Core
* @param {String} name The name which this model will be registered with
* @param {Iridium.ModelFactory} modelFactory The factory responsible for creating the model to register on this Iridium Core
* @returns {Iridium.Core}
*/
register<TSchema, TInstance extends instance.IInstance<any, any>>(name: string, modelFactory: model.IModelFactory<TSchema, TInstance>): Core;

register(arg0: any, arg1?: any): Core {
if (typeof arg0 == 'object') {
this.plugins.push(arg0);
return this;
}

if (arg1.isModel) this.models[arg0] = arg1;
else this.models[arg0] = arg1(this);
Object.defineProperty(this, arg0, {
get: function () {
return this.models[arg0];
},
enumerable: false
});
register(plugin: IPlugin): Core {
this.plugins.push(plugin);
return this;
}

Expand Down
13 changes: 13 additions & 0 deletions lib/General.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,17 @@ export interface Callback<T> {

export interface Predicate<T> {
(object: T, key?: string): boolean;
}

export interface PropertyGetter<T> {
(): T;
}

export interface PropertySetter<T> {
(value: T): void;
}

export interface Property<T> {
get?: PropertyGetter<T>;
set?: PropertySetter<T>;
}
10 changes: 5 additions & 5 deletions lib/Hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import instance = require('./Instance');

export interface IHooks<TSchema> {
creating?(document: any);
retrieved?(document: any);
ready?(instance: instance.IInstance<any, any> | any);
beforeSave?(instance: instance.IInstance<any, any>);
export interface IHooks<TDocument, TInstance> {
creating? (document: TDocument);
retrieved? (document: TDocument);
ready? (instance: TInstance);
beforeSave? (instance: TInstance);
}

0 comments on commit b757f4a

Please sign in to comment.