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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This client supports the following Google Cloud Platform services:
* [Google Cloud Datastore](#google-cloud-datastore)
* [Google Cloud Storage](#google-cloud-storage)
* [Google Cloud Pub/Sub](#google-cloud-pubsub-beta) (Beta)
* [Google Cloud Search](#google-cloud-search-alpha) (Alpha)

If you need support for other Google APIs, check out the [Google Node.js API Client library][googleapis].

Expand Down Expand Up @@ -238,6 +239,48 @@ topic.subscribe('new-subscription', function(err, subscription) {
});
```

## Google Cloud Search (Alpha)
> This is an *Alpha* release of Google Cloud Search. This feature is not covered by any SLA or deprecation policy and may be subject to backward-incompatible changes.

[Google Cloud Search][cloud-search] ([docs][cloud-search-docs]) allows you to quickly perform full-text and geospatial searches against your data without having to spin up your own instances and without the hassle of managing and maintaining a search service.

See the [gcloud-node Search API documentation][gcloud-search-docs] to learn how to store and query your indexes and documents using this library.

```js
var gcloud = require('gcloud');

// Authorizing on a per-API-basis. You don't need to do this if you auth on a
// global basis (see Authorization section above).

var search = gcloud.search({
keyFilename: '/path/to/keyfile.json',
projectId: 'my-project'
});

// Create a document in a new index.
var index = search.index('memberData');

var document = index.document('member-id-34211');
document.addField('preferredContactForm').addTextValue('phone');

index.createDocument(document, function(err, document) {
console.log(err || document);
});

// Search an index and get the results as a readable object stream.
var index = search.index('memberData');

index.search('preferredContactForm:phone')
.on('error', console.error)
.on('data', function(document) {
// document.id = 'member-id-34211';
})
.on('end', function() {
// All results consumed.
});
```


## Contributing

Contributions to this library are always welcome and highly encouraged.
Expand All @@ -253,6 +296,7 @@ Apache 2.0 - See [COPYING](COPYING) for more information.
[gcloud-bigquery-docs]: https://googlecloudplatform.github.io/gcloud-node/#/docs/bigquery
[gcloud-datastore-docs]: https://googlecloudplatform.github.io/gcloud-node/#/docs/datastore
[gcloud-pubsub-docs]: https://googlecloudplatform.github.io/gcloud-node/#/docs/pubsub
[gcloud-search-docs]: https://googlecloudplatform.github.io/gcloud-node/#/docs/search
[gcloud-storage-docs]: https://googlecloudplatform.github.io/gcloud-node/#/docs/storage
[gcloud-todos]: https://github.com/GoogleCloudPlatform/gcloud-node-todos
[gitnpm]: https://github.com/stephenplusplus/gitnpm
Expand All @@ -273,8 +317,12 @@ Apache 2.0 - See [COPYING](COPYING) for more information.
[cloud-pubsub]: https://cloud.google.com/pubsub/
[cloud-pubsub-docs]: https://cloud.google.com/pubsub/docs

[cloud-search]: https://cloud.google.com/search/
[cloud-search-docs]: https://cloud.google.com/search/

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.


[cloud-storage]: https://cloud.google.com/storage/
[cloud-storage-docs]: https://cloud.google.com/storage/docs/overview
[cloud-storage-create-bucket]: https://cloud.google.com/storage/docs/cloud-console#_creatingbuckets

[hya-wave]: https://wav.hya.io
[hya-io]: https://hya.io
Empty file.
25 changes: 24 additions & 1 deletion docs/site/components/docs/docs-values.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,25 @@ angular.module('gcloud.docs')
]
},

search: {
title: 'Search',
_url: '{baseUrl}/search',
pages: [
{
title: 'Index',
url: '/index'
},
{
title: 'Document',
url: '/document'
},
{
title: 'Field',
url: '/field'
}
]
},

storage: {
title: 'Storage',
_url: '{baseUrl}/storage'
Expand Down Expand Up @@ -135,6 +154,10 @@ angular.module('gcloud.docs')
// introduce new storage api.
'>=0.9.0': ['storageWithFiles'],

'>=0.10.0': ['bigquery']
// introduce bigquery api.
'>=0.10.0': ['bigquery'],

// introduce search api.
'>=0.16.0': ['search']
}
});
2 changes: 1 addition & 1 deletion docs/site/components/docs/docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ <h3 class="sub-heading">
</article>
<hr>

<article ng-repeat="service in ['bigquery', 'datastore', 'pubsub', 'storage']"
<article ng-repeat="service in ['bigquery', 'datastore', 'pubsub', 'search', 'storage']"
ng-if="isActiveDoc(service)"
ng-include="'site/components/docs/' + service + '-overview.html'">
</article>
Expand Down
3 changes: 3 additions & 0 deletions docs/site/components/docs/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ angular
path.push('index.json');
} else if (module && cl) {
path.push(module);
if (cl === 'index') {
cl = 'index-class';
}
path.push(cl + '.json');
}
return $http.get(path.join('/'))
Expand Down
7 changes: 7 additions & 0 deletions docs/site/components/docs/search-overview.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<h3>Search Overview</h3>
<p>
The object returned from <code>gcloud.search</code> gives you complete access to store your documents and search your indexes.
</p>
<p>
To learn more about Search, see <a href="https://cloud.google.com/search">What is Google Cloud Search?</a>
</p>
137 changes: 137 additions & 0 deletions lib/common/stream-router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*!
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*!
* @module common/streamrouter
*/

'use strict';

var streamEvents = require('stream-events');
var through = require('through2');

/**
* @type {module:common/util}
* @private
*/
var util = require('../common/util.js');

/*! Developer Documentation
*
* streamRouter is used to extend `nextQuery`+callback methods with stream

This comment was marked as spam.

* functionality.
*
* Before:
*
* search.query('done=true', function(err, results, nextQuery) {});
*
* After:
*
* search.query('done=true').on('data', function(result) {});
*
* Methods to extend should be written to accept callbacks and return a
* `nextQuery`. All stream logic is handled in `streamRouter.router_`.
*/
var streamRouter = {};

/**
* Cache the original method, then overwrite it on the Class's prototype.
*
* @param {function} Class - The parent class of the methods to extend.
* @param {array|string} methodNames - Name(s) of the methods to extend.
*/
streamRouter.extend = function(Class, methodNames) {
methodNames = util.arrayize(methodNames);

methodNames.forEach(function(methodName) {
var originalMethod = Class.prototype[methodName];

Class.prototype[methodName] = function() {
return streamRouter.router_(arguments, originalMethod.bind(this));
};
});
};

/**
* The router accepts all incoming arguments to the overwritten method. If the
* last argument is a function, simply pass them through to the original method.
* If the last argument is not a function, activate stream mode.
*
* Stream mode simply calls the nextQuery recursively. The stream ends when
* `nextQuery` is null.
*
* @param {array} args - The original `arguments` pseudo-array as it was
* received by the original method.
* @param {function} originalMethod - The cached method that accepts a callback
* and returns `nextQuery` to receive more results.
* @return {undefined|stream}
*/
streamRouter.router_ = function(args, originalMethod) {
args = util.toArray(args);
var callback = args[args.length - 1];
var isStreamMode = !util.is(callback, 'function');

if (!isStreamMode) {
originalMethod.apply(null, args);
return;
}

var stream = streamEvents(through.obj());

// Results from the API are split apart for the user. If 50 results are
// returned, we emit 50 data events. While the user is consuming these, they
// might choose to end the stream early by calling ".end()". We keep track of
// this state to prevent pushing more results to the stream, ending it again,
// or making unnecessary API calls.
var streamEnded = false;
var _end = stream.end;
stream.end = function() {
streamEnded = true;
_end.apply(this, arguments);
};

function onResultSet(err, results, nextQuery) {
if (err) {
stream.emit('error', err);
stream.end();
return;
}

results.forEach(function(result) {
if (!streamEnded) {
stream.push(result);
}
});

if (streamEnded) {
return;
}

if (nextQuery) {
originalMethod(nextQuery, onResultSet);
} else {
stream.end();
}
}

stream.once('reading', function() {
originalMethod.apply(null, args.concat(onResultSet));
});

return stream;
};

module.exports = streamRouter;
2 changes: 1 addition & 1 deletion lib/common/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@

var extend = require('extend');
var GoogleAuth = require('google-auth-library');
var nodeutil = require('util');
var request = require('request').defaults({
pool: {
maxSockets: Infinity
}
});
var nodeutil = require('util');
var uuid = require('node-uuid');

/** @const {object} gcloud-node's package.json file. */
Expand Down
45 changes: 40 additions & 5 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ var Datastore = require('./datastore');
*/
var PubSub = require('./pubsub');

/**
* @type {module:search}
* @private
*/
var Search = require('./search');

/**
* @type {module:storage}
* @private
Expand Down Expand Up @@ -120,6 +126,10 @@ function gcloud(config) {
options = options || {};
return new PubSub(util.extendGlobalConfig(config, options));
},
search: function(options) {
options = options || {};
return new Search(util.extendGlobalConfig(config, options));
},
storage: function(options) {
options = options || {};
return new Storage(util.extendGlobalConfig(config, options));
Expand Down Expand Up @@ -173,11 +183,9 @@ gcloud.datastore = Datastore;
* reliable, many-to-many, asynchronous messaging service from Google Cloud
* Platform.
*
* Note: Google Cloud Pub/Sub API is available as a Limited Preview and the
* client library we provide is currently experimental. The API and/or the
* client might be changed in backward-incompatible ways. This API is not
* subject to any SLA or deprecation policy. Request to be whitelisted to use it
* by filling the [Limited Preview application form](http://goo.gl/sO0wTu).
* Note: This is a *Beta* release of Google Cloud Pub/Sub. This feature is not
* covered by any SLA or deprecation policy and may be subject to backward-
* incompatible changes.
*
* @type {module:pubsub}
*
Expand All @@ -194,6 +202,33 @@ gcloud.pubsub = function(config) {
return new PubSub(config);
};

/**
* **Experimental**
*
* [Google Cloud Search](https://cloud.google.com/search/) allows you to quickly
* perform full-text and geospatial searches against your data without having to
* spin up your own instances and without the hassle of managing and maintaining
* a search service.
*
* Note: This is an *Alpha* release of Google Cloud Search. This feature is not
* covered by any SLA or deprecation policy and may be subject to backward-
* incompatible changes.
*
* @type {module:search}
*
* @return {module:search}
*
* @example
* var gcloud = require('gcloud');
* var search = gcloud.search({
* projectId: 'project-id',
* keyFilename: '/path/to/keyfile.json'
* });
*/
gcloud.search = function (config) {
return new Search(config);
};

/**
* Google Cloud Storage allows you to store data on Google infrastructure.
* Read [Google Cloud Storage API docs](https://developers.google.com/storage/)
Expand Down
Loading