From 2f23ff4c610b8966c3eb98d77dca5d819a3fad82 Mon Sep 17 00:00:00 2001 From: David Fahlander Date: Wed, 9 Mar 2016 01:27:17 +0100 Subject: [PATCH] Updated to v1.3.1. --- dexie/dexie-tests.ts | 265 +++---------------------------------------- dexie/dexie.d.ts | 73 ++++++------ 2 files changed, 49 insertions(+), 289 deletions(-) diff --git a/dexie/dexie-tests.ts b/dexie/dexie-tests.ts index 79c5ff36a9..7eb6a75dbb 100644 --- a/dexie/dexie-tests.ts +++ b/dexie/dexie-tests.ts @@ -1,256 +1,25 @@ -/// - -import Dexie = require("dexie"); - -module Utils { - - export class Console { - textarea: HTMLTextAreaElement; - - constructor() { - this.textarea = document.createElement('textarea'); - } - - log(txt: string, type?: string) { - if (type) this.textarea.value += type + " "; - this.textarea.value += txt + "\n"; - } - error = function (txt: string) { - this.log(txt, "ERROR!"); - } - } +import Dexie from "dexie"; +interface IFriend { + id?: number, + name?: string, + age?: number } -module AppDb { - - export class AppDatabase extends Dexie { - - contacts: Dexie.Table; - emails: Dexie.Table; - phones: Dexie.Table; - - constructor() { - - super("MyTypeScriptAppDb"); - - var db = this; - - // - // Define tables and indexes - // - db.version(1).stores({ - contacts: '++id, first, last', - emails: '++id, contactId, type, email', - phones: '++id, contactId, type, phone', - }); - - // Let's physically map Contact class to contacts table. - // This will make it possible to call loadEmailsAndPhones() - // directly on retrieved database objects. - db.contacts.mapToClass(Contact); - } - } - - /* Just for code completion and compilation - defines - * the interface of objects stored in the emails table. - */ - export interface IEmailAddress { - id?: number; - contactId: number; - type: string; - email: string; - } - - /* Just for code completion and compilation - defines - * the interface of objects stored in the phones table. - */ - export interface IPhoneNumber { - id?: number; - contactId: number; - type: string; - phone: string; - } - - /* This is a 'physical' class that is mapped to - * the contacts table. We can have methods on it that - * we could call on retrieved database objects. - */ - export class Contact { - id: number; - first: string; - last: string; - emails: IEmailAddress[]; - phones: IPhoneNumber[]; - - constructor(first: string, last: string, id?: number) { - this.first = first; - this.last = last; - if (id) this.id = id; - } - - loadEmailsAndPhones() : Dexie.Promise { - return Dexie.Promise.all( - db.emails - .where('contactId').equals(this.id) - .toArray(emails => this.emails = emails) - , - db.phones - .where('contactId').equals(this.id) - .toArray(phones => this.phones = phones) - - ).then(() => this); - } - - save() { - return db.transaction('rw', db.contacts, db.emails, db.phones, () => { - Dexie.Promise.all( - // Save existing arrays - Dexie.Promise.all(this.emails.map(email => db.emails.put(email))), - Dexie.Promise.all(this.phones.map(phone => db.phones.put(phone)))) - .then(results => { - // Remove items from DB that is was not saved here: - var emailIds = results[0], // array of resulting primary keys - phoneIds = results[1]; // array of resulting primary keys - - db.emails.where('contactId').equals(this.id) - .and(email => emailIds.indexOf(email.id) === -1) - .delete(); - - db.phones.where('contactId').equals(this.id) - .and(phone => phoneIds.indexOf(phone.id) === -1) - .delete(); - - // At last, save our own properties. - // (Must not do put(this) because we would get - // reduntant emails/phones arrays saved into db) - db.contacts.put( - new Contact(this.first, this.last, this.id)) - .then(id => this.id = id); - }); - }); - } - } - - export var db = new AppDatabase(); - db.open(); -} - - -import Console = Utils.Console; -import db = AppDb.db; - -document.addEventListener('DOMContentLoaded', () => { - - // Initialize our Console widget - it will log browser window. - var console = new Console(); - document.getElementById('consoleArea').appendChild(console.textarea); - - // Test it: - console.log("Hello world!"); - - // Make sure to never miss any unexpected error: - Dexie.Promise.on.error.subscribe(e => { - // Log any uncatched error: - console.error(e); - }); - - // - // Let's clear and re-seed the database: - // - clearDatabase() - .then(seedDatabase) - .then(playALittle_add_phone_to_adam) - .then(printContacts); - - function clearDatabase() { - console.log("Clearing database..."); - return Dexie.Promise.all( - db.contacts.clear(), - db.emails.clear(), - db.phones.clear()); - } - - function seedDatabase() { - console.log("Seeding database with some contacts..."); - return db.transaction('rw', db.contacts, db.emails, db.phones, () => { - // Populate a contact - db.contacts.add(new AppDb.Contact('Arnold', 'Fitzgerald')).then(id => { - // Populate some emails and phone numbers for the contact - db.emails.add({ contactId: id, type: 'home', email: 'arnold@email.com' }); - db.emails.add({ contactId: id, type: 'work', email: 'arnold@abc.com' }); - db.phones.add({ contactId: id, type: 'home', phone: '12345678' }); - db.phones.add({ contactId: id, type: 'work', phone: '987654321' }); - }); - - // ... and another one... - db.contacts.add(new AppDb.Contact('Adam', 'Tensta')).then(id => { - // Populate some emails and phone numbers for the contact - db.emails.add({ contactId: id, type: 'home', email: 'adam@tensta.se' }); - db.phones.add({ contactId: id, type: 'work', phone: '88888888' }); - }); +class MyDB extends Dexie { + friends: Dexie.Table; + constructor() { + super("MyDB"); + this.version(1).stores({ + friends: "++id,name,age" }); } +} - function playALittle_add_phone_to_adam() { - // Now, just to examplify how to use the save() method as an alternative - // to db.phones.add(), we will add yet another phone number - // to an existing contact and then re-save it: - console.log("Playing a little: adding another phone entry for Adam Tensta..."); - return db.contacts - .where('last').equals('Tensta').first(c => c.loadEmailsAndPhones()) - .then(contact => { - // Also add another phone number to Adam Tensta: - contact.phones.push({ - contactId: contact.id, - type: 'custom', - phone: '112' - }); - contact.save(); - }); - } +var db = new MyDB(); - function printContacts() { - - // Now we're gonna list all contacts starting with letter 'A' - // and print them out. - // For each contact, also resolve its collection of - // phone number entries and email addresses by reverse-quering - // the foreign tables. - - // For atomicity and speed, use a single transaction for the - // queries to make: - db.transaction('r', [db.contacts, db.phones, db.emails], () => { - - // Query some contacts - return db.contacts - .where('first').startsWithIgnoreCase('a') - .sortBy('id') - .then(contacts => - - // Resolve array properties 'emails' and 'phones' - // on each and every contact: - Dexie.Promise.all( - contacts.map(contact => - contact.loadEmailsAndPhones())) - ); - - }).then(contacts => { - - // Print result - console.log("Database contains the following contacts:"); - contacts.forEach(contact => { - console.log(contact.id + ". " + contact.first + " " + contact.last); - console.log(" Phone numbers: "); - contact.phones.forEach(phone => { - console.log(" " + phone.phone + "(" + phone.type + ")"); - }); - console.log(" Emails: "); - contact.emails.forEach(email => { - console.log(" " + email.email + "(" + email.type + ")"); - }); - }); - }); - } +db.friends.add({name: "Kalle", age: 23}).then(()=>{ + db.friends.where('age').below(30).count(count => { + console.log("Num yound friends: " + count); + }); }); - diff --git a/dexie/dexie.d.ts b/dexie/dexie.d.ts index 2220bac56d..34fedad062 100644 --- a/dexie/dexie.d.ts +++ b/dexie/dexie.d.ts @@ -1,7 +1,7 @@ -// Type definitions for Dexie v1.2 +// Type definitions for Dexie 1.3.1 // Project: https://github.com/dfahlander/Dexie.js // Definitions by: David Fahlander -// Definitions: https://github.com/borisyankov/DefinitelyTyped +// Date Wed Mar 09 2016 interface Thenable { then(onFulfilled: (value: R) => Thenable, onRejected: (error: any) => Thenable): Thenable; @@ -10,6 +10,8 @@ interface Thenable { then(onFulfilled?: (value: R) => U, onRejected?: (error: any) => U): Thenable; } +declare type IndexableType = string | number | Date | Array; + declare class Dexie { constructor(databaseName: string); @@ -38,7 +40,7 @@ declare class Dexie { static deepClone(obj: Object): Object; - version(versionNumber: number): Dexie.Version; + version(versionNumber: Number): Dexie.Version on: { (eventName: string, subscriber: () => any): void; @@ -48,7 +50,7 @@ declare class Dexie { populate: Dexie.DexieEvent; blocked: Dexie.DexieEvent; versionchange: Dexie.DexieVersionChangeEvent; - }; + } open(): Dexie.Promise; @@ -103,13 +105,19 @@ declare module Dexie { then(onFulfilled: (value: R) => U, onRejected: (error: any) => Thenable): Promise; then(onFulfilled?: (value: R) => U, onRejected?: (error: any) => U): Promise; - - catch(onRejected: (error: any) => Promise): Promise; - + + catch(onRejected: (error: any) => Thenable): Promise; + + catch(onRejected: (error: any) => U): Promise; + catch(ExceptionType: Function, onRejected: (error: any) => Promise): Promise; + catch(ExceptionType: Function, onRejected: (error: any) => U): Promise; + catch(errorName: string, onRejected: (error: any) => Promise): Promise; + catch(errorName: string, onRejected: (error: any) => U): Promise; + finally(onFinally: () => any): Promise; onuncatched: () => any; @@ -229,42 +237,26 @@ declare module Dexie { } interface WhereClause { - above(key: number): Collection; - above(key: string): Collection; - above(key: Date): Collection; - above(key: Array): Collection; - aboveOrEqual(key: number): Collection; - aboveOrEqual(key: string): Collection; - aboveOrEqual(key: Date): Collection; - aboveOrEqual(key: Array): Collection; - anyOf(keys: Array): Collection; - anyOf(...keys: any[]): Collection; - below(key: number): Collection; - below(key: string): Collection; - below(key: Date): Collection; - below(key: Array): Collection; - belowOrEqual(key: number): Collection; - belowOrEqual(key: string): Collection; - belowOrEqual(key: Date): Collection; - belowOrEqual(key: Array): Collection; - between(lower: number, upper: number, includeLower?: boolean, includeUpper?: boolean): Collection; - between(lower: string, upper: string, includeLower?: boolean, includeUpper?: boolean): Collection; - between(lower: Date, upper: Date, includeLower?: boolean, includeUpper?: boolean): Collection; - between(lower: Array, upper: Array, includeLower?: boolean, includeUpper?: boolean): Collection; - equals(key: number): Collection; - equals(key: string): Collection; - equals(key: Date): Collection; - equals(key: Array): Collection; + above(key: IndexableType): Collection; + aboveOrEqual(key: IndexableType): Collection; + anyOf(keys: IndexableType[]): Collection; + anyOf(...keys: IndexableType[]): Collection; + anyOfIgnoreCase(keys: string[]): Collection; + anyOfIgnoreCase(...keys: string[]): Collection; + below(key: IndexableType): Collection; + belowOrEqual(key: IndexableType): Collection; + between(lower: IndexableType, upper: IndexableType, includeLower?: boolean, includeUpper?: boolean): Collection; + equals(key: IndexableType): Collection; equalsIgnoreCase(key: string): Collection; + inAnyRange(ranges: Array): Collection; startsWith(key: string): Collection; startsWithAnyOf(prefixes: string[]): Collection; startsWithAnyOf(...prefixes: string[]): Collection; startsWithIgnoreCase(key: string): Collection; - noneOf(keys: Array): Collection; - notEqual(key: number): Collection; - notEqual(key: string): Collection; - notEqual(key: Date): Collection; - notEqual(key: Array): Collection; + startsWithAnyOfIgnoreCase(prefixes: string[]): Collection; + startsWithAnyOfIgnoreCase(...prefixes: string[]): Collection; + noneOf(keys: Array): Collection; + notEqual(key: IndexableType): Collection; } interface Collection { @@ -323,6 +315,5 @@ declare module Dexie { } } -declare module 'dexie' { - export = Dexie; -} +export default Dexie; +