不要怂,就是干,撸起袖子干!

Commit 1d8a6f75 by Sascha Depold

removed old doc

1 parent 5df944e4
Showing with 0 additions and 3795 deletions
Sequelize.STRING ===> VARCHAR(255)
Sequelize.TEXT ===> TEXT
Sequelize.INTEGER ===> INT
Sequelize.DATE ===> DATETIME
Sequelize.BOOLEAN ===> TINYINT(1)
\ No newline at end of file
// app.js
var Project = sequelize.import(__dirname + "/path/to/models/Project").Project
// Project.js
exports.getProjectClass = function(Sequelize, sequelize) {
sequelize.define("Project", {
name: Sequelize.STRING,
description: Sequelize.TEXT
})
}
\ No newline at end of file
/**
* Module dependencies.
*/
require.paths.unshift(__dirname + "/lib/node")
var express = require('express')
, connect = require('connect')
, fs = require('fs')
, http = require('http')
, koala = require('koala')
, sys = require('sys')
, ChangelogImporter = require(__dirname + "/lib/sequelizejs/ChangelogImporter")
, ExampleImporter = require(__dirname + "/lib/sequelizejs/ExampleImporter")
, changelogImporter = new ChangelogImporter("github.com", "/sdepold/sequelize/raw/master/changelog.md", false)
, exampleImporter = new ExampleImporter(false)
var app = module.exports = express.createServer(
connect.logger()
)
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views')
app.use(connect.bodyDecoder())
app.use(connect.methodOverride())
app.use(connect.compiler({ src: __dirname + '/public', enable: ['less'] }))
app.use(app.router)
app.use(connect.staticProvider(__dirname + '/public'))
})
app.configure('development', function(){
app.use(connect.errorHandler({ dumpExceptions: true, showStack: true }))
})
app.configure('production', function(){
app.use(connect.errorHandler())
})
// Routes
app.get('/', function(req, res){
res.render('index.ejs', {
locals: { koala: koala }
})
})
app.get("/changelog", function(req, res) {
res.render('changelog.ejs')
})
app.get("/examples/:example?", function(req, res) {
var examples = fs.readdirSync(__dirname + "/views/examples"),
example = req.params.example
if (typeof example != "undefined") {
console.log(example)
if(examples.indexOf(example + ".ejs") > -1)
res.render("examples/" + example + ".ejs", {
locals: { examples: examples }
})
else
res.redirect("/examples")
} else {
res.render("examples/" + examples[0], {
locals: { examples: examples }
})
}
})
app.get("/background", function(req, res) {
fs.readdir(__dirname + "/public/images/", function(err, files) {
if(err) sys.log(err)
else {
if(files[0] == ".DS_Store") files.shift()
var i = Math.round(Math.random() * (files.length - 1))
res.sendfile(__dirname + "/public/images/" + files[i])
}
})
})
// Only listen on $ node app.js
if (!module.parent) {
app.listen(4000)
sys.log("Server is now listening on port 4000")
var runImporters = function() {
try {
changelogImporter.run()
exampleImporter.run()
} catch(e) {
console.log(e)
}
}
setInterval(runImporters, 1000*60*60)
runImporters()
}
\ No newline at end of file
.DS_Store
0.0.1.seed
\ No newline at end of file
[submodule "vendor/node-async-testing"]
path = vendor/node-async-testing
url = git://github.com/bentomas/node-async-testing.git
The MIT License
Copyright (c) 2010 ajax.org B.V (Fabian Jakobs)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
node-github
===========
Copyright 2010 Ajax.org B.V.
This product includes software developed by
Ajax.org B.V. (http://www.ajax.org/).
The library is based on the the "php-github-api" project by Thibault Duplessis
(http://github.com/ornicar/php-github-api), which is MIT licensed
\ No newline at end of file
# JavaScript GitHub API for node.js
A node.js module, which provides an object oriented wrapper for the GitHub API. This library is a direct port of [php-github-api](http://github.com/ornicar/php-github-api) by Thibault Duplessis to JavaScript. The only major difference is that the JavaScript code is fully asynchronous.
## Installation
Install the [Kiwi package manager for nodejs](http://github.com/visionmedia/kiwi)
and run:
$ kiwi install node-github
or
Install via git clone:
$ git clone git://github.com/ajaxorg/node-github.git && cd node-github && git submodule update --init
## Example
Print all followers of the user "fjakobs" to the console.
var sys = require("sys");
var GitHubApi = require("github").GitHubApi;
var github = new GitHubApi(true);
github.getUserApi().getFollowers('fjakobs', function(err, followers) {
console.log(followers.join('\n'));
});
First the _GitHubApi_ class is imported from the _github_ module. This class provides access to all of GitHub's APIs (e.g. user, commit or repository APIs). The _getFollowers_ method lists all followers of a given GitHub user. Is is part of the user API. It takes the user name as first argument and a callback as last argument. Once the follower list is returned from the server, the callback is called.
Like in node.js callbacks are always the last argument. If the functions fails an error object is passed as first argument to the callback.
## Authentification
Most GitHub API calls don't require authentification. As a rule of thumb: If you can see the information by visiting the site without being logged in, you don't have to be authenticated to retrieve the same information through the API. Of course calls, which change data or read sensitive information have to be authenticated.
You need the GitHub user name and the API key for authentification. The API key can be found in the user's _Account Settings_ page.
This example shows how to authenticate and then change _location_ field of the account settings to _Argentinia_:
github.authenticate(username, token);
github.getUserApi().update(username, {location: "Argentinia"}, function(err) {
console.log("done!");
});
Note that the _authenticate_ method is synchronous because it only stores the credentials for the next request.
## Implemented GitHub APIs
* User API: 100%
* Commit API: 100%
* Object API: 100%
* Repository API: almost complete. Only _create_ and _delete_ repository is missing
* Issues API: only _getList_ is implemented
* Gist API: still missing
* Network API: still missing
## Running the Tests
The unit tests are based on the [node-async-test](http://github.com/bentomas/node-async-testing) module, which is provided as a git submodule. This has to be initialized once using:
git submodule update --init
Running all unit tests:
node test/AllTests.js
The test classes can also be run separately. This will e.g. run the UserApi test:
node test/UserApiTest.js
Note that a connection to the internet is required to run the tests.
## TODO
* port to CommonJS (this should be easy because only the 'doSend' method is node specific)
* API docs
* fix and polish (there might still be some PHP-isms)
* generate API documentation
* Documentation
## LICENSE
MIT license. See the LICENSE file for details.
## Credits
Thanks to Thibault Duplessis for the excellent php-github-api library, which is the blueprint of this library. Especially the unit tests proved to be very helpful.
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var Request = require("./github/Request").Request;
/**
* Simple JavaScript GitHub API
*
* Based on the PHP GitHub API project http://github.com/ornicar/php-github-api
*/
var GitHubApi = exports.GitHubApi = function(debug) {
/**
* Use debug mode (prints debug messages)
*/
this.$debug = debug;
/**
* The list of loaded API instances
*/
this.$apis = [];
};
(function() {
/**
* The request instance used to communicate with GitHub
*/
this.$request = null;
/**
* Authenticate a user for all next requests
*
* @param {String} login GitHub username
* @param {String} token GitHub private token
* @return {GitHubApi} fluent interface
*/
this.authenticate = function(login, token)
{
this.getRequest()
.setOption('login', login)
.setOption('token', token);
return this;
};
/**
* Deauthenticate a user for all next requests
*
* @return {GitHubApi} fluent interface
*/
this.deAuthenticate = function() {
return this.authenticate(null, null);
};
/**
* Call any route, GET method
* Ex: api.get('repos/show/my-username/my-repo')
*
* @param {String} route the GitHub route
* @param {Object} parameters GET parameters
* @param {Object} requestOptions reconfigure the request
* @return {Array} data returned
*/
this.get = function(route, parameters, requestOptions, callback) {
return this.getRequest().get(route, parameters || {}, requestOptions, callback);
};
/**
* Call any route, POST method
* Ex: api.post('repos/show/my-username', {'email': 'my-new-email@provider.org'})
*
* @param {String} route the GitHub route
* @param {Object} parameters POST parameters
* @param {Object} requestOptions reconfigure the request
* @return {Array} data returned
*/
this.post = function(route, parameters, requestOptions, callback) {
return this.getRequest().post(route, parameters || {}, requestOptions, callback);
};
/**
* Get the request
*
* @return {Request} a request instance
*/
this.getRequest = function()
{
if(!this.request) {
this.request = new Request({debug: this.debug});
}
return this.request;
};
/**
* Get the user API
*
* @return {UserApi} the user API
*/
this.getUserApi = function()
{
if(!this.$apis['user']) {
this.$apis['user'] = new (require("./github/UserApi").UserApi)(this);
}
return this.$apis['user'];
};
/**
* Get the repo API
*
* @return {RepoApi} the repo API
*/
this.getRepoApi = function()
{
if(!this.$apis['repo']) {
this.$apis['repo'] = new (require("./github/RepoApi").RepoApi)(this);
}
return this.$apis['repo'];
};
/**
* Get the issue API
*
* @return {IssueApi} the issue API
*/
this.getIssueApi = function()
{
if(!this.$apis['issue']) {
this.$apis['issue'] = new (require("./github/IssueApi").IssueApi)(this);
}
return this.$apis['issue'];
};
/**
* Get the object API
*
* @return {ObjectApi} the object API
*/
this.getObjectApi = function()
{
if(!this.$apis['object']) {
this.$apis['object'] = new (require("./github/ObjectApi").ObjectApi)(this);
}
return this.$apis['object'];
};
/**
* Get the commit API
*
* @return {CommitTest} the commit API
*/
this.getCommitApi = function()
{
if(!this.$apis['commit']) {
this.$apis['commit'] = new (require("./github/CommitApi").CommitApi)(this);
}
return this.$apis['commit'];
};
}).call(GitHubApi.prototype);
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var AbstractApi = exports.AbstractApi = function(api) {
this.$api = api;
};
(function() {
this.$createListener = function(callback, key) {
return function(err, response) {
if (err) {
callback & callback(err);
return;
}
// var sys = require("sys");
// sys.debug("FOOO " + key + sys.inspect(response));
callback(err, key ? response[key] : response);
};
};
}).call(AbstractApi.prototype);
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var sys = require("sys");
var AbstractApi = require("./AbstractApi").AbstractApi;
var CommitApi = exports.CommitApi = function(api) {
this.$api = api;
};
sys.inherits(CommitApi, AbstractApi);
(function() {
/**
* List commits by username, repo and branch
* http://develop.github.com/p/commits.html#listing_commits_on_a_branch
*
* @param {String} username the username
* @param {String} repo the repo
* @param {String} $branch the branch
*/
this.getBranchCommits = function(username, repo, branch, callback)
{
this.$api.get(
'commits/list/' + encodeURI(username) + "/" + encodeURI(repo) + "/" + encodeURI(branch),
null, null,
this.$createListener(callback, "commits")
);
};
/**
* List commits by username, repo, branch and path
* http://develop.github.com/p/commits.html#listing_commits_for_a_file
*
* @param {String} username the username
* @param {String} repo the repo
* @param {String} branch the branch
* @param {String} path the path
*/
this.getFileCommits = function(username, repo, branch, path, callback)
{
this.$api.get(
'commits/list/' + encodeURI(username) + "/" + encodeURI(repo) + "/" + encodeURI(branch) + "/" + encodeURI(path),
null, null,
this.$createListener(callback, "commits")
);
};
}).call(CommitApi.prototype);
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var sys = require("sys");
var AbstractApi = require("./AbstractApi").AbstractApi;
var IssueApi = exports.IssueApi = function(api) {
this.$api = api;
};
sys.inherits(IssueApi, AbstractApi);
(function() {
/**
* List issues by username, repo and state
* http://develop.github.com/p/issues.html#list_a_projects_issues
*
* @param {String} username the username
* @param {String} repo the repo
* @param {String} $state the issue state, can be open or closed
*/
this.getList = function(username, repo, state, callback)
{
var state = state || "open";
this.$api.get(
'issues/list/' + encodeURI(username) + "/" + encodeURI(repo) + "/" + encodeURI(state),
null, null,
this.$createListener(callback, "issues")
);
};
}).call(IssueApi.prototype);
//
///**
// * Search issues by username, repo, state and search term
// * http://develop.github.com/p/issues.html#list_a_projects_issues
// *
// * @param {String} username the username
// * @param {String} repo the repo
// * @param {String} $state the issue state, can be open or closed
// * @param {String} $searchTerm the search term to filter issues by
// */
//this.search = function(username, repo, $state, $searchTerm)
//{
// $response = $this->api->get('issues/search/'.urlencode(username).'/'.urlencode(repo).'/'.urlencode($state).'/'.urlencode($searchTerm));
//
// return $response['issues'];
//}
//
///**
// * Get extended information about an issue by its username, repo and number
// * http://develop.github.com/p/issues.html#view_an_issue
// *
// * @param {String} username the username
// * @param {String} repo the repo
// * @param {String} issueNumber the issue number
// */
//this.show = function(username, repo, issueNumber)
//{
// $response = $this->api->get('issues/show/'.urlencode(username).'/'.urlencode(repo).'/'.urlencode(issueNumber));
//
// return $response['issue'];
//}
//
///**
// * Create a new issue for the given username and repo.
// * The issue is assigned to the authenticated user. Requires authentication.
// * http://develop.github.com/p/issues.html#open_and_close_issues
// *
// * @param {String} username the username
// * @param {String} repo the repo
// * @param {String} $issueTitle the new issue title
// * @param {String} $issueBody the new issue body
// */
//this.open = function(username, repo, $issueTitle, $issueBody)
//{
// $response = $this->api->post('issues/open/'.urlencode(username).'/'.urlencode(repo), array(
// 'title' => $issueTitle,
// 'body' => $issueBody
// ));
//
// return $response['issue'];
//}
//
///**
// * Close an existing issue by username, repo and issue number. Requires authentication.
// * http://develop.github.com/p/issues.html#open_and_close_issues
// *
// * @param {String} username the username
// * @param {String} repo the repo
// * @param {String} issueNumber the issue number
// */
//this.close = function(username, repo, issueNumber)
//{
// $response = $this->api->post('issues/close/'.urlencode(username).'/'.urlencode(repo).'/'.urlencode(issueNumber));
//
// return $response['issue'];
//}
//
///**
// * Update issue informations by username, repo and issue number. Requires authentication.
// * http://develop.github.com/p/issues.html#edit_existing_issues
// *
// * @param {String} username the username
// * @param {String} repo the repo
// * @param {String} issueNumber the issue number
// * @param array $data key=>value user attributes to update.
// * key can be title or body
// */
//this.update = function(username, repo, issueNumber, array $data)
//{
// $response = $this->api->post('issues/edit/'.urlencode(username).'/'.urlencode(repo).'/'.urlencode(issueNumber), $data);
//
// return $response['issue'];
//}
//
///**
// * Repoen an existing issue by username, repo and issue number. Requires authentication.
// * http://develop.github.com/p/issues.html#open_and_close_issues
// *
// * @param {String} username the username
// * @param {String} repo the repo
// * @param {String} issueNumber the issue number
// */
//this.reOpen = function(username, repo, issueNumber)
//{
// $response = $this->api->post('issues/reopen/'.urlencode(username).'/'.urlencode(repo).'/'.urlencode(issueNumber));
//
// return $response['issue'];
//}
//
///**
// * List an issue comments by username, repo and issue number
// * http://develop.github.com/p/issues.html#list_an_issues_comments
// *
// * @param {String} username the username
// * @param {String} repo the repo
// * @param {String} issueNumber the issue number
// */
//this.getComments = function(username, repo, issueNumber)
//{
// $response = $this->api->get('issues/comments/'.urlencode(username).'/'.urlencode(repo).'/'.urlencode(issueNumber));
//
// return $response['comments'];
//}
//
///**
// * Add a comment to the issue by username, repo and issue number
// * http://develop.github.com/p/issues.html#comment_on_issues
// *
// * @param {String} username the username
// * @param {String} repo the repo
// * @param {String} issueNumber the issue number
// * @param {String} $comment the comment body
// */
//this.addComment = function(username, repo, issueNumber, $commentBody)
//{
// $response = $this->api->post('issues/comment/'.urlencode(username).'/'.urlencode(repo).'/'.urlencode(issueNumber), array(
// 'comment' => $commentBody
// ));
//
// return $response['comment'];
//}
//
///**
// * List all project labels by username and repo
// * http://develop.github.com/p/issues.html#listing_labels
// *
// * @param {String} username the username
// * @param {String} repo the repo
// */
//this.getLabels = function(username, repo)
//{
// $response = $this->api->get('issues/labels/'.urlencode(username).'/'.urlencode(repo));
//
// return $response['labels'];
//}
//
///**
// * Add a label to the issue by username, repo and issue number. Requires authentication.
// * http://develop.github.com/p/issues.html#add_and_remove_labels
// *
// * @param {String} username the username
// * @param {String} repo the repo
// * @param {String} issueNumber the issue number
// * @param {String} labelName the label name
// */
//this.addLabel = function(username, repo, labelName, issueNumber)
//{
// $response = $this->api->post('issues/label/add/'.urlencode(username).'/'.urlencode(repo).'/'.urlencode(labelName).'/'.urlencode(issueNumber));
//
// return $response['labels'];
//}
//
///**
// * Remove a label from the issue by username, repo, issue number and label name. Requires authentication.
// * http://develop.github.com/p/issues.html#add_and_remove_labels
// *
// * @param {String} username the username
// * @param {String} repo the repo
// * @param {String} issueNumber the issue number
// * @param {String} labelName the label name
// */
//this.removeLabel = function(username, repo, labelName, issueNumber)
//{
// $response = $this->api->post('issues/label/remove/'.urlencode(username).'/'.urlencode(repo).'/'.urlencode(labelName).'/'.urlencode(issueNumber));
//
// return $response['labels'];
//}
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var sys = require("sys");
var AbstractApi = require("./AbstractApi").AbstractApi;
var ObjectApi = exports.ObjectApi = function(api) {
this.$api = api;
};
sys.inherits(ObjectApi, AbstractApi);
(function() {
/**
* Get a listing of the root tree of a project by the username, repo, and tree SHA
* http://develop.github.com/p/object.html#trees
*
* @param {String} username the username
* @param {String} repo the repo
* @param {String} treeSha the tree sha
*/
this.showTree = function(username, repo, treeSha, callback)
{
this.$api.get(
'tree/show/' + encodeURI(username) + "/" + encodeURI(repo) + "/" + encodeURI(treeSha),
null, null,
this.$createListener(callback, "tree")
);
};
/**
* Lists the data blobs of a tree by tree SHA
* http://develop.github.com/p/object.html#blobs
*
* @param {String} username the username
* @param {String} repo the repo
* @param {String} treeSha the tree sha
* @param {String} path the path
*/
this.listBlobs = function(username, repo, treeSha, callback)
{
this.$api.get(
'blob/all/' + encodeURI(username) + "/" + encodeURI(repo) + "/" + encodeURI(treeSha),
null, null,
this.$createListener(callback, "blobs")
);
};
/**
* Get the data about a blob by tree SHA and file path.
* http://develop.github.com/p/object.html#blobs
*
* @param {String} username the username
* @param {String} repo the repo
* @param {String} treeSha the tree sha
* @param {String} path the path
*/
this.showBlob = function(username, repo, treeSha, path, callback)
{
this.$api.get(
'blob/show/' + encodeURI(username) + "/" + encodeURI(repo) + "/" + encodeURI(treeSha) + "/" + encodeURI(path),
null, null,
this.$createListener(callback, "blob")
);
};
/**
* Returns the raw text content of the object.
* http://develop.github.com/p/object.html#raw_git_data
*
* @param {String} username the username
* @param {String} repo the repo
* @param {String} objectSha the object sha can be either a blob SHA1, a tree SHA1 or a commit SHA1
*/
this.getRawData = function(username, repo, objectSha, callback)
{
this.$api.get(
'blob/show/' + encodeURI(username) + "/" + encodeURI(repo) + "/" + encodeURI(objectSha),
null, {format: "text"},
this.$createListener(callback)
);
};
}).call(ObjectApi.prototype);
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var sys = require("sys");
var AbstractApi = require("./AbstractApi").AbstractApi;
var RepoApi = exports.RepoApi = function(api) {
this.$api = api;
};
sys.inherits(RepoApi, AbstractApi);
(function() {
/**
* Search repos by keyword
* http://develop.github.com/p/repos.html#searching_repositories
*
* @param {String} $query the search query
*/
this.search = function(query, callback)
{
this.$api.get(
'repos/search/' + encodeURI(query),
null, null,
this.$createListener(callback, "repositories")
);
};
/**
* Get extended information about a repository by its username and repo name
* http://develop.github.com/p/repos.html#show_repo_info
*
* @param {String} username the user who owns the repo
* @param {String} repo the name of the repo
*/
this.show = function(username, repo, callback)
{
this.$api.get(
'repos/show/' + encodeURI(username) + "/" + encodeURI(repo),
null, null,
this.$createListener(callback, "repository")
);
};
/**
* Get the repositories of a user
* http://develop.github.com/p/repos.html#list_all_repositories
*
* @param {String} username the username
*/
this.getUserRepos = function(username, callback)
{
this.$api.get(
'repos/show/' + encodeURI(username),
null, null,
this.$createListener(callback, "repositories")
);
};
/**
* Get the tags of a repository
* http://develop.github.com/p/repos.html#repository_refs
*
* @param {String} username the username
* @param {String} repo the name of the repo
*/
this.getRepoTags = function(username, repo, callback)
{
this.$api.get(
'repos/show/' + encodeURI(username) + "/" + encodeURI(repo) + "/tags",
null, null,
this.$createListener(callback, "tags")
);
};
/**
* Get the branches of a repository
* http://develop.github.com/p/repos.html#repository_refs
*
* @param {String} username the username
* @param {String} repo the name of the repo
*/
this.getRepoBranches = function(username, repo, callback)
{
this.$api.get(
'repos/show/' + encodeURI(username) + "/" + encodeURI(repo) + "/branches",
null, null,
this.$createListener(callback, "branches")
);
};
}).call(RepoApi.prototype);
///**
// * Create a new repository
// * @param {String} repo name of the repo
// * @param {String} $description repo description
// * @param {String} $homepage homepage url
// * @param {String} $public 1 for public, 0 for private
// */
//this.createRepo = function(repo, $description=null, $homepage=null, $public=1, callback)
//{
// $param = array(
// 'name' => repo,
// 'public'=>$public
// );
// if (isset($description)) $param['description'] = $description;
// if (isset($homepage)) $param['homepage'] = $homepage;
//
// $response = $this->api->post('repos/create/', $param);
//
// return $response;
// }
//
///**
// * Delete a repository
// * @param {String} repo name of the repo
// */
//this.deleteRepo = function(repo, callback)
//{
// if (isset($description)) $param['description'] = $description;
// if (isset($homepage)) $param['homepage'] = $homepage;
//
// $res = $this->api->post('repos/delete/' . repo);
// $response = $this->api->post('repos/delete/' . repo, array('delete_token' => $res['delete_token']));
//
// return $response;
// }
//
///**
// * Fork a repository. Requires authentication.
// * @param {String} username the username
// * @param {String} repo name of the repo
// */
//this.forkRepo = function(username, repo, callback)
//{
// $response = $this->api->get('repos/fork/'.urlencode(username).'/'.urlencode(repo));
//
// return $response;
//}
//
///**
// * Show all forks of a repository
// * @param {String} username the username
// * @param {String} repo name of the repo
// */
//this.getRepoForks = function(username, repo, callback)
//{
// $response = $this->api->get('repos/show/'.urlencode(username).'/'.urlencode(repo).'/network');
//
// return $response['network'];
//}
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var http = require("http");
var sys = require("sys");
/**
* Performs requests on GitHub API. API documentation should be self-explanatory.
*/
var Request = exports.Request = function(options) {
this.configure(options);
};
(function() {
this.$defaults = {
protocol : 'http',
url : ':protocol://github.com/api/v2/:format/:path',
path : '/api/v2',
hostname : "github.com",
format : 'json',
user_agent : 'js-github-api (http://github.com/ornicar/php-github-api)',
http_port : 80,
timeout : 20,
login : null,
token : null,
debug : false
};
this.configure = function(options)
{
var options = options || {};
this.$options = {};
for (var key in this.$defaults) {
this.$options[key] = options[key] !== undefined ? options[key] : this.$defaults[key];
}
return this;
};
/**
* Change an option value.
*
* @param {String} name The option name
* @param {Object} value The value
*
* @return {Request} The current object instance
*/
this.setOption = function(name, value)
{
this.$options[name] = value;
return this;
};
/**
* Get an option value.
*
* @param string $name The option name
*
* @return mixed The option value
*/
this.getOption = function(name, defaultValue)
{
var defaultValue = defaultValue === undefined ? null : defaultValue;
return this.$options[name] ? this.$options[name] : defaultValue;
};
/**
* Send a GET request
* @see send
*/
this.get = function(apiPath, parameters, options, callback) {
return this.send(apiPath, parameters, 'GET', options, callback);
};
/**
* Send a POST request
* @see send
*/
this.post = function(apiPath, parameters, options, callback) {
return this.send(apiPath, parameters, 'POST', options, callback);
};
/**
* Send a request to the server, receive a response,
* decode the response and returns an associative array
*
* @param {String} apiPath Request API path
* @param {Object} parameters Parameters
* @param {String} httpMethod HTTP method to use
* @param {Object} options reconfigure the request for this call only
*/
this.send = function(apiPath, parameters, httpMethod, options, callback)
{
var httpMethod = httpMethod || "GET";
if(options)
{
var initialOptions = this.$options;
this.configure(options);
}
var self = this;
this.doSend(apiPath, parameters, httpMethod, function(err, response) {
if (err) {
callback && callback(err);
return;
}
var response = self.decodeResponse(response);
if (initialOptions) {
self.options = initialOptions;
};
callback && callback(null, response);
});
};
/**
* Send a request to the server, receive a response
*
* @param {String} $apiPath Request API path
* @param {Object} $parameters Parameters
* @param {String} $httpMethod HTTP method to use
*/
this.doSend = function(apiPath, parameters, httpMethod, callback)
{
var httpMethod = httpMethod.toUpperCase();
var client = http.createClient(this.$options.http_port, this.$options.hostname);
if (this.$options['login']) {
parameters.login = this.$options['login'];
parameters.token = this.$options['token'];
}
var args = [];
for (var key in parameters) {
args.push(encodeURIComponent(key) + "=" + encodeURIComponent(parameters[key]));
}
var queryString = args.join("&");
var path = this.$options.path + "/" + this.$options.format + "/" + apiPath.replace(/\/*$/, "");
var headers = {
'host':'github.com',
"User-Agent": "NodeJS HTTP Client",
"Content-Length": "0"
};
if (queryString) {
if (httpMethod == "GET") {
path += "?" + queryString;
} else if (httpMethod == "POST") {
headers["Content-Length"] = queryString.length;
}
}
var request = client.request(httpMethod, path, headers);
if (httpMethod == "POST") {
request.write(queryString);
}
this.$debug('send ' + httpMethod + ' request: ' + path);
request.addListener('response', function (response) {
if (response.statusCode > 200) {
callback({status: response.statusCode, msg: response.status});
return;
}
response.setEncoding('utf8');
var body = [];
response.addListener('data', function (chunk) {
body.push(chunk);
});
response.addListener('end', function () {
callback(null, body.join(""));
});
});
request.end();
},
/**
* Get a JSON response and transform to JSON
*/
this.decodeResponse = function(response)
{
if(this.$options['format'] === "text")
{
return response;
}
else if(this.$options['format'] === "json")
{
return JSON.parse(response);
}
};
this.$debug = function(msg) {
if (this.$options.debug) {
require("sys").debug(msg);
}
};
}).call(Request.prototype);
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var sys = require("sys");
var AbstractApi = require("./AbstractApi").AbstractApi;
var UserApi = exports.UserApi = function(api) {
this.$api = api;
};
sys.inherits(UserApi, AbstractApi);
(function() {
/**
* Search users by username
* http://develop.github.com/p/users.html#searching_for_users
*
* @param {String} username the username to search
*/
this.search = function(username, callback)
{
this.$api.get(
'user/search/' + encodeURI(username),
null, null,
this.$createListener(callback, "users")
);
};
/**
* Get extended information about a user by its username
* http://develop.github.com/p/users.html#getting_user_information
*
* @param {String} username the username to show
*/
this.show = function(username, callback)
{
this.$api.get(
'user/show/' + encodeURI(username),
null, null,
this.$createListener(callback, "user")
);
};
/**
* Request the users that a specific user is following
* http://develop.github.com/p/users.html#following_network
*
* @param {String} username the username
*/
this.getFollowing = function(username, callback)
{
this.$api.get(
'user/show/' + encodeURI(username) + "/following",
null, null,
this.$createListener(callback, "users")
);
};
/**
* Request the users following a specific user
* http://develop.github.com/p/users.html#following_network
*
* @param {String} username the username
*/
this.getFollowers = function(username, callback)
{
this.$api.get(
'user/show/' + encodeURI(username) + '/followers',
null, null,
this.$createListener(callback, "users")
);
},
/**
* Update user informations. Requires authentication.
* http://develop.github.com/p/users.html#authenticated_user_management
*
* @param {String} username the username to update
* @param {Object} data key, value user attributes to update.
* key can be name, email, blog, company or location
*/
this.update = function(username, data, callback)
{
var parameters = {};
for (var key in data) {
parameters["values[" + key + "]"] = data[key];
}
this.$api.post(
'user/show/' + encodeURI(username),
parameters, null,
this.$createListener(callback)
);
};
/**
* Make the authenticated user follow the specified user. Requires authentication.
* http://develop.github.com/p/users.html#following_network
*
* @param {String} username the username to follow
*/
this.follow = function(username, callback)
{
this.$api.post(
'user/follow/' + encodeURI(username),
null, null,
this.$createListener(callback)
);
},
/**
* Make the authenticated user unfollow the specified user. Requires authentication.
* http://develop.github.com/p/users.html#following_network
*
* @param {String} username the username to unfollow
*/
this.unFollow = function(username, callback)
{
this.$api.post(
'user/unfollow/' + encodeURI(username),
null, null,
this.$createListener(callback)
);
},
/**
* Request the repos that a specific user is watching
* http://develop.github.com/p/users.html#watched_repos
*
* @param {String} username the username
*/
this.getWatchedRepos = function(username, callback)
{
this.$api.get(
'repos/watched/' + encodeURI(username),
null, null,
this.$createListener(callback, "repositories")
);
},
/**
* Get the authenticated user emails. Requires authentication.
*/
this.getEmails = function(callback)
{
this.$api.get(
"user/emails",
null, null,
this.$createListener(callback, "emails")
);
},
/**
* Add an email to the authenticated user. Requires authentication.
*/
this.addEmail = function(email, callback)
{
this.$api.post(
'user/email/add',
{email: email}, null,
this.$createListener(callback, "emails")
);
},
/**
* Remove an email from the authenticated user. Requires authentication.
*/
this.removeEmail = function(email, callback)
{
this.$api.post(
'user/email/remove',
{email: email}, null,
this.$createListener(callback, "emails")
);
},
/**
* Get a list with deploy keys that are set for the authenticated user. Requires authentication.
*/
this.getKeys = function(callback)
{
this.$api.get(
'user/keys',
null, null,
this.$createListener(callback, "public_keys")
);
},
/**
* Add a public key for the authenticated user. Requires authentication.
*
* @param {String} title title of the key
* @param {String} key public key data
*/
this.addKey = function(title, key, callback)
{
var parameters = {
title: title,
key: key
};
this.$api.post(
'user/key/add',
parameters, null,
this.$createListener(callback, "public_keys")
);
},
/**
* Remove a public key from the authenticated user. Requires authentication.
*
* @param {String} id id of the key to remove
*/
this.removeKey = function(id, callback)
{
this.$api.post(
'user/key/remove',
{id: id}, null,
this.$createListener(callback, "public_keys")
);
};
}).call(UserApi.prototype);
\ No newline at end of file
{
"name" : "github",
"version" : "0.0.2",
"description" : "Wrapper for the GitHub API",
"author": "Fabian Jakobs <fabian.jakobs@web.de>",
"homepage": "http://github.com/ajaxorg/node-github.git",
"modules" : {
"index" : "./lib/github",
},
"repository" : {
"type" : "git",
"url" : "http://github.com/ajaxorg/node-github.git"
},
"engine" : ["node >=0.1.100"],
"licenses": [{
"type": "The MIT License",
"url": "http://www.opensource.org/licenses/mit-license.php"}
]
}
---
name: node-github
description: node wrapper for the GitHub API
tags: git github web
version: 0.0.1
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var async_testing = require('../vendor/node-async-testing/async_testing');
var suites = {
ObjectApi: require("./ObjectApiTest").suite,
IssueApi: require("./IssueApiTest").suite,
CommitApi: require("./CommitApiTest").suite,
RepoApi: require("./RepoApiTest").suite,
UserApi: require("./UserApiTest").suite,
GitHubApi: require("./GitHubApiTest").suite,
Request: require("./RequestTest").suite,
Authentification: require("./AuthentificationTest").suite
};
if (module === require.main) {
async_testing.runSuites(suites);
}
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var GitHubApi = require("../lib/github").GitHubApi;
var async_testing = require('../vendor/node-async-testing/async_testing');
var suite = exports.suite = new async_testing.TestSuite();
var username = 'fjakobstest';
var token = 'b98166e45acf66df70a992e2de56b92a';
var repo = "o3";
suite.setup(function() {
this.github = new GitHubApi(true);
this.userApi = this.github.getUserApi();
});
suite.addTests({
"test: show user without authentification should have no 'plan'" : function(assert, finished, test) {
test.userApi.show(username, function(err, user) {
assert.equal(user.plan, undefined);
finished();
});
},
"test: show user with authentification should have a 'plan'" : function(assert, finished, test) {
test.github.authenticate(username, token);
test.userApi.show(username, function(err, user) {
assert.ok(user.plan !== undefined);
finished();
});
},
"test: authenticate with bad token" : function(assert, finished, test) {
test.github.authenticate(username, "bad-token");
test.userApi.show(username, function(err, user) {
assert.ok(err !== undefined);
finished();
});
}
});
if (module === require.main) {
async_testing.runSuites({GitHubApi: suite});
}
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var sys = require("sys");
var GitHubApi = require("../lib/github").GitHubApi;
var async_testing = require('../vendor/node-async-testing/async_testing');
var suite = exports.suite = new async_testing.TestSuite();
var username = "ornicar";
var branch = "master";
var repo = "php-github-api";
suite.setup(function() {
this.github = new GitHubApi(true);
this.commitApi = this.github.getCommitApi();
});
suite.addTests({
"test: list branch commits" : function(assert, finished, test) {
test.commitApi.getBranchCommits(username, repo, branch, function(err, commits) {
assert.ok(commits.length > 0);
assert.ok(commits[0].message !== undefined);
finished();
});
},
"test: get file commits" : function(assert, finished, test) {
test.commitApi.getFileCommits(username, repo, branch, "README", function(err, commits) {
assert.ok(commits.length > 0);
assert.equal(commits.pop().message, "first commit");
finished();
});
}
});
if (module === require.main) {
async_testing.runSuites({CommitApi: suite});
}
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var GitHubApi = require("../lib/github").GitHubApi;
var async_testing = require('../vendor/node-async-testing/async_testing');
var suite = exports.suite = new async_testing.TestSuite();
suite.addTests({
"test: create API instance" : function(assert) {
var api = new GitHubApi();
assert.ok(api instanceof GitHubApi);
},
"test loading a repository" : function(assert, finished) {
var github = new GitHubApi();
github.get('repos/show/ornicar/php-github-api', null, null, function(err, repo) {
assert.equal(repo['repository']['name'], 'php-github-api', 'Found information about php-github-api repo');
finished();
});
},
"test loading a non existing repository should return an error" : function(assert, finished) {
var github = new GitHubApi();
github.get('non-existing-url/for-sure', null, null, function(err, repo) {
assert.ok(err !== undefined);
finished();
});
}
});
if (module === require.main) {
async_testing.runSuites({GitHubApi: suite});
}
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var sys = require("sys");
var GitHubApi = require("../lib/github").GitHubApi;
var async_testing = require('../vendor/node-async-testing/async_testing');
var suite = exports.suite = new async_testing.TestSuite();
var username = 'ornicar';
var repo = 'php-github-api';
suite.setup(function() {
this.github = new GitHubApi(true);
this.issueApi = this.github.getIssueApi();
});
suite.addTests({
"test: list issues" : function(assert, finished, test) {
test.issueApi.getList(username, repo, "closed", function(err, issues) {
assert.equal(issues[0].state, "closed");
finished();
});
}
});
if (module === require.main) {
async_testing.runSuites({IssueApi: suite});
}
//$t->is_deeply($github->listIssues($username, $repo, 'closed'), $issues, 'Both new and BC syntax work');
//
//$t->comment('Search issues');
//
//$issues = $github->getIssueApi()->search($username, $repo, 'closed', 'documentation');
//
//$t->is($issues[0]['state'], 'closed', 'Found closed issues matching "documentation"');
//
//$t->is_deeply($github->searchIssues($username, $repo, 'closed', 'documentation'), $issues, 'Both new and BC syntax work');
//
//$t->comment('Show issue');
//
//$issue = $github->getIssueApi()->show($username, $repo, 1);
//
//$t->is($issue['title'], 'Provide documentation', 'Found issue #1');
//
//$t->is_deeply($github->showIssue($username, $repo, 1), $issue, 'Both new and BC syntax work');
//
//$username = 'ornicartest';
//$token = 'fd8144e29b4a85e9487d1cacbcd4e26c';
//$repo = 'php-github-api';
//
//$t->comment('Authenticate '.$username);
//
//$github->authenticate($username, $token);
//
//$t->comment('Open a new issue');
//
//$issueTitle = 'Test new issue title '.time();
//$issue = $github->getIssueApi()->open($username, $repo, $issueTitle, 'Test new issue body');
//
//$t->is($issue['title'], $issueTitle, 'Got the new issue');
//$t->is($issue['state'], 'open', 'The new issue is open');
//
//$issueNumber = $issue['number'];
//
//$t->comment('Close the issue');
//
//$issue = $github->getIssueApi()->close($username, $repo, $issueNumber);
//
//$t->is($issue['state'], 'closed', 'The new issue is closed');
//
//$t->comment('Reopen the issue');
//
//$issue = $github->getIssueApi()->reOpen($username, $repo, $issueNumber);
//
//$t->is($issue['state'], 'open', 'The new issue is open');
//
//$t->comment('Update the issue');
//
//$issue = $github->getIssueApi()->update($username, $repo, $issueNumber, array(
// 'body' => 'Test new issue body updated'
//));
//
//$t->is($issue['body'], 'Test new issue body updated', 'The issue has been updated');
//
//$t->comment('Add an issue comment');
//$commentText = 'This is a test comment';
//
//$comment = $github->getIssueApi()->addComment($username, $repo, $issueNumber, $commentText);
//
//$t->is($comment['comment'], $commentText, 'Got the new comment');
//
//$t->comment('List issue comments');
//
//$comments = $github->getIssueApi()->getComments($username, $repo, $issueNumber);
//
//$t->is($comments[0]['body'], $commentText, 'Found the new comment');
//
//$t->comment('Add a label to the issue');
//$labelName = 'testing';
//
//$labels = $github->getIssueApi()->addLabel($username, $repo, $labelName, $issueNumber);
//
//$t->ok(in_array($labelName, $labels), 'The issue now has the label '.$labelName);
//
//$t->comment('Remove a label from the issue');
//
//$labels = $github->getIssueApi()->removeLabel($username, $repo, $labelName, $issueNumber);
//
//$t->ok(!in_array($labelName, $labels), 'The issue has no more label '.$labelName);
//
//$t->comment('List project labels');
//
//$labels = $github->getIssueApi()->getLabels($username, $repo);
//
//$t->ok(in_array($labelName, $labels), 'The project has the label '.$labelName);
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var sys = require("sys");
var GitHubApi = require("../lib/github").GitHubApi;
var async_testing = require('../vendor/node-async-testing/async_testing');
var suite = exports.suite = new async_testing.TestSuite();
var username = 'ornicar';
var repo = 'php-github-api';
var treeSha = '691c2ec7fd0b948042047b515886fec40fe76e2b';
suite.setup(function() {
this.github = new GitHubApi(true);
this.objectApi = this.github.getObjectApi();
});
suite.addTests({
"test: show tree" : function(assert, finished, test) {
this.objectApi.showTree(username, repo, treeSha, function(err, tree) {
assert.equal(tree.pop().sha, "5ac35496a1cbb2a914ff4325e7d6e8cae61f90b9");
finished();
});
},
"test: show blob" : function(assert, finished, test) {
this.objectApi.showBlob(username, repo, treeSha, 'CHANGELOG', function(err, blob) {
assert.equal(blob.name, "CHANGELOG");
finished();
});
},
"test: list blobs" : function(assert, finished, test) {
this.objectApi.listBlobs(username, repo, treeSha, function(err, blobs) {
assert.equal(blobs["README.markdown"], "d15692fb3adcbb752064c6be20361cf86914d736");
finished();
});
},
"test: get raw text" : function(assert, finished, test) {
var expected = [
"tree d978e4755a9ed4e7ca3ebf9ed674dfb95b4af481",
"parent e291e9377fd64e08dba556f2dce5b0fc0011430e",
"author Thibault Duplessis <thibault.duplessis@gmail.com> 1266076405 +0100",
"committer Thibault Duplessis <thibault.duplessis@gmail.com> 1266076405 +0100",
"",
"created README.markdown",
""
].join("\n");
this.objectApi.getRawData(username, repo, "bd25d1e4ea7eab84b856131e470edbc21b6cd66b", function(err, data) {
assert.equal(data, expected);
finished();
});
}
});
if (module === require.main) {
async_testing.runSuites({ObjectApi: suite});
}
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var sys = require("sys");
var GitHubApi = require("../lib/github").GitHubApi;
var async_testing = require('../vendor/node-async-testing/async_testing');
var suite = exports.suite = new async_testing.TestSuite();
suite.setup(function() {
this.github = new GitHubApi(true);
this.repoApi = this.github.getRepoApi();
});
suite.addTests({
"test: search repos" : function(assert, finished, test) {
test.repoApi.search("php github api", function(err, repos) {
assert.ok(repos.length > 0);
assert.ok(repos[0].name !== undefined);
finished();
});
},
"test: show repository" : function(assert, finished, test) {
test.repoApi.show("fjakobs", "qxoo", function(err, repo) {
assert.equal(repo.name, "qxoo");
finished();
});
},
"test: get user repos" : function(assert, finished, test) {
test.repoApi.getUserRepos("fjakobs", function(err, repos) {
assert.ok(repos.length > 0);
assert.ok(repos[0].name !== undefined);
finished();
});
},
"test: get repo tags" : function(assert, finished, test) {
test.repoApi.getRepoTags("fjakobs", "node", function(err, tags) {
assert.ok(tags["v0.1.0"] == "813b53938b40484f63e7324c030e33711f26a149");
finished();
});
},
"test: get repo branches" : function(assert, finished, test) {
test.repoApi.getRepoBranches("fjakobs", "node", function(err, branches) {
assert.ok(branches["master"] !== undefined);
finished();
});
}
});
if (module === require.main) {
async_testing.runSuites({RepoApi: suite});
}
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var Request = require("../lib/github/Request").Request;
var async_testing = require('../vendor/node-async-testing/async_testing');
var suite = exports.suite = new async_testing.TestSuite();
suite.addTests({
"test: create request instance" : function(assert) {
var request = new Request();
assert.ok(request instanceof Request);
},
"test: GET request" : function(assert, finished) {
var request = new Request();
request.get('user/search/diem-project', null, null, function(err, response) {
var sys = require("sys");
assert.equal(response.users.length, 1, "Found one user");
assert.equal(response.users[0].name, "diem-project", "Found one user");
finished();
});
}
});
if (module === require.main) {
async_testing.runSuites({Request: suite});
}
\ No newline at end of file
/**
* Copyright 2010 Ajax.org B.V.
*
* This product includes software developed by
* Ajax.org B.V. (http://www.ajax.org/).
*
* Author: Fabian Jaokbs <fabian@ajax.org>
*/
var sys = require("sys");
var GitHubApi = require("../lib/github").GitHubApi;
var async_testing = require('../vendor/node-async-testing/async_testing');
var suite = exports.suite = new async_testing.TestSuite();
var username = 'fjakobstest';
var token = 'b98166e45acf66df70a992e2de56b92a';
suite.setup(function() {
this.github = new GitHubApi(true);
this.userApi = this.github.getUserApi();
});
suite.addTests({
"test: search users" : function(assert, finished) {
this.userApi.search(username, function(err, users) {
assert.equal(users.length, 1);
assert.equal(users[0].name, username);
finished();
});
},
"test: show a user" : function(assert, finished) {
this.userApi.show(username, function(err, user) {
assert.equal(user.login, username);
finished();
});
},
"test: show a non existing user" : function(assert, finished) {
this.userApi.show('this-user-probably-doesnt-exist', function(err, user) {
assert.notEqual(err, undefined);
finished();
});
},
"test: get following users" : function(assert, finished) {
this.userApi.getFollowing('fjakobs', function(err, following) {
assert.ok(following.length > 0);
finished();
});
},
"test: get follower users" : function(assert, finished) {
this.userApi.getFollowers('fjakobs', function(err, followers) {
assert.ok(followers.length > 0);
finished();
});
},
"test: authenticate user and update location to Argentinia" : function(assert, finished, test) {
test.github.authenticate(username, token);
test.userApi.update(username, {location: "Argentinia"}, function(err) {
test.userApi.show(username, function(err, user) {
assert.equal(user.location, "Argentinia");
finished();
});
});
},
"test: authenticate user and update location to France" : function(assert, finished, test) {
test.github.authenticate(username, token);
test.userApi.update(username, {location: "France"}, function(err) {
test.userApi.show(username, function(err, user) {
assert.equal(user.location, "France");
finished();
});
});
},
"test: follow and unfollow fjakobs" : function(assert, finished, test) {
test.github.authenticate(username, token);
test.userApi.follow("fjakobs", function(err) {
test.userApi.getFollowing(username, function(err, following) {
assert.ok(following.indexOf("fjakobs") !== -1);
test.userApi.unFollow("fjakobs", function(err) {
test.userApi.getFollowing(username, function(err, following) {
assert.ok(following.indexOf("fjakobs") === -1);
finished();
});
});
});
});
},
"test: get watched repos" : function(assert, finished, test) {
test.userApi.getWatchedRepos("fjakobs", function(err, repos) {
assert.ok(repos.length > 0);
assert.ok(repos[0].homepage !== undefined);
finished();
});
},
"test: get emails" : function(assert, finished, test) {
test.github.authenticate(username, token);
test.userApi.getEmails(function(err, mails) {
assert.ok(mails.indexOf("fabian@ajax.org") !== -1);
finished();
});
},
"test: add and remove email" : function(assert, finished, test) {
test.github.authenticate(username, token);
test.userApi.addEmail("juhu@ajax.org", function(err, mails) {
assert.ok(mails.indexOf("juhu@ajax.org") !== -1);
test.userApi.removeEmail("juhu@ajax.org", function(err, mails) {
assert.ok(mails.indexOf("juhu@ajax.org") === -1);
finished();
});
});
},
"test: get ssh keys" : function(assert, finished, test) {
test.github.authenticate(username, token);
test.userApi.getKeys(function(err, keys) {
assert.ok(keys[0].title !== undefined);
finished();
});
},
"test: add and remove ssh keys" : function(assert, finished, test) {
var sshKey = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq3iNw6EbjbV7M+Y74bMaRJ2V4fhGbpCPf4r5LziRlbkwZ2odG3Zkxzvhgg6EGxh6M4PWwiTF/gK/2nk81aAGN8iKvqS8b8TML/0RHrYyvR2Okug+CR5LbLVO+yM23nAixadhrZqTreqqgjJvqF4ffD0rsfVyqaYAsNxDoqvLFaEyMqh0+gNsO20M1jRLjQqeA4gzvQhjMWSnzOzBpCorCECjhl9o7iqitDaTzUWPLB4V0jnuyG15nbDOrCmzA8l9wIrqSjI6Kglx2aZWRKcsEaCUPHD5n4F63og+8aHRPMaEvNCvKj/21a0/zhEtdh1Vd3etmfe38Rh4WmOyuv5L+Q== test@ajax.org";
test.github.authenticate(username, token);
test.userApi.addKey("test2", sshKey, function(err, keys) {
var key = keys.filter(function(key) { return key.title == "test2"; })[0];
assert.equal(key.key, sshKey.replace(" test@ajax.org", ""));
test.userApi.removeKey(key.id, function(err, keys) {
var key = keys.filter(function(key) { return key.title == "test2"; })[0];
assert.equal(key, undefined);
finished();
});
});
}
});
if (module === require.main) {
async_testing.runSuites({UserApi: suite});
}
\ No newline at end of file
module.exports = function(host, filename, forceFetch) {
this.filename = filename
this.host = host
this.forceFetch = forceFetch
}
module.exports.prototype = {
markdown: require('markdown'),
changelogFile: __dirname + "/../../views/partials/changelog.ejs",
fs: require("fs"),
fetchChangelog: function(callback) {
var self = this
, https = require("https")
, changelog = []
https.get({ host: this.host, path: this.filename }, function(res) {
res.setEncoding('utf8')
res.on('data', function(data) { changelog.push(data.toString()) })
res.on("end", function() { callback(changelog.join("")) })
}).on("error", function(err) {
console.log(err)
})
},
transformChangelog: function(markdownChangelog) {
return this.markdown
.toHTML(markdownChangelog)
.replace(/h1/g, 'h2')
.replace(/<ul>/g, "<div class='pre_like'><ul>")
.replace(/<\/ul>/g, "</ul></div>")
},
writeChangelog: function(callback) {
var self = this
this.fetchChangelog(function(data) {
var dataParts = data.toString().split(/# (.*?) #/).reverse(),
changelog = []
dataParts.pop()
for(var i = 0; i < dataParts.length; i++) {
if(i%2 != 1) continue
var headline = "# " + dataParts[i] + " #\n",
content = dataParts[i-1].replace (/^\s+/, '').replace (/\s+$/, '')
changelog.push('<div><a name="' + dataParts[i] + '"></a>' + self.transformChangelog(headline + content) + '<br></div>')
}
self.fs.writeFile(self.changelogFile, changelog.join('<div class="seperator"></div>'), callback)
})
},
run: function() {
var self = this,
sys = require("sys")
sys.log("Changelog will be updated now!")
self.writeChangelog(function() {
sys.log("Changelog written!")
})
}
}
/*
Call it:
var changelogImporter = new ChangelogImporter(filename, host)
changelogImporter.run()
*/
\ No newline at end of file
var sys = require("sys"),
fs = require("fs")
module.exports = function(forceFetch) {
var GitHubApi = require(__dirname + "/../node-github/lib/github").GitHubApi
this.github = new GitHubApi(true)
this.forceFetch = forceFetch
this.lastUpdateFile = __dirname + "/../../tmp/examplesUpdatedAt.log"
}
module.exports.prototype = {
fetchExamples: function(callback) {
var self = this,
objectApi = this.github.getObjectApi(),
examples = {},
addExample = function(path, treeSha, callback) {
objectApi.showBlob('sdepold', 'sequelize', treeSha, path, function(err, blob) {
var pathSplit = path.split("/"),
example = pathSplit[pathSplit.length - 2],
file = pathSplit[pathSplit.length - 1]
examples[example] = examples[example] || []
examples[example].push({ filename: file, data: blob.data })
callback()
})
}
this.github.getRepoApi().getRepoBranches('sdepold', 'sequelize', function(err, branches) {
var treeSha = branches.master
objectApi.listBlobs('sdepold', 'sequelize', treeSha, function(err, blobs) {
if(err) throw new Error(err)
var exampleCount = Object.keys(blobs).filter(function(name){ return name.indexOf("examples/") == 0 }).length
for(var path in blobs) {
if(path.indexOf("examples/") == 0) {
var finished = 0
addExample(path, treeSha, function() {
if(++finished == exampleCount) callback(examples)
})
}
}
})
})
},
fetchedDataToExamples: function(data) {
var result = []
for(var exampleName in data) {
var singleData = data[exampleName],
example = { filename: exampleName + ".ejs", name: exampleName, files: [] },
trim = function(stringToTrim) {
return stringToTrim.replace(/^\s+|\s+$/g,"");
}
singleData = singleData.sort(function(a,b) {
return (a.filename.toLowerCase() < b.filename.toLowerCase()) ? -1 : 1
})
singleData.forEach(function(file) {
var content = file.data,
description = ""
if((content.indexOf("/*") == 0) && (content.indexOf("*/") > 0)) {
var split = content.split("/*")[1].split("*/"),
comment = trim(split[0])
content = split[1]
description = comment
if(comment.indexOf('Title:') != -1) {
split = comment.split('Title:')[1].split('\n')
if(file.filename == "app.js")
example.name = trim(split[0])
description = trim(split.filter(function(s) { return trim(s) != example.name }).join("\n"))
}
}
example.files.push({filename: file.filename, description: description, code: content})
})
result.push(example)
}
return result
},
examplesToNavigation: function(examples) {
return examples.map(function(example) {
return '"<a href=\\"/examples/' + example.filename.replace(".ejs", "") + '\\">' + example.name + '</a>"'
}).join(",\n")
},
writeExamples: function(examples) {
var self = this
examples.forEach(function(example) {
var template = fs.readFileSync(__dirname + '/../../views/examples/exampleTemplate.ejs', "utf8"),
content = require('ejs').render(template, { locals: {
title: example.name,
files: example.files,
navigation: self.examplesToNavigation(examples)
}})
fs.writeFileSync(__dirname + "/../../views/examples/" + example.filename, content)
})
},
run: function() {
var self = this
sys.log('Updating examples!')
this.fetchExamples(function(data) {
var examples = self.fetchedDataToExamples(data)
examples = examples.sort(function(a, b) {
return (a.name.toLowerCase() < b.name.toLowerCase()) ? -1 : 1
})
self.writeExamples(examples)
self.lastUpdatedAt = +new Date()
sys.log("Finished updating examples!")
})
}
}
\ No newline at end of file
{
"name": "sequelizejs.com",
"description": "The official sequelize webite.",
"version": "0.4.3",
"homepage": "http://sequelizejs.com",
"repository": {
"type": "git",
"url": "git://github.com/sdepold/sequelize.git"
},
"author": "Sascha Depold <sascha@depold.com> (http://depold.com)",
"directories": {
"lib": "lib"
},
"engines": {
"node": "*"
},
"dependencies": {
"koala": ">=0.1.2",
"markdown": ">=0.2.1"
}
}
\ No newline at end of file
This diff could not be displayed because it is too large.
body {
padding: 50px;
font-size: 14px;
font-family: "Helvetica Neue", Verdana;
line-height: 1.5;
}
h2 {
margin: 0px;
}
.active {
text-decoration: underline !important;
}
.bordered {
-moz-border-radius: 15px;
border-radius: 15px;
padding: 20px;
border: 1px solid #888;
color: white;
background-color: rgba(0, 0, 0, 0.7);
box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
-o-box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
-webkit-box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
-moz-box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
}
#wrapper {
text-align: center;
padding: 0 200px;
}
#navigation, #content, #footer {
width: 800px;
text-align: justify;
margin: 0px auto;
}
#footer {
margin-top: 15px;
color: white;
text-align: center;
}
#footer a {
color: white;
}
#navigation {
margin-bottom: 15px;
padding: 10px 20px;
}
#navigation a {
color: white;
display: block;
text-decoration: none;
font-size: 16px;
font-weight: bold;
}
#navigation a:hover {
text-decoration: underline;
}
#sidebar {
float: left;
position: fixed;
width: 140px;
}
#sidebar a {
color: white;
padding: 5px 0px;
display: block;
text-decoration: none;
}
#sidebar a:hover {
text-decoration: underline;
}
pre, .pre_like {
border: 1px solid #888;
-moz-border-radius: 5px;
border-radius: 5px;
padding: 5px;
background-color: rgba(43, 32, 28, 0.7);
}
.comment {
color: grey;
}
.string {
color: #04d80d;
}
.regexp {
color: #2fe420;
}
.number {
color: #44aa43;
}
.class, .this {
color: #8ac9f2;
}
.inst.variable, .class.variable, .global.variable {
color: #2f5fe0;
}
.keyword {
font-weight: bold;
color: #43a8ed;
}
.seperator {
border-top: 1px solid white;
height: 1px;
overflow: hidden;
margin-bottom: 10px;
}
#forkBadge {
position: fixed;
top: 0px;
right: 0px;
}
#forkBadge img {
border: none;
}
#changelog p {
margin: 0px;
}
#changelog h3 {
margin: 5px 0px;
}
#changelog .pre_like {
margin: 10px 0px;
}
#changelog ul {
margin: 5px 0px;
padding-left: 30px;
padding-bottom: 0px;
}
body {
padding: 50px;
font-size: 14px;
font-family: "Helvetica Neue", Verdana;
line-height: 1.5;
}
h2 {
margin: 0px
}
.active {
text-decoration: underline !important;
}
.bordered {
-moz-border-radius: 15px;
border-radius: 15px;
padding: 20px;
border: 1px solid #888;
color: white;
background-color: rgba(0, 0, 0, 0.7);
box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
-o-box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
-webkit-box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
-moz-box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
}
#wrapper{ text-align:center; padding:0 200px; }
#navigation, #content, #footer {
width: 800px;
text-align: justify;
margin:0px auto;
}
#footer {
margin-top: 15px;
color: white;
text-align: center;
a { color: white; }
}
#navigation {
margin-bottom: 15px;
padding: 10px 20px;
a {
color: white;
display: block;
text-decoration: none;
font-size: 16px;
font-weight: bold;
&:hover {
text-decoration: underline;
}
}
}
#sidebar {
float: left;
position: fixed;
width: 140px;
a {
color: white;
padding: 5px 0px;
display: block;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
pre, .pre_like {
border: 1px solid #888;
-moz-border-radius: 5px;
border-radius: 5px;
padding: 5px;
background-color: rgba(43, 32, 28, 0.7);
}
.comment { color: grey }
.string { color: #04D80D }
.regexp { color: #2FE420 }
.number { color: #44AA43 }
.class, .this { color: #8AC9F2 }
.inst.variable, .class.variable, .global.variable { color: #2F5FE0 }
.keyword { font-weight: bold; color: #43A8ED }
.seperator {
border-top: 1px solid white;
height: 1px;
overflow: hidden;
margin-bottom: 10px
}
#forkBadge {
position: fixed;
top: 0px;
right: 0px;
img {
border: none
}
}
#changelog {
p { margin: 0px }
h3 { margin: 5px 0px }
.pre_like { margin: 10px 0px }
ul {
margin: 5px 0px;
padding-left: 30px;
padding-bottom: 0px;
}
}
\ No newline at end of file
// Run $ expresso
/**
* Module dependencies.
*/
var app = require('../app');
module.exports = {
'GET /': function(assert){
assert.response(app,
{ url: '/' },
{ status: 200, headers: { 'Content-Type': 'text/html; charset=utf-8' }},
function(res){
assert.includes(res.body, '<title>Express</title>');
});
}
};
\ No newline at end of file
<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function() {
buildNavigation([], [])
})
</script>
<div id="changelog">
<a name="changelog"></a>
<h1>Changelog</h1>
</div>
<div class="seperator"></div>
<%- partial("changelog.ejs") %>
\ No newline at end of file
<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function() {
buildNavigation([], ["<br />", "<a href=\"/examples/Count\">Count</a>",
"<a href=\"/examples/DefaultValues\">Default values</a>",
"<a href=\"/examples/fetchAssociations\">fetchAssociations</a>",
"<a href=\"/examples/MethodPassing\">MethodPassing</a>",
"<a href=\"/examples/Performance\">Performance</a>",
"<a href=\"/examples/SequelizeWithOptions\">SequelizeWithOptions</a>",
"<a href=\"/examples/ChainQueries\">Using the chainQueries function</a>",
"<a href=\"/examples/UsingMultipleModelFiles\">UsingMultipleModelFiles</a>",
"<a href=\"/examples/Associations\">Working with associations</a>"], { seperator: ' ' })
})
</script>
<div>
<a name="sequelize"></a>
<h1>Working with associations</h1>
<p></p>
</div>
<div class="seperator"></div>
<div>
<a name="app.js"></a>
<h2>app.js</h2>
<p>
This example demonstrates the use of associations.
First of all, Person is getting associated via many-to-many with other Person objects (e.g. Person.hasMany('brothers')).
Afterwards a Person becomes associated with a 'father' and a mother using a one-to-one association created by hasOneAndBelongsTo.
The last association has the type many-to-one and is defined by the function hasManyAndBelongsTo.
The rest of the example is about setting and getting the associated data.
<pre>
var Sequelize = require(__dirname + &quot;/../../lib/sequelize/Sequelize&quot;).Sequelize,
sequelize = new Sequelize(&quot;sequelize_test&quot;, &quot;root&quot;, null, {disableLogging: true}),
Person = sequelize.define('person', {
name: Sequelize.STRING
}),
Pet = sequelize.define('pet', {
name: Sequelize.STRING
})
Person.hasMany('brothers')
Person.hasMany('sisters')
Person.hasOneAndBelongsTo('father', Person)
Person.hasOneAndBelongsTo('mother', Person)
Person.hasManyAndBelongsTo('pets', Pet, 'owner')
Sequelize.chainQueries([{drop: sequelize}, {sync: sequelize}], function() {
var person = new Person({ name: 'Luke' }),
mother = new Person({ name: 'Jane' }),
father = new Person({ name: 'John' }),
brother = new Person({ name: 'Brother' }),
sister = new Person({ name: 'Sister' }),
pet = new Pet({ name: 'Bob' })
Sequelize.chainQueries({save: [person, mother, father, brother, sister, pet]}, function() {
person.setMother(mother, function(mom) { Sequelize.Helper.log('my mom: ' + mom.name) })
person.setFather(father, function(dad) { Sequelize.Helper.log('my dad: ' + dad.name) })
person.setBrothers([brother], function(bros) { Sequelize.Helper.log(&quot;ma bro: &quot; + bros[0].name)})
person.setSisters([sister], function(sis) { Sequelize.Helper.log(&quot;ma sis: &quot; + sis[0].name)})
person.setPets([pet], function(pets) { Sequelize.Helper.log('my pet: ' + pets[0].name )})
})
})</pre>
</p>
</div>
<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function() {
buildNavigation([], ["<br />", "<a href=\"/examples/Count\">Count</a>",
"<a href=\"/examples/DefaultValues\">Default values</a>",
"<a href=\"/examples/fetchAssociations\">fetchAssociations</a>",
"<a href=\"/examples/MethodPassing\">MethodPassing</a>",
"<a href=\"/examples/Performance\">Performance</a>",
"<a href=\"/examples/SequelizeWithOptions\">SequelizeWithOptions</a>",
"<a href=\"/examples/ChainQueries\">Using the chainQueries function</a>",
"<a href=\"/examples/UsingMultipleModelFiles\">UsingMultipleModelFiles</a>",
"<a href=\"/examples/Associations\">Working with associations</a>"], { seperator: ' ' })
})
</script>
<div>
<a name="sequelize"></a>
<h1>Using the chainQueries function</h1>
<p></p>
</div>
<div class="seperator"></div>
<div>
<a name="app.js"></a>
<h2>app.js</h2>
<p>
This example demonstrates the use of chainQueries.
<pre>
var Sequelize = require(__dirname + &quot;/../../lib/sequelize/Sequelize&quot;).Sequelize
var sys = require(&quot;sys&quot;)
var Class = function(){ sys.log(&quot;You've just created a new instance!&quot;) }
Class.prototype.add = function(a,b,callback){
this.result = a + b
sys.log(&quot;The result: &quot; + this.result)
callback(this.result)
}
sys.log(&quot;First of all the old and obsolete way:&quot;)
Sequelize.chainQueries([
{add: (new Class()), params: [1, 2]},
{add: (new Class()), params: [2, 3]}
], function() {
sys.log(&quot;And we did it!&quot;)
})
sys.puts(&quot;&quot;)
sys.log(&quot;The new fashioned way is about removing the array and pass an arbitrary amount of parameters!&quot;)
sys.log(&quot;Just pass as many hashes as you want, but at the end a function as callback!&quot;)
Sequelize.chainQueries(
{add: new Class(), params: [1, 2]},
{add: new Class(), params: [2, 3]},
function() { sys.log(&quot;And we did it! Great!&quot;) }
)
sys.puts(&quot;&quot;)
sys.log(&quot;As you see we add some values two times.&quot;)
sys.log(&quot;Let's say you want to call a method on multiple objects with the same or no parameters!&quot;)
Sequelize.chainQueries(
{add: [new Class(), new Class()], params: [1, 2]},
function() { sys.log(&quot;And we did it! Great!&quot;) }
)</pre>
</p>
</div>
<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function() {
buildNavigation([], ["<br />", "<a href=\"/examples/Count\">Count</a>",
"<a href=\"/examples/DefaultValues\">Default values</a>",
"<a href=\"/examples/fetchAssociations\">fetchAssociations</a>",
"<a href=\"/examples/MethodPassing\">MethodPassing</a>",
"<a href=\"/examples/Performance\">Performance</a>",
"<a href=\"/examples/SequelizeWithOptions\">SequelizeWithOptions</a>",
"<a href=\"/examples/ChainQueries\">Using the chainQueries function</a>",
"<a href=\"/examples/UsingMultipleModelFiles\">UsingMultipleModelFiles</a>",
"<a href=\"/examples/Associations\">Working with associations</a>"], { seperator: ' ' })
})
</script>
<div>
<a name="sequelize"></a>
<h1>Count</h1>
<p></p>
</div>
<div class="seperator"></div>
<div>
<a name="app.js"></a>
<h2>app.js</h2>
<p>
<pre>var Sequelize = require(__dirname + &quot;/../../lib/sequelize/Sequelize&quot;).Sequelize,
sequelize = new Sequelize(&quot;sequelize_test&quot;, &quot;root&quot;, null, { disableLogging: true })
var Person = sequelize.define('person', { name: Sequelize.STRING })
Sequelize.chainQueries({drop: sequelize}, {sync: sequelize}, function() {
var count = 10,
queries = []
for(var i = 0; i &lt; count; i++) {
var p = new Person({name: 'someone' + (i%3)})
queries.push({ save: p })
}
Sequelize.Helper.log(&quot;Begin to save &quot; + count + &quot; items!&quot;)
Sequelize.chainQueries(queries, function() {
Sequelize.Helper.log(&quot;Finished!&quot;)
Person.count(function(count) {
Sequelize.Helper.log(&quot;Counted &quot; + count + &quot; elements!&quot;)
})
Person.count({name: 'someone2'}, function(count) {
Sequelize.Helper.log(&quot;Counted &quot; + count + &quot; elements with name = someone2!&quot;)
})
})
})</pre>
</p>
</div>
<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function() {
buildNavigation([], ["<br />", "<a href=\"/examples/Count\">Count</a>",
"<a href=\"/examples/DefaultValues\">Default values</a>",
"<a href=\"/examples/fetchAssociations\">fetchAssociations</a>",
"<a href=\"/examples/MethodPassing\">MethodPassing</a>",
"<a href=\"/examples/Performance\">Performance</a>",
"<a href=\"/examples/SequelizeWithOptions\">SequelizeWithOptions</a>",
"<a href=\"/examples/ChainQueries\">Using the chainQueries function</a>",
"<a href=\"/examples/UsingMultipleModelFiles\">UsingMultipleModelFiles</a>",
"<a href=\"/examples/Associations\">Working with associations</a>"], { seperator: ' ' })
})
</script>
<div>
<a name="sequelize"></a>
<h1>Default values</h1>
<p></p>
</div>
<div class="seperator"></div>
<div>
<a name="app.js"></a>
<h2>app.js</h2>
<p>
This example demonstrates the use of default values for defined model fields. Instead of just specifying the datatype,
you have to pass a hash with a type and a default. You also might want to specify either an attribute can be null or not!
<pre>
var Sequelize = require(__dirname + &quot;/../../lib/sequelize/Sequelize&quot;).Sequelize,
sequelize = new Sequelize(&quot;sequelize_test&quot;, &quot;root&quot;, null),
User = sequelize.define('User', {
name: { type: Sequelize.STRING, allowNull: false},
isAdmin: { type: Sequelize.BOOLEAN, allowNull: false, default: false }
}),
user = new User({ name: 'Someone' })
Sequelize.chainQueries([{drop: User}, {sync: User}], function() {
user.save(function(user) {
Sequelize.Helper.log(&quot;user.isAdmin should be the default value (false): &quot; + user.isAdmin)
user.updateAttributes({ isAdmin: true }, function(user) {
Sequelize.Helper.log(&quot;user.isAdmin was overwritten to true: &quot; + user.isAdmin)
})
})
})</pre>
</p>
</div>
<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function() {
buildNavigation([], ["<br />", "<a href=\"/examples/Count\">Count</a>",
"<a href=\"/examples/DefaultValues\">Default values</a>",
"<a href=\"/examples/fetchAssociations\">fetchAssociations</a>",
"<a href=\"/examples/MethodPassing\">MethodPassing</a>",
"<a href=\"/examples/Performance\">Performance</a>",
"<a href=\"/examples/SequelizeWithOptions\">SequelizeWithOptions</a>",
"<a href=\"/examples/ChainQueries\">Using the chainQueries function</a>",
"<a href=\"/examples/UsingMultipleModelFiles\">UsingMultipleModelFiles</a>",
"<a href=\"/examples/Associations\">Working with associations</a>"], { seperator: ' ' })
})
</script>
<div>
<a name="sequelize"></a>
<h1>MethodPassing</h1>
<p></p>
</div>
<div class="seperator"></div>
<div>
<a name="app.js"></a>
<h2>app.js</h2>
<p>
<pre>var Sequelize = require(__dirname + &quot;/../../lib/sequelize/Sequelize&quot;).Sequelize,
sequelize = new Sequelize(&quot;sequelize_test&quot;, &quot;test&quot;, &quot;test&quot;, {disableLogging: true})
// model definition
var Task = sequelize.define(&quot;Task&quot;, {
name: Sequelize.STRING,
deadline: Sequelize.DATE,
importance: Sequelize.INTEGER
}, {
classMethods: {
setImportance: function(newImportance, callback) {
Task.findAll(function(allTasks) {
var queries = []
allTasks.forEach(function(task) {
queries.push({updateAttributes: task, params: [{ importance: newImportance }]})
})
Sequelize.chainQueries(queries, callback)
})
}
},
instanceMethods: {
hasDeadlinePassed: function() {
return (this.deadline &lt; new Date())
}
}
})
// instance creation
var task1 = new Task({
name: 'Choose a nice MySQL connector',
deadline: new Date(Date.parse(&quot;Jul 8, 2100&quot;)),
importance: 10
}),
task2 = new Task({
name: 'Build the rest',
deadline: new Date(Date.parse(&quot;Jul 8, 2005&quot;)),
importance: 90
})
Task.drop(function(table, error) {
if(error) return Sequelize.Helper.log(error)
Task.sync(function(table, error) {
if(error) return Sequelize.Helper.log(error)
task1.save(function() {
task2.save(function() {
Sequelize.Helper.log(&quot;should be false: &quot; + task1.hasDeadlinePassed())
Sequelize.Helper.log(&quot;should be true: &quot; + task2.hasDeadlinePassed())
Sequelize.Helper.log(&quot;should be 10: &quot; + task1.importance)
Task.setImportance(30, function() {
Task.findAll(function(tasks) {
tasks.forEach(function(task) {
Sequelize.Helper.log(&quot;should be 30: &quot; + task.importance)
})
})
})
})
})
})
})</pre>
</p>
</div>
<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function() {
buildNavigation([], ["<br />", "<a href=\"/examples/Count\">Count</a>",
"<a href=\"/examples/DefaultValues\">Default values</a>",
"<a href=\"/examples/fetchAssociations\">fetchAssociations</a>",
"<a href=\"/examples/MethodPassing\">MethodPassing</a>",
"<a href=\"/examples/Performance\">Performance</a>",
"<a href=\"/examples/SequelizeWithOptions\">SequelizeWithOptions</a>",
"<a href=\"/examples/ChainQueries\">Using the chainQueries function</a>",
"<a href=\"/examples/UsingMultipleModelFiles\">UsingMultipleModelFiles</a>",
"<a href=\"/examples/Associations\">Working with associations</a>"], { seperator: ' ' })
})
</script>
<div>
<a name="sequelize"></a>
<h1>Performance</h1>
<p></p>
</div>
<div class="seperator"></div>
<div>
<a name="app.js"></a>
<h2>app.js</h2>
<p>
<pre>var Sequelize = require(__dirname + &quot;/../../lib/sequelize/Sequelize&quot;).Sequelize,
sequelize = new Sequelize(&quot;sequelize_test&quot;, &quot;root&quot;, null, { disableLogging: true })
var Person = sequelize.define('person', { name: Sequelize.STRING })
Sequelize.chainQueries([{drop: sequelize}, {sync: sequelize}], function() {
var start = Date.now(),
count = 10000,
queries = []
for(var i = 0; i &lt; count; i++) {
var p = new Person({name: 'someone'})
queries.push({ save: p })
}
Sequelize.Helper.log(&quot;Begin to save &quot; + count + &quot; items!&quot;)
Sequelize.chainQueries(queries, function() {
Sequelize.Helper.log(&quot;Saving &quot; + count + &quot; items took: &quot; + (Date.now() - start) + &quot;ms&quot;)
start = Date.now()
Sequelize.Helper.log(&quot;Will now read them from the database:&quot;)
Person.findAll(function(persons) {
Sequelize.Helper.log(&quot;Reading &quot; + persons.length + &quot; items took: &quot; + (Date.now() - start) + &quot;ms&quot;)
})
})
})</pre>
</p>
</div>
<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function() {
buildNavigation([], ["<br />", "<a href=\"/examples/Count\">Count</a>",
"<a href=\"/examples/DefaultValues\">Default values</a>",
"<a href=\"/examples/fetchAssociations\">fetchAssociations</a>",
"<a href=\"/examples/MethodPassing\">MethodPassing</a>",
"<a href=\"/examples/Performance\">Performance</a>",
"<a href=\"/examples/SequelizeWithOptions\">SequelizeWithOptions</a>",
"<a href=\"/examples/ChainQueries\">Using the chainQueries function</a>",
"<a href=\"/examples/UsingMultipleModelFiles\">UsingMultipleModelFiles</a>",
"<a href=\"/examples/Associations\">Working with associations</a>"], { seperator: ' ' })
})
</script>
<div>
<a name="sequelize"></a>
<h1>SequelizeWithOptions</h1>
<p></p>
</div>
<div class="seperator"></div>
<div>
<a name="app.js"></a>
<h2>app.js</h2>
<p>
<pre>var Sequelize = require(__dirname + &quot;/../../lib/sequelize/Sequelize&quot;).Sequelize,
sequelize = new Sequelize(&quot;sequelize_test&quot;, &quot;root&quot;, null, {
// use other database server or port
host: 'my.srv.tld',
port: 12345,
// disable logging
disableLogging: true
}),
Smth = sequelize.define('Smth', {foo: Sequelize.STRING})
Smth.sync(function(_, err) {
if(err) Sequelize.Helper.log(err)
else Sequelize.Helper.log('Hey we established the connection successfully! Woot!')
})</pre>
</p>
</div>
<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function() {
buildNavigation([], ["<br />", "<a href=\"/examples/Count\">Count</a>",
"<a href=\"/examples/DefaultValues\">Default values</a>",
"<a href=\"/examples/fetchAssociations\">fetchAssociations</a>",
"<a href=\"/examples/MethodPassing\">MethodPassing</a>",
"<a href=\"/examples/Performance\">Performance</a>",
"<a href=\"/examples/SequelizeWithOptions\">SequelizeWithOptions</a>",
"<a href=\"/examples/ChainQueries\">Using the chainQueries function</a>",
"<a href=\"/examples/UsingMultipleModelFiles\">UsingMultipleModelFiles</a>",
"<a href=\"/examples/Associations\">Working with associations</a>"], { seperator: ' ' })
})
</script>
<div>
<a name="sequelize"></a>
<h1>UsingMultipleModelFiles</h1>
<p></p>
</div>
<div class="seperator"></div>
<div>
<a name="app.js"></a>
<h2>app.js</h2>
<p>
<pre>var Sequelize = require(__dirname + &quot;/../../lib/sequelize/Sequelize&quot;).Sequelize,
sequelize = new Sequelize(&quot;sequelize_test&quot;, &quot;test&quot;, &quot;test&quot;),
Project = sequelize.import(__dirname + &quot;/Project&quot;).Project,
Task = sequelize.import(__dirname + &quot;/Task&quot;).Task
Project.hasMany('tasks', Task)
Task.belongsTo('project', Project)
sequelize.drop(function(errors) {
if(errors.length &gt; 0) return Sequelize.Helper.log(errors)
sequelize.sync(function(errors) {
if(errors.length &gt; 0) return Sequelize.Helper.log(errors)
new Project({
name: 'Sequelize',
description: 'A nice MySQL ORM for NodeJS'
}).save(function(project) {
var task1 = new Task({
name: 'Choose a nice MySQL connector',
deadline: new Date(),
importance: 10
})
var task2 = new Task({
name: 'Build the rest',
deadline: new Date(),
importance: 90
})
Sequelize.chainQueries([{save: task1}, {save: task2}], function() {
project.setTasks([task1, task2], function(tasks) {
Sequelize.Helper.log(project)
Sequelize.Helper.log(tasks)
})
})
})
})
})</pre>
</p>
</div>
<div class="seperator"></div>
<div>
<a name="Project.js"></a>
<h2>Project.js</h2>
<p>
<pre>exports.getProjectClass = function(Sequelize, sequelize) {
var Project = sequelize.define(&quot;Project&quot;, {
name: Sequelize.STRING,
description: Sequelize.TEXT
})
/*
Here comes further Project logic
*/
}</pre>
</p>
</div>
<div class="seperator"></div>
<div>
<a name="Task.js"></a>
<h2>Task.js</h2>
<p>
<pre>exports.getTaskClass = function(Sequelize, sequelize) {
var Task = sequelize.define(&quot;Task&quot;, {
name: Sequelize.STRING,
deadline: Sequelize.DATE,
importance: Sequelize.INTEGER
})
/*
Here comes further Task logic
*/
}</pre>
</p>
</div>
<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function() {
buildNavigation([], ["<br />", <%- navigation %>], { seperator: ' ' })
})
</script>
<div>
<a name="sequelize"></a>
<h1><%= title %></h1>
<p></p>
</div>
<% files.forEach(function(file) { %>
<div class="seperator"></div>
<div>
<a name="<%= file.filename %>"></a>
<h2><%= file.filename %></h2>
<p>
<%= file.description %>
<pre><%= file.code %></pre>
</p>
</div>
<% }) %>
\ No newline at end of file
<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function() {
buildNavigation([], ["<br />", "<a href=\"/examples/Count\">Count</a>",
"<a href=\"/examples/DefaultValues\">Default values</a>",
"<a href=\"/examples/fetchAssociations\">fetchAssociations</a>",
"<a href=\"/examples/MethodPassing\">MethodPassing</a>",
"<a href=\"/examples/Performance\">Performance</a>",
"<a href=\"/examples/SequelizeWithOptions\">SequelizeWithOptions</a>",
"<a href=\"/examples/ChainQueries\">Using the chainQueries function</a>",
"<a href=\"/examples/UsingMultipleModelFiles\">UsingMultipleModelFiles</a>",
"<a href=\"/examples/Associations\">Working with associations</a>"], { seperator: ' ' })
})
</script>
<div>
<a name="sequelize"></a>
<h1>fetchAssociations</h1>
<p></p>
</div>
<div class="seperator"></div>
<div>
<a name="app.js"></a>
<h2>app.js</h2>
<p>
<pre>var Sequelize = require(__dirname + &quot;/../../lib/sequelize/Sequelize&quot;).Sequelize,
sequelize = new Sequelize(&quot;sequelize_test&quot;, &quot;root&quot;, null, {disableLogging: false})
var Person = sequelize.define('person', {
name: Sequelize.STRING
})
var Pet = sequelize.define('pet', {
name: Sequelize.STRING
})
Person.hasManyAndBelongsTo('pets', Pet, 'owner')
Sequelize.chainQueries([{drop: sequelize}, {sync: sequelize}], function() {
var person = new Person({ name: 'Luke' }),
pet1 = new Pet({ name: 'Bob' }),
pet2 = new Pet({ name: 'Aaron' })
Sequelize.chainQueries([{save: person}, {save: pet1}, {save: pet2}], function() {
person.setPets([pet1], function(pets) {
Sequelize.Helper.log('my pet: ' + pets[0].name )
Sequelize.Helper.log(&quot;Now let's get the same data with fetchData!&quot;)
person.fetchAssociations(function(data) {
Sequelize.Helper.log(&quot;And here we are: &quot; + data.pets[0].name)
Sequelize.Helper.log(&quot;The object should now also contain the data: &quot; + person.fetchedAssociations.pets[0].name)
Sequelize.Helper.log('This won\'t do a database request!')
person.getPets(function(pets) {
Sequelize.Helper.log(&quot;Pets: &quot; + pets.map(function(pet) { return pet.name }).join(&quot;, &quot;))
Sequelize.Helper.log(&quot;Let's associate with another pet...&quot;)
person.setPets([pet1, pet2], function() {
Sequelize.Helper.log(&quot;The set call has stored the pets as associated data!&quot;)
Sequelize.Helper.log(&quot;And now let's find the pets again! This will make no new database request but serve the already stored pets Bob and Aaron!&quot;)
person.getPets(function(pets) {
Sequelize.Helper.log(&quot;Pets: &quot; + pets.map(function(pet) { return pet.name }).join(&quot;, &quot;))
Sequelize.Helper.log(&quot;Now let's force the reloading of pets!&quot;)
person.getPets({refetchAssociations: true}, function(pets) {
Sequelize.Helper.log(&quot;Pets: &quot; + pets.map(function(pet) { return pet.name }).join(&quot;, &quot;))
Person.find(person.id, { fetchAssociations: true }, function(p) {
var petNames = p.fetchedAssociations.pets.map(function(pet) { return pet.name }).join(&quot;, &quot;)
Sequelize.Helper.log('Works with find as well: ' + petNames)
})
Person.findAll({ fetchAssociations: true }, function(people) {
var petNames = people[0].fetchedAssociations.pets.map(function(pet) { return pet.name }).join(&quot;, &quot;)
Sequelize.Helper.log('And also with findAll: ' + petNames)
})
})
})
})
})
})
})
})
})</pre>
</p>
</div>
<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function() { buildNavigation([], []) })
</script>
<div>
<a name="sequelize"></a>
<h1>Sequelize</h1>
<p>
The Sequelize library provides easy access to a MySQL database by mapping database
entries to objects and vice versa. To put it in a nutshell... it's an ORM (Object-Relational-Mapper).
The library is written entirely in JavaScript and can be used in the Node.JS environment.
</p>
</div>
<div class="seperator"></div>
<div>
<a name="installation"></a>
<h2>Installation</h2>
<p>
Sequelize will have a Kiwi package in future. For now, you can install it via NPM or just download
the code from the git repository and require Sequelize.js:
<pre><%= partial("installation.ejs") %></pre>
This will make the class Sequelize available.
</p>
</div>
<div class="seperator"></div>
<div>
<a name="basicMapping"></a>
<h2>Basic Mapping</h2>
<p>
To get the ball rollin' you first have to create an instance of Sequelize. Use it the following way:
<pre><%- koala.render(".js", "var sequelize = new Sequelize('database', 'username', 'password')") %></pre>
This will save the passed database credentials and provide all further methods. Furthermore you can specify
a non-default host or port and some options:
<pre><%- koala.render(".js", partial("advancedInstantiation.ejs")) %></pre>
To define mappings between a class (Stop telling me that JavaScript don't know classes. Name it however you want to!)
and a table, use the define method:
<pre><%- koala.render(".js", partial("basicMapping1.ejs")) %></pre>
Sequelize currently supports the following datatypes:
<pre><%= partial("basicMapping2.ejs") %></pre>
You can also store your model definitions in a single file using the import method:
<pre><%- koala.render(".js", partial("basicMapping3.ejs")) %></pre>
Choose the name of the exported function the way you want. It doesn't matter at all. You can also specify multiple
models in one file. The import method will return a hash, which stores the result of sequelize.define under the key <i>Project</i>.
</p>
</div>
<div class="seperator"></div>
<div>
<a name="sync"></a>
<h2>Synchronize with database</h2>
<p>
When starting a new project you won't have a database structure and using Sequelize you won't need to. Just specify
your model structures and let the library do the rest.<br><br>
Currently supported is the creation and deletion of tables:
<pre><%- koala.render(".js", partial("sync1.ejs")) %></pre>
Because synchronizing and dropping all of your tables might be a lot of lines to write, you can also let
Sequelize do the work for you:
<pre><%- koala.render(".js", partial("sync2.ejs")) %></pre>
</p>
</div>
<div class="seperator"></div>
<div>
<a name="models"></a>
<h2>Creating and working with instances</h2>
<p>
In order to create instances of defined classes just do it as follows:
<pre><%- koala.render(".js", partial("models1.ejs")) %></pre>
To save it in the database use the save method and pass a callback to it, if needed:
<pre><%- koala.render(".js", partial("models2.ejs")) %></pre>
Now lets change some values and save changes to the database... There are two ways to do that:
<pre><%- koala.render(".js", partial("models3.ejs")) %></pre>
</p>
</div>
<div class="seperator"></div>
<div>
<a name="expandingModels"></a>
<h2>Expanding models</h2>
<p>
Sequelize allows you to pass custom class and instance methods. Just do the following:
<pre><%- koala.render(".js", partial("expand.ejs")) %></pre>
</p>
</div>
<div class="seperator"></div>
<div>
<a name="chainQueries"></a>
<h2>Chain queries</h2>
<p>
Because you will want to save several items at once and just go on after all of them are saved, Sequelize provides a handy helper for that:
<pre><%- koala.render(".js", partial("chainQueries1.ejs")) %></pre>
And a real example:
<pre><%- koala.render(".js", partial("chainQueries2.ejs")) %></pre>
You can also pass params to the method... and of course you can also call other methods, which trigger a callback:
<pre><%- koala.render(".js", partial("chainQueries3.ejs")) %></pre>
</p>
</div>
<div class="seperator"></div>
<div>
<a name="associations"></a>
<h2>Associations</h2>
<p>
With Sequelize you can also specify associations between multiple classes. Doing so will help you to easily
access and set those associated objects. The library therefore provides for each defined class the method
the following methods:
<pre><%- koala.render(".js", partial("associations1.ejs")) %></pre>
Because Sequelize is doing a lot of magic, you have to call Sequelize#sync after setting the associations!
Doing so will allow you the following:
<pre><%- koala.render(".js", partial("associations2.ejs")) %></pre>
To remove created associations you can just call the set method without a specific id:
<pre><%- koala.render(".js", partial("associations3.ejs")) %></pre>
You can also do it vice versa:
<pre><%- koala.render(".js", partial("associations4.ejs")) %></pre>
For hasOne its basically the same:
<pre><%- koala.render(".js", partial("associations5.ejs")) %></pre>
In order to specify many-to-many associations you can use the following syntax:
<pre><%- koala.render(".js", partial("associations6.ejs")) %></pre>
This will create a table, named according to the specified association names (= MembersProjects),
which just stores the id of a project and a member. Don't forget to call the sync method of the sequelize
instance.<br><br>
Since v0.4.1 all association tables and association keys are named as the passed association names:
<pre><%- koala.render(".js", partial("associations7.ejs")) %></pre>
Sequelize v0.4.2 introduced a new possibility to load the associated objects from the database.
The relevant method is called <i>fetchAssociations</i> and returns a hash:
<pre><%- koala.render(".js", partial("associations8.ejs")) %></pre>
</p>
</div>
<div class="seperator"></div>
<div>
<a name="finding"></a>
<h2>Finding some objects</h2>
<p>
OK... you can define classes and associations. You can save them. You would probably like to get them from
the database again :-) Easy:
<pre><%- koala.render(".js", partial("finding.ejs")) %></pre>
Since v0.4.3 there is an option for find methods, which forces the load of associated data. The resulting objects
will store the data in the <i>fetchedAssociations</i> attribute:
<pre><%- koala.render(".js", partial("finding2.ejs")) %></pre>
</p>
</div>
<div class="seperator"></div>
<div>
<a name="projects"></a>
<h2>Projects using Sequelize</h2>
<p>
You are using Sequelize? Let me know and get listed here! Just send me a private message on github :-)
</p>
</div>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Sequelize &raquo; A MySQL Object-Relational-Mapper for NodeJS</title>
<link rel="stylesheet" href="/stylesheets/style.css">
<style type="text/css" media="screen">
body { background: url(/background) repeat top left fixed; }
</style>
<script type="text/javascript" charset="utf-8" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js"></script>
<!-- <script type="text/javascript" charset="utf-8" src="/javascripts/prototype.js"></script> -->
<script type="text/javascript" charset="utf-8">
var highlightNavigation = function(e) {
$$("#sidebar a").each(function(anchor) { anchor.removeClassName("active") })
$(e).addClassName("active")
}
var buildNavigation = function(additionalBefore, additionalAfter, options) {
options = options || {}
options.seperator = options.seperator || "<br />"
var navigationContent = "<h2>Navigation</h2><br />",
headline = null
navigationContent += additionalBefore.join(options.seperator)
$$("#content div a").each(function(e) {
if(headline = e.up().down("h2"))
navigationContent += "<a href='#" + e.name + "' onclick='highlightNavigation(this)'>" + headline.innerHTML + "</a>"
})
navigationContent += additionalAfter.join(options.seperator)
$("sidebar").update(navigationContent)
}
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-9039631-4']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div id="sidebar" class="bordered"></div>
<div id="wrapper">
<div id="navigation" class="bordered">
<table width="100%">
<tr>
<td align="center" width="33%"><a href="/">Documentation</a></td>
<td align="center" width="33%"><a href="/examples">Examples</a></td>
<td align="center" width="33%"><a href="/changelog">Changelog</a></td>
</tr>
</table>
</div>
<div id="content" class="bordered"><%- body %></div>
<div id="footer" class="bordered">
&copy; 2010 Layout | Code by <a href="http://depold.com" target="_blank">Sascha Depold</a>;
Website based on <a href="http://nodejs.org" target="_blank" rel="nofollow">NodeJS</a> and
<a href="http://expressjs.com" target="_blank" rel="nofollow">ExpressJS</a>.
</div>
</div>
<a href="http://github.com/sdepold/sequelize" id="forkBadge">
<img src="http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png" id="ribbon" alt="Fork me on GitHub">
</a>
</body>
</html>
\ No newline at end of file
var sequelize = new Sequelize('database', 'username', 'password', {
host: "my.server.tld",
port: 12345
})
// No need for password?
var sequelize = new Sequelize('database', 'username'[, null])
// Want no logging? Use that:
var sequelize = new Sequelize('database', 'username', 'password', {
disableLogging: true
})
// Since v0.4.3 you can disable the pluralization of table names:
var sequelize = new Sequelize('database', 'username', 'password', {
disableTableNameModification: true
})
sequelize.define('person', { /* ... */})
// will result in a table called >person< if that option is specified
// will result in a table called >people< if that option is not specified
\ No newline at end of file
// many to many association:
Class.hasMany('association name', AssociationClass, 'back association name')
// example
Project.hasMany('tasks', Task, 'projects')
// many to many association on the same class
Class.hasMany('association name')
// example
Person.hasMany('friends')
// one-to-one association
Class.hasOneAndBelongsTo('association name', AssociationClass)
// example
Person.hasOneAndBelongsTo('house', House, 'owner')
// one-to-many association
Class.hasManyAndBelongsTo('association name', AssociationClass, 'back association name')
// example
Person.hasManyAndBelongsTo('cars', Car, 'owner')
// one way associations
Class.hasMany('association name', AssociationClass)
Class.hasOne('association name', AssociationClass)
\ No newline at end of file
Project.hasManyAndBelongsTo('tasks', Task, 'project')
var project = new Project...
var task1 = new Task...
var task2 = new Task
// save them... and then:
project.setTasks([task1, task2], function(associatedTasks) {
// the associatedTasks are the very same as task1 and task2
})
// ok now they are save... how do I get them later on?
project.getTasks(function(associatedTasks) {
// bam
})
\ No newline at end of file
// remove the association with task1
project.setTasks([task2], function(associatedTasks) {
// you will get task2 only
})
// remove 'em all
projects.setTasks([], function(associatedTasks) {
// you will get an empty array
})
// project is associated with task1 and task2
task2.setProject(null, function(associatedProject) {
// will return no associations
})
\ No newline at end of file
Task.hasOne('author', Author)
Task.setAuthor(anAuthor)
\ No newline at end of file
Project.hasMany('members', Member, 'projects')
\ No newline at end of file
Person.hasOne('father', Person) // will create a foreign key 'fatherId'
Person.hasOne('mother', Person) // will create a foreign key 'motherId'
Person.hasMany('friends') // will create a table 'FriendsPeople' with friendId and personId
\ No newline at end of file
// Sequelize instantiation...
var Person = sequelize.define('person', { name: Sequelize.STRING })
var Pet = sequelize.define('pet', { name: Sequelize.STRING })
Person.hasManyAndBelongsTo('pets', Pet, 'owner')
// Table synchronization...
var person = new Person({ name: 'Luke' }),
pet1 = new Pet({ name: 'Bob' }),
pet2 = new Pet({ name: 'Aaron' })
// Save the objects and associate them...
person.fetchAssociations(function(assocs) {
// assocs == { pets: [pet1, pet2] }
})
\ No newline at end of file
var Project = sequelize.define('Project', {
title: Sequelize.STRING,
description: Sequelize.TEXT
})
var Task = sequelize.define('Task', {
title: Sequelize.STRING,
description: Sequelize.TEXT,
deadline: Sequelize.DATE
})
// You can also set some options:
var Foo = sequelize.define('Foo', {
// instantiating will automatically set the flag to true if not set
flag: { type: Sequelize.BOOLEAN, allowNull: false, default: true},
// setting no title will throw an error when trying to save
title: { type: Sequelize.STRING, allowNull: false}
})
\ No newline at end of file
Sequelize.STRING ===> VARCHAR(255)
Sequelize.TEXT ===> TEXT
Sequelize.INTEGER ===> INT
Sequelize.DATE ===> DATETIME
Sequelize.BOOLEAN ===> TINYINT(1)
\ No newline at end of file
// app.js
var Project = sequelize.import(__dirname + "/path/to/models/Project").Project
// Project.js
exports.getProjectClass = function(Sequelize, sequelize) {
sequelize.define("Project", {
name: Sequelize.STRING,
description: Sequelize.TEXT
})
}
\ No newline at end of file
Sequelize.chainQueries(
// push your items + method calls here
, function() {
// and here do some callback stuff
}
)
\ No newline at end of file
Sequelize.chainQueries(
{ save: project },
{ save: task },
// what is equal to: { save: [project, task] }
function() {
// woot! saved.
}
)
\ No newline at end of file
Sequelize.chainQueries(
{ methodWithParams: project, params: [1, 2, 3] },
function() {
// the method call will equal: project.methodWithParams(1, 2, 3, callback)
}
)
\ No newline at end of file
<div><a name="v0.4.4 - in development"></a><h2>v0.4.4 - in development</h2>
<div class='pre_like'><ul><li>select now supports array usage of fields</li><li>select now supports hash usage of where</li><li>Wrapped queries correctly using <code>foo</code></li><li>Added Model.count(callback), which returns the number of elements saved in the database</li><li>Merged israeldelahoz's changes for using created<em>at and updated</em>at instead of the camel cased version</li><li>using expresso 0.7.2</li><li>tests were working all the time</li><li>moved config for test database into seperated config file</li><li>TODO: Add method for adding and deleting single associations</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.4.3"></a><h2>v0.4.3</h2>
<div class='pre_like'><ul><li>renamed loadAssociatedData to fetchAssociations</li><li>renamed Model#associatedData to fetchedAssociations</li><li>added fetchAssociations to finder methods</li><li>store data found by finder method in the associatedData hash + grep them from there if reload is not forced</li><li>added option to sequelize constructor for disabling the pluralization of tablenames: disableTableNameModification</li><li>allow array as value for chainQueries =&gt; Sequelize.chainQueries([save: [a,b,c]], callback)</li><li>remove the usage of an array =&gt; Sequelize.chainQueries({save: a}, {destroy: b}, callback)</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.4.2"></a><h2>v0.4.2</h2>
<div class='pre_like'><ul><li>fixed bugs from 0.4.1</li><li>added the model instance method loadAssociatedData which adds the hash Model#associatedData to an instance which contains all associated data</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.4.1"></a><h2>v0.4.1</h2>
<div class='pre_like'><ul><li>THIS UPDATE CHANGES TABLE STRUCTURES MASSIVELY!</li><li><p>MAKE SURE TO DROP YOUR CURRENT TABLES AND LET THEM CREATE AGAIN!</p></li><li><p>names of many-to-many-association-tables are chosen from passed association names</p></li><li>foreign keys are chosen from passed association name</li><li>added many-to-many association on the same model</li><li>added hasManyAndBelongsTo</li><li>added hasOneAndBelongsTo</li><li>nodejs-mysql-native 0.4.2</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.4.0"></a><h2>v0.4.0</h2>
<div class='pre_like'><ul><li>added error handling when defining invalid database credentials</li><li>Sequelize#sync, Sequelize#drop, model#sync, model#drop returns errors via callback</li><li>code is now located under lib/sequelize to use it with nDistro</li><li>added possibility to use non default mysql database (host/port)</li><li>added error handling when defining invalid database port/host</li><li>schema definitions can now contain default values and null allowance</li><li>database credentials can now also contain an empty / no password</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.3.0"></a><h2>v0.3.0</h2>
<div class='pre_like'><ul><li>added possibility to define class and instance methods for models</li><li>added import method for loading model definition from a file</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.2.6"></a><h2>v0.2.6</h2>
<div class='pre_like'><ul><li>refactored Sequelize to fit CommonJS module conventions</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.2.5"></a><h2>v0.2.5</h2>
<div class='pre_like'><ul><li>added BOOLEAN type</li><li>added FLOAT type</li><li>fixed DATE type issue</li><li>fixed npm package</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.2.4"></a><h2>v0.2.4</h2>
<div class='pre_like'><ul><li>fixed bug when using cross associated tables (many to many associations)</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.2.3"></a><h2>v0.2.3</h2>
<div class='pre_like'><ul><li>added latest mysql connection library<div class='pre_like'><ul><li>fixed id handling on save</li><li>fixed text handling (varchar &gt; 255; text)</li></ul></div></li><li>using the inflection library for naming tables more convenient</li><li>Sequelize.TEXT is now using MySQL datatype TEXT instead of varchar(4000)</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.2.2"></a><h2>v0.2.2</h2>
<div class='pre_like'><ul><li>released project as npm package</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.2.1"></a><h2>v0.2.1</h2>
<div class='pre_like'><ul><li>fixed date bug</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.2.0"></a><h2>v0.2.0</h2>
<div class='pre_like'><ul><li>added methods for setting associations</li><li>added method for chaining an arbitraty amount of queries</li></ul></div><br></div><div class="seperator"></div><div><a name="v0.1.0"></a><h2>v0.1.0</h2>
<div class='pre_like'><ul><li>first stable version</li><li>implemented all basic functions</li><li>associations are working</li></ul></div><br></div>
\ No newline at end of file
var Foo = sequelize.define('Foo', { /* attributes */}, {
classMethods: {
method1: function(){ return 'smth' }
},
instanceMethods: {
method2: function() { return 'foo' }
}
})
// ==>
Foo.method1()
new Foo({}).method2()
\ No newline at end of file
Project.find(123, function(project) {
// project will be an instance of Project and stores the content of the table entry
// with id 123 if such an entry is not defined you will get null
})
Project.find({ title: 'aProject' }, function(project) {
// project will be the first entry of the Projects table with the title 'aProject' || null
})
Project.findAll(function(projects) {
// projects will be an array of all Project instances
})
Project.findAll({where: "name = 'A Project'"}, function(persons) {
// projects will be an array of Project instances with the specified name
})
\ No newline at end of file
Person.find(person.id, { fetchAssociations: true }, function(p) {
var petNames = p.fetchedAssociations.pets.map(function(pet) { return pet.name }).join(", ")
Sequelize.Helper.log('The person's pets: ' + petNames)
})
\ No newline at end of file
# npm:
npm install sequelize
var Sequelize = require("sequelize").Sequelize
# checkout:
cd path/to/lib
git clone git://github.com/sdepold/sequelize.git
var Sequelize = require(__dirname + "/lib/sequelize/lib/sequelize/Sequelize").Sequelize
\ No newline at end of file
var project = new Project({
title: 'my awesome project',
description: 'woot woot. this will make me a rich man'
})
var task = new Task({
title: 'specify the project idea',
description: 'bla',
deadline: new Date()
})
\ No newline at end of file
project.save(function() {
// my nice callback stuff
})
task.save(function() {
// some other stuff
})
new Task({ title: 'foo', description: 'bar', deadline: new Date()})
.save(function(anotherTask) {
// you can now access the currently saved task with the variable <i>anotherTask</i>... nice!
})
\ No newline at end of file
// way 1
task.title = 'a very different title now'
task.save(function(){})
// way 2
task.updateAttributes({
title: 'a very different title now'
}, function(){})
// create my nice tables:
Project.sync(callback)
Task.sync(callback)
// drop the tables:
Project.drop(callback)
Task.drop(callback)
// with error handling:
Project.[sync|drop](function(table, error) {
if(error) // oooh, did you entered wrong database credentials?
else // ok ... everything is nice!
})
\ No newline at end of file
// create all tables... now!
sequelize.sync(callback)
// and drop it!
sequelize.drop(callback)
// with error handling:
sequelize.[sync|drop](function(errors) {
if(errors.length > 0) // whooops
else // woot woot
})
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!