Skip to content

Commit

Permalink
support global configuration.
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenplusplus committed Sep 15, 2014
1 parent c550d09 commit 009ae90
Show file tree
Hide file tree
Showing 20 changed files with 562 additions and 192 deletions.
76 changes: 51 additions & 25 deletions docs/components/docs/docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,65 @@ <h1 class="page-title">Node.js</h1>
</header>

<section class="content">
<article>
<h1>{{module[0].toUpperCase() + module.substr(1)}}</h1>
<h1>{{module[0].toUpperCase() + module.substr(1)}}</h1>
<h3 class="sub-heading">
<div class="toggler" ng-click="showGcloudDocs = !showGcloudDocs">
<span class="toggle" ng-hide="showGcloudDocs"></span>
<span class="toggle" ng-show="showGcloudDocs"></span>
</div>
Getting Started with <code>gcloud</code>
</h3>
<article ng-if="showGcloudDocs">
<p>
First, install <code>gcloud</code> with npm and require it into your project:
</p>
<div hljs>$ npm install --save gcloud</div>
<div hljs>var gcloud = require('gcloud');</div>
<p>
There are a couple of ways to use the <code>gcloud</code> module.
</p>
<p>
If you are running your app on Google App Engine or Google Compute Engine, you won't need to worry about supplying connection configuration options to <code>gcloud</code>&mdash; we figure that out for you.
</p>
<p>
However, if you're running your app elsewhere, you will need to provide this information.
</p>
<div hljs>
// App Engine and Compute Engine
var gcloud = require('gcloud');

<article ng-if="isActiveDoc('datastore')">
<p>
The <code>gcloud.datastore</code> object gives you some convenience methods, as well as exposes a <code>Dataset</code> function. This will allow you to create a <code>Dataset</code>, which is the object from which you will interact with the Google Cloud Datastore.
</p>
<div hljs>
// Elsewhere
var gcloud = require('gcloud')({
keyFilename: '/path/to/keyfile.json'
});</div>
<p>
In any environment, you are free to provide these and other default properties, which eventually will be passed to the <code>gcloud</code> sub-modules (Datastore, Storage, etc.).
</p>
</article>
<hr>
<article ng-if="isActiveDoc('datastore')">
<h2>Overview</h2>
<p>
The <code>gcloud.datastore</code> object gives you some convenience methods, as well as exposes a <code>dataset</code> function. This will allow you to create a <code>dataset</code>, which is the object from which you will interact with the Google Cloud Datastore.
</p>
<div hljs>
var datastore = gcloud.datastore;
var dataset = new datastore.Dataset();</div>
<p ng-if="!isActiveUrl('/docs/datastore/dataset')">
See <a href="#/docs/datastore/dataset">the Dataset documentation</a> for examples of how to query the datastore, save entities, run a transaction, and others.
</p>
</article>

<article ng-if="isActiveDoc('storage')">
<p>
The <code>gcloud.storage</code> object contains a <code>Bucket</code> object, which is how you will interact with your Google Cloud Storage bucket.
</p>
<div hljs>
var storage = gcloud.storage;
var bucket = new storage.Bucket({
bucketName: 'MyBucket'
var dataset = datastore.dataset({
projectId: 'myProject',
keyFilename: '/path/to/keyfile.json'
});</div>
<p>
See examples below for more on how to upload a file, read from your bucket's files, create signed URLs, and more.
</p>
</article>
<p ng-if="!isActiveUrl('/docs/datastore/dataset')">
See <a href="#/docs/datastore/dataset">the Dataset documentation</a> for examples of how to query the datastore, save entities, run a transaction, and others.
</p>
</article>
<article ng-if="isActiveDoc('storage')">
<h2>Overview</h2>
<p>
The <code>gcloud.storage</code> object contains a <code>bucket</code> object, which is how you will interact with your Google Cloud Storage bucket. See the guide on <a href="https://developers.google.com/storage">Google Cloud Storage</a> to create a bucket.
</p>
<p>
See examples below for more on how to access your bucket to upload a file, read its files, create signed URLs, and more.
</p>
</article>

<article
Expand Down
5 changes: 4 additions & 1 deletion docs/components/docs/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ angular
return {
data: obj,
name: obj.ctx.name,
constructor: obj.tags.some(function(tag) {
return tag.type === 'constructor';
}),
description: $sce.trustAsHtml(
formatHtml(detectLinks(detectModules(obj.description.full)))),
params: obj.tags.filter(function(tag) {
Expand Down Expand Up @@ -95,7 +98,7 @@ angular
};
})
.sort(function(a, b) {
return a.name > b.name;
return a.constructor ? -1: a.name > b.name;
});
};
}
Expand Down
15 changes: 15 additions & 0 deletions docs/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,21 @@ h2, h3 {
display: block;
}

.sub-heading {
color: #5d6061;
margin: 0;
}

.toggler {
float: left;
min-width: 15px;
margin: auto;
}

.toggle {
cursor: pointer;
}

/*
Page Title
*/
Expand Down
56 changes: 35 additions & 21 deletions lib/common/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,50 @@
* @module common/util
*/

var extend = require('extend');
var util = require('util');

/**
* Extend a base object with properties from another.
* Extend a global configuration object with user options provided at the time
* of sub-module instantiation.
*
* @param {object} from - The base object.
* @param {object} to - The object to extend with.
* Connection details currently come in two ways: `credentials` or
* `keyFilename`. Because of this, we have a special exception when overriding a
* global configuration object. If a user provides either to the global
* configuration, then provides another at submodule instantiation-time, the
* latter is preferred.
*
* @param {object} globalConfig - The global configuration object.
* @param {object} overrides - The instantiation-time configuration object.
* @return {object}
* ```
*
* @example
* // globalConfig = {
* // credentials: {...}
* // }
* Datastore.prototype.dataset = function(options) {
* // options = {
* // keyFilename: 'keyfile.json'
* // }
* return extendGlobalConfig(this.config, options);
* // returns:
* // {
* // keyFilename: 'keyfile.json'
* // }
* };
*/
function extend(from, to) {
if (from === null || typeof from !== 'object') {
return from;
}
if (from.constructor === Date || from.constructor === Function ||
from.constructor === String || from.constructor === Number ||
from.constructor === Boolean) {
return new from.constructor(from);
}
if (from.constructor !== Object && from.constructor !== Array) {
return from;
}
to = to || new from.constructor();
for (var name in from) {
to[name] = to[name] ? extend(from[name], null) : to[name];
function extendGlobalConfig(globalConfig, overrides) {
var options = extend({}, globalConfig);
var hasGlobalConnection = options.credentials || options.keyFilename;
var isOverridingConnection = overrides.credentials || overrides.keyFilename;
if (hasGlobalConnection && isOverridingConnection) {
delete options.credentials;
delete options.keyFilename;
}
return to;
return extend(true, {}, options, overrides);
}

module.exports.extend = extend;
module.exports.extendGlobalConfig = extendGlobalConfig;

/**
* Wrap an array around a non-Array object. If given an Array, it is returned.
Expand Down
18 changes: 10 additions & 8 deletions lib/datastore/dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ var SCOPES = [
* @alias module:datastore/dataset
*
* @param {object=} options
* @param {string} options.projectId - Dataset ID. This is your project ID from
* @param {string=} options.projectId - Dataset ID. This is your project ID from
* the Google Developers Console.
* @param {string=} options.keyFilename - Full path to the JSON key downloaded
* from the Google Developers Console. Alternatively, you may provide a
Expand All @@ -84,20 +84,24 @@ var SCOPES = [
* @param {string} options.namespace - Namespace to isolate transactions to.
*
* @example
* var dataset = new datastore.Dataset({
* var dataset = datastore.dataset({
* projectId: 'my-project',
* keyFilename: '/path/to/keyfile.json'
* });
*/
function Dataset(options) {
if (!(this instanceof Dataset)) {
return new Dataset(options);
}

options = options || {};

this.connection = new conn.Connection({
credentials: options.credentials,
keyFilename: options.keyFilename,
scopes: SCOPES
});
this.id = options.projectId;
this.projectId = options.projectId;
this.namespace = options.namespace;
this.transaction = this.createTransaction_();
}
Expand All @@ -108,13 +112,11 @@ function Dataset(options) {
* You may also specify a configuration object to define a namespace and path.
*
* @example
* var key;
*
* // Create a key from the dataset's namespace.
* key = dataset.key('Company', 123);
* var company123 = dataset.key('Company', 123);
*
* // Create a key from a provided namespace and path.
* key = dataset.key({
* var nsCompany123 = dataset.key({
* namespace: 'My-NS',
* path: ['Company', 123]
* });
Expand Down Expand Up @@ -347,7 +349,7 @@ Dataset.prototype.allocateIds = function(incompleteKey, n, callback) {
* @private
*/
Dataset.prototype.createTransaction_ = function() {
return new Transaction(this.connection, this.id);
return new Transaction(this.connection, this.projectId);
};

module.exports = Dataset;
95 changes: 85 additions & 10 deletions lib/datastore/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,97 @@
*/
var entity = require('./entity');

/*!
* @alias module:datastore
/**
* @type module:common/util
* @private
*/
var util = require('../common/util.js');

/**
* @type module:datastore/dataset
* @private
*/
var datastore = {};
var Dataset = require('./dataset');

/*! Developer Documentation
*
* Invoking the Datastore class allows you to provide configuration up-front.
* This configuration will be used for future invokations of the returned
* `dataset` method.
*
* @example
* var datastore = require('gcloud/lib/datastore')({
* keyFilename: '/path/to/keyfile.json'
* });
*
* var dataset = datastore.dataset();
* // equal to:
* // datastore.dataset({
* // keyFilename: '/path/to/keyfile.json'
* // });
*/
/**
* @see {module:datastore/dataset}
* The example below will demonstrate the different usage patterns your app may
* need to support to retrieve a datastore object.
*
* @alias module:datastore
* @constructor
*
* @example
* var gcloud = require('gcloud');
* var datastore = gcloud.datastore;
*
* // Providing configuration details up-front.
* var myProject = gcloud({
* keyFilename: '/path/to/keyfile.json',
* projectId: 'my-project'
* });
*
* var dataset = myProject.datastore.dataset();
*
*
* // Overriding default configuration details.
* var anotherDataset = myProject.datastore.dataset({
* keyFilename: '/path/to/another/keyfile.json'
* });
*
*
* // Not using a default configuration.
* var myOtherProject = gcloud.datastore.dataset({
* keyFilename: '/path/to/keyfile.json',
* projectId: 'my-project'
* });
*/
function Datastore(config) {
this.config = config || {};
}

/*! Developer Documentation
*
* Use this static method to create a dataset without any pre-configured
* options.
*
* @example
* var datastore = require('gcloud/lib/datastore');
*
* // Create a Dataset object.
* var dataset = new datastore.Dataset();
* var dataset = datastore.dataset({
* keyFilename: '/path/to/keyfile.json'
* });
*/
datastore.Dataset = require('./dataset');
Datastore.dataset = Dataset;

/*! Developer Documentation
*
* Create a dataset using the instance method when you want to use your
* pre-configured options from the Datastore instance.
*
* @param {object=} options - Configuration object.
* @return {module:datastore/dataset}
*/
Datastore.prototype.dataset = function(options) {
// Mix in global config data to the provided options.
return new Dataset(util.extendGlobalConfig(this.config, options));
};

/**
* Helper function to get a Datastore Integer object.
Expand All @@ -55,7 +130,7 @@ datastore.Dataset = require('./dataset');
* // Create an Integer.
* var sevenInteger = gcloud.datastore.int(7);
*/
datastore.int = function(value) {
Datastore.int = function(value) {
return new entity.Int(value);
};

Expand All @@ -71,8 +146,8 @@ datastore.int = function(value) {
* // Create a Double.
* var threeDouble = gcloud.datastore.double(3.0);
*/
datastore.double = function(value) {
Datastore.double = function(value) {
return new entity.Double(value);
};

module.exports = datastore;
module.exports = Datastore;
Loading

0 comments on commit 009ae90

Please sign in to comment.