Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ You can annotate a `@Model` as per the following simple example
```dart
import 'package:shellstone/shellstone.dart';

// Annotate this class as being a Model class with identity user
// Annotate this class as being a Model class which corresponds table 'user'
@Model(name: 'user', source: 'mysql')
class User {

Expand Down
56 changes: 21 additions & 35 deletions example/planning.dart
Original file line number Diff line number Diff line change
@@ -1,42 +1,28 @@
import '../lib/shellstone.dart';

// Models can be defined with annotations
@Model(name: 'user')
@Model(migration: 'drop') // 'name' is auto set to Classname in lowercase e.g 'user'
class User {
// Attributes are specified in the same way
@Attr(type: 'integer', primaryKey: true) int id;
@Attr(type: 'string') int username;
@Attr(type: 'string') int password;
@Attr(type: 'boolean') bool archived;
// Attribute definitions
@Attr(primaryKey: true) int id;
@Attr() String username;
@Attr() String password;

// Relations to come (this annotation is conceptual)
// @Rel('1:n') List<Role> roles;
// Has one to many 'roles', the model relation is inferred by <Role>
@Rel(by: 'id', as: 'user_id') List<Role> roles;
}

// @Model('person')
// class Person extends BaseModel with Transactional {
// //<== CONCEPTS
// // @Attr(column: '_id') int id; Provided by BaseModel
// // @Attr() DateTime createdAt; ^^
// // @Attr() DateTime updatedAt; ^^
//
// // save(); Provided by Transactional
// // rollback(); ^^
//
// @Attr(type: 'string') String firstName;
// @Attr(type: 'string') String lastName;
// }
@Model(migration: 'drop')
class Role {
@Attr(primaryKey: true) int id;

// main() async {
// // Setup Shellstone
// await Shellstone.setup();
//
// // Get the first user where it matches the query
// User user = await Model.find('User').where('username').eq('1234').run();
//
// // Get user using filter
// user = await Model.find('User').filter((user) => user.lastName == 'Smith').run();
//
// // Find all users
// Stream<User> users = await Model.findAll('User').run();
// }
// Belongs to user, using model type for example if type cant be inferred
@Rel() User user;
}

main() async {
// Setup Shellstone
await strapIn();

// // Get the first user where it matches the query
// User user = await Model.find('User').where('username').eq('1234').incl('roles').run();
}
19 changes: 10 additions & 9 deletions example/scratchpad.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import 'dart:async';
import 'package:shellstone/shellstone.dart';

main() async {
await strapIn();
@Model(migration: 'drop')
class User {
@Attr(primaryKey:true) int id;
@Attr() String firstName;
@Attr() String lastName;
@Attr() String username;
@Attr() String password;
}

main() async {
await strapIn();

// Javascript Examples
// User.find({ where: { name: 'foo' }, skip: 20, limit: 10, sort: 'name DESC' });
// User.find({ name: { '!' : ['Walter', 'Skyler'] }});

// [Expected] Shellstone Examples
// Model.find('User').where(['name']).eq('foo').skip(20).limit(10).sort(['name'],Desc).run();
// Model.find('User').where(['name']).ne(['Walter','Skyler']).run();
}
24 changes: 20 additions & 4 deletions lib/shellstone.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export 'src/metadata/metadata_proxies.dart';
export 'src/datalayer/database_adapter.dart';
export 'src/datalayer/querylang.dart';
export 'src/datalayer/schema/schema.dart';
export 'src/datalayer/schema/schema_field.dart';
export 'src/datalayer/schema/schema_relation.dart';
export 'src/events/events.dart';
export 'src/events/event_registration.dart';
export 'src/entities/entity_wrapper.dart';
Expand Down Expand Up @@ -75,16 +77,26 @@ addAdapter(String name, DatabaseAdapter adapter) {
///
/// **Note** you cant listen to events that trigger during setup such as some
/// adapter events for example. To listen on those you must use the @Listen annotation
addListener(EventRegistration reg, Function f, [loc = 'pre']) {
addHandler(Listen, reg, f, loc);
addListener(EventRegistration reg, Function f) {
addHandler(Listen, reg, f);
}

/// Adds a hook for a given [EventRegistration]
///
/// **Note** you cant listen to events that trigger during setup such as some
/// adapter events for example. To listen on those you must use the @Listen annotation
addHook(EventRegistration reg, Function f, [loc = 'pre']) {
addHandler(Listen, reg, f, loc);
addHook(EventRegistration reg, Function f) {
addHandler(Hook, reg, f);
}

/// Removes a hook for a given [EventRegistration]
removeListener(EventRegistration reg, Function f) {
removeHandler(Listen, reg, f);
}

/// Removes a hook for a given [EventRegistration]
removeHook(EventRegistration reg, Function f) {
removeHandler(Hook, reg, f);
}

/// Allows for the triggering of some [Event] e
Expand Down Expand Up @@ -145,4 +157,8 @@ _loadSchemas() {

// Construct the schema which will slam it into the cache
meta.forEach((name, proxy) => new Schema.fromMetadata(name, proxy));

// Copies relation keys into their schemas, at least it only happens once
// otherwise a nicer solution might be better for this...
Schema.getAll().forEach((schema) => schema.transferDerivedFields());
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class PostgresQueryExecutor extends SqlExecutor {

// Execute some sql
executeSql(sql, [bool release]) async {
// conn = await psql.connect(adapter.uri);
conn = await adapter.pool.connect();

var result;
Expand Down
11 changes: 10 additions & 1 deletion lib/src/datalayer/adapters/sql_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ abstract class SqlBuilder {
// Add the table creation statements
return _schemas.fold(new List(), (list, schema) {
list.addAll(getTableStatements(schema));
if (schema.indexes.isNotEmpty) list.addAll(getIndexStatements(schema));
return list;
});
}
Expand All @@ -34,7 +35,7 @@ abstract class SqlBuilder {
buffer.write('create table if not exists ${schema.resource}');

// Buffer the field lines
var fields = schema.fields.values.fold(new List(), (list,field) {
var fields = schema.allFields.values.fold(new List(), (list,field) {
list.add(getFieldLine(field));
return list;
}).join(',');
Expand Down Expand Up @@ -77,5 +78,13 @@ abstract class SqlBuilder {
return result.join(' ');
}

// Get the statements to add all the indexes
List<String> getIndexStatements(Schema schema) {
return schema.indexes.values.fold(new List(),(list,field) {
list.add('alter table ${schema.resource} add index(${field.column})');
return list;
});
}

String getPrimaryKey(Schema schema) => 'primary key (${schema.primaryKey.column})';
}
1 change: 1 addition & 0 deletions lib/src/datalayer/querylang.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export 'querylang/tokens/modifier.dart';
export 'querylang/tokens/selector.dart';
export 'querylang/tokens/condition.dart';
export 'querylang/tokens/indentifier.dart';
export 'querylang/tokens/inclusion.dart';
export 'querylang/tokens/insertion.dart';
export 'querylang/tokens/update.dart';
export 'querylang/tokens/removal.dart';
Expand Down
5 changes: 3 additions & 2 deletions lib/src/datalayer/querylang/query_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ class QueryAction {
QueryChain _chain;

// Constructor
QueryAction(String name) {
QueryAction(String name,[this._chain]) {
this.name = name;
_chain = new QueryChain()..setQueryAction(this);
model = Metadata.model(name);
if (_chain == null) _chain = new QueryChain()..setQueryAction(this);
else _chain.setQueryAction(this);
}

dynamic _init(type, result) {
Expand Down
9 changes: 9 additions & 0 deletions lib/src/datalayer/querylang/query_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import '../../../shellstone.dart'; // Ugh hmmm

class QueryRunner implements SingleResultRunnable, MultipleResultRunnable {
QueryChain _chain;
List<QueryChain> _includes = [];

QueryRunner(this._chain);

Expand All @@ -16,4 +17,12 @@ class QueryRunner implements SingleResultRunnable, MultipleResultRunnable {
// Return the result of the query adapter run
return adapter.execute(_chain);
}

// Handles an include call for the governed chain
handleInclude(entity, chain) {
// The provided chain must match the parent!
if (chain != _chain) return;


}
}
5 changes: 3 additions & 2 deletions lib/src/datalayer/querylang/query_token.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ import 'query_runner.dart';
/// Essentially the classes here are all part of a Query
abstract class QueryToken {
QueryChain _chain;
QueryRunner runner;
String operator;
Iterable args;

/// Takes a single [QueryChain] as an argument
QueryToken(this._chain);
QueryToken(this._chain,[QueryRunner this.runner]);

// Allows conveniently setting the operator, values and returning the result
dynamic init(op, val, result) {
Expand All @@ -32,7 +33,7 @@ abstract class QueryToken {
return result;
}

runChain() => new QueryRunner(chain).run();
runChain() => runner == null ? new QueryRunner(chain).run() : runner.run();

get chain => _chain;
}
16 changes: 16 additions & 0 deletions lib/src/datalayer/querylang/tokens/inclusion.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'query.dart';
import '../query_chain.dart';
import '../query_token.dart';
import '../query_runner.dart';
import '../query_action.dart';

/// Defines a class which specifies an included relation on the chain
class Inclusion extends QueryToken {
Inclusion(QueryChain chain) : super(chain);

/// Takes an [id] and returns the [QueryChain]
MultipleResultQuery incl(String name) {
//
// var action = new QueryAction('User');
}
}
Loading