From 0f592d4bf5ed33be8cadecfccaa6dbc718b1aad3 Mon Sep 17 00:00:00 2001
From: Anatoliy Chakkaev <anatoliy.chakkaev@flatsoft.com>
Date: Tue, 22 Jan 2013 01:48:04 +0700
Subject: [PATCH] Implement schema.extendModel, closes #157

---
 lib/schema.js         | 35 ++++++++++++++++++++++++++++++++++-
 test/adapters_test.js |  2 +-
 test/common_test.js   |  8 +++++++-
 3 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/lib/schema.js b/lib/schema.js
index 9e13a6e7..305aeaed 100644
--- a/lib/schema.js
+++ b/lib/schema.js
@@ -260,7 +260,6 @@ Schema.prototype.define = function defineClass(className, properties, settings)
 
 };
 
-
 /**
  * Define single property named `prop` on `model`
  *
@@ -276,6 +275,40 @@ Schema.prototype.defineProperty = function (model, prop, params) {
     }
 };
 
+/**
+ * Extend existing model with bunch of properties
+ *
+ * @param {String} model - name of model
+ * @param {Object} props - hash of properties
+ *
+ * Example:
+ *
+ *     // Instead of doing this:
+ *
+ *     // amend the content model with competition attributes
+ *     db.defineProperty('Content', 'competitionType', { type: String });
+ *     db.defineProperty('Content', 'expiryDate', { type: Date, index: true });
+ *     db.defineProperty('Content', 'isExpired', { type: Boolean, index: true });
+ *
+ *     // schema.extend allows to
+ *     // extend the content model with competition attributes
+ *     db.extendModel('Content', {
+ *       competitionType: String,
+ *       expiryDate: { type: Date, index: true },
+ *       isExpired: { type: Boolean, index: true }
+ *     });
+ */
+Schema.prototype.extendModel = function (model, props) {
+    var t = this;
+    Object.keys(props).forEach(function (propName) {
+        var definition = props[propName];
+        if (typeof definition === 'function' || typeof definition !== 'object') {
+            definition = {type: definition};
+        }
+        t.defineProperty(model, propName, definition);
+    });
+};
+
 /**
  * Drop each model table and re-create.
  * This method make sense only for sql adapters.
diff --git a/test/adapters_test.js b/test/adapters_test.js
index dd621a92..f9721081 100644
--- a/test/adapters_test.js
+++ b/test/adapters_test.js
@@ -1,4 +1,4 @@
-var jdb = require('jugglingdb'),
+var jdb = require('../'),
     Schema = jdb.Schema,
     test = jdb.test;
 
diff --git a/test/common_test.js b/test/common_test.js
index 80e04c48..1af56dfc 100644
--- a/test/common_test.js
+++ b/test/common_test.js
@@ -121,11 +121,17 @@ function testOrm(schema) {
             approved:     Boolean,
             joinedAt:     Date,
             age:          Number,
-            passwd:    { type: String, index: true },
+            passwd:    { type: String, index: true }
+        });
+
+        schema.extendModel('User', {
             settings:  { type: Schema.JSON },
             extra:      Object
         });
 
+        var newuser = new User({settings: {hey: 'you'}});
+        test.ok(newuser.settings);
+
         Post = schema.define('Post', {
             title:     { type: String, length: 255, index: true },
             subject:   { type: String },