jrwalt4 / arga Goto Github PK
View Code? Open in Web Editor NEWA JavaScript implementation of the ADO.NET DataSet pattern
License: MIT License
A JavaScript implementation of the ADO.NET DataSet pattern
License: MIT License
namespace arga {
namespace row {
export interface DataRowPublic {
get(key: string): any
set(key: string, value: any): boolean
acceptChanges(): boolean
}
export interface DataRowPublicConstructor {
new (): DataRowPublic
typeName:string
}
export interface DataRowInternal extends DataRowPublic {
_id:string
}
export interface DataRowInternalConstructor {
new ():DataRowInternal
}
export class DataRowDef implements DataRowInternal {
static typeName = "Data Row";
_id: string = "1"
private store = {};
protected name = "row"
get(key: string) {
return this.store[key];
}
set(key: string, value: any) {
return this.store[key] = value;
}
acceptChanges(): boolean {
return true;
}
}
export let DataRowPublic: DataRowPublicConstructor = DataRowDef;
export let DataRow: DataRowPublicConstructor = DataRowDef;
export let DataRowInternal: DataRowInternalConstructor = DataRowDef;
}
export let DataRow = row.DataRow;
export let DataRowDef = row.DataRowDef;
namespace table {
type DataRow = row.DataRowPublic;
type DataRowInternal = row.DataRowInternal;
export class DataTable {
rows: row.DataRowInternal[] = [];
constructor() {
this.rows.push(new row.DataRow() as DataRowInternal);
}
getRow(id:string): DataRow {
return this.rows.find((row) => {
return row._id == id;
})
}
}
}
export let DataTable = table.DataTable
}
let dt = new arga.DataTable();
let dr = dt.getRow('1');
class MyDataRow extends arga.DataRowDef {
get(key: string) {
console.log(this.name);
return super.get(key);
}
}
let mdr = new MyDataRow();
mdr.set('name', 'reese');
mdr.get('name');
type ContentCompare<T> = (value: T, index: number, array: T[]) => boolean
interface Array<T> {
find(compare: ContentCompare<T>, thisp: any): T
findIndex(compare: ContentCompare<T>, thisp: any): number
values():{next():{value:T, done:boolean}}
}
if (!Array.prototype.find) {
Array.prototype.findIndex = function (predicate:ContentCompare<any>) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.findIndex called on null or undefined');
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return i;
}
}
return -1;
};
Array.prototype.find = function find(compare: ContentCompare<any>, thisp) {
var index = this.findIndex(compare, thisp);
if (index < 0) {
return void 0;
} else {
return this[index];
}
}
}
if (!Array.prototype.values) {
Array.prototype.values = function values() {
var array = this.slice();
var privateIndex = 0;
var iterator = {
next: function next() {
var returnValue = {
value: array[privateIndex],
done: privateIndex >= array.length
}
++privateIndex;
return returnValue;
}
};
if (typeof Symbol !== "undefined") {
if (typeof Symbol.iterator !== "undefined") {
iterator[Symbol.iterator] = () => iterator;
}
}
return iterator;
}
}
namespace Collections {
export class Collection<K, V> {
private _data: V[]
private _keyPath: string
constructor(keyPath: string) {
this._data = [];
this._keyPath = keyPath;
}
has(key: K): boolean {
return this.indexOf(key) !== void 0
}
get(key: K): V {
var index = this.indexOf(key);
if (index < 0) {
return void 0;
} else {
return this._data[index];
}
}
set(value: V): boolean {
var added = false;
var newKey = resolveKeyPath<K>(value, this._keyPath)
var index = this.indexOf(newKey);
if (index < 0) {
added = true;
this._data.push(value)
} else {
console.warn("value with key=" + newKey + " exists in collection. Replacing value")
this._data.splice(index, 1, value);
added = true;
}
return added;
}
add(newValue: V): boolean {
var added = false;
var newKey = resolveKeyPath<K>(newValue, this._keyPath)
var index = this.indexOf(newKey);
if (index < 0) {
added = true;
this._data.push(newValue)
} else {
throw new Error("value with key=" + newKey + " already exists in collection")
}
return added;
}
del(key: K): boolean {
var deleted = false;
var index = this.indexOf(key);
if (index < 0) {
throw new TypeError("key:" + key + "does not exist in set");
} else {
deleted = true;
this._data.splice(index, 1);
}
return deleted;
}
indexOf(key: K): number {
var self = this;
return this._data.findIndex(function (value: V) {
return resolveKeyPath(value, self._keyPath) === key;
})
}
keys(): Iterator<K> {
var self = this;
return this._data.map(function (value: V) {
return resolveKeyPath<K>(value, self._keyPath);
}).values();
}
values(): Iterator<V> {
return this._data.values();
}
entries(): Iterator<Array<any>> {
var self = this;
return this._data.map(function (value: V) {
return [resolveKeyPath(value, self._keyPath), value];
}).values();
}
toString(): string {
return this._data.map((value: V, index: number)=>{
var key = resolveKeyPath(value, this._keyPath);
return key + ":" + value;
}).join(', ');
}
get size():number {
return this._data.length
}
set size(newValue) {
this._data.length = newValue;
}
static isCollection(obj: any) {
return obj instanceof Collection
}
}
function resolveKeyPath<T>(obj: any, keyPath: string): T {
return keyPath.split('.').reduce(function (previous: any, current: string) {
if (obj === void 0) return void 0;
return obj[current];
}, obj)
}
}
There's really not much point to a DataColumn simply as a lookup, since Javascript objects are associative arrays anyways. Why not use DataColumns as indices, which can control constraints and indexed searchese? Doesn't match the ADO.NET DataSet pattern, but is much more useful.
Add a way to associate model objects with data inside a DataTable.
class Person {
constructor(private _dataRow:DataRow){}
name():string {
return this._dataRow.get("name");
}
age():number {
return this._dataRow.get("age");
}
parent():Person {
var dr = this._dataRow;
var relation = dr.table().set().relations("parent");
return dr.getParentRow(relation).model();
}
}
let dt:DataTable = new DataTable("people")
dt.modelConstructor = (row:DataRow)={return new Person(row);}
Use a function to deep copy values during acceptChanges.
function flattenPrototype(a) {
var obj = (Array.isArray(a)) ? [] : Object.create(null);
for (var key in a) {
var value;
if (typeof a[key] === "object") {
value = flattenPrototype(a[key]);
} else value = a[key];
obj[key] = value;
}
return obj;
}
Also, use Object.create(null)
for DataRow._original
Change DataColumn getter/setter to make use of the DataRow calling the getter/setter:
class DataColumn {
// ...
getValue<T>(data:{}, row:DataRow):T {
// ... perform get operation
}
setValue<T>(data:{}, value:T, row:DataRow):T {
// ... perform set operation
this.onValueChanged({
column:this,
row,
oldValue,
newValue:value
}
}
// ...
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.