Programmatically creating Faunadb child database - multi-tenant

Hi I am new in Faunadb and trying a multi-tenancy app. There is option of creating child databases from fauna shell. But my thinking is when a user is signed up, a child database with that username will create automatically.
I searched in there documentation but got no idea. Is it possible from frontend JS libraries such as React, Vue or from API in Nodejs?
Thanks is advance.

Yes, you can programatically create a child database using CreateDatabase. Two things are important to note here:
The key you use for creating the child db must have the admin role, so you'd want to do it from a secure backend node server.
Which database you connect to in fauna is defined by which key you use to connect, so you must generate and use another key for the new child database.
This is how the code might look:
// Connect to the parent database
const parentFauna = new faunadb.Client({
secret: FAUNA_ADMIN_KEY
})
// Create child database and retrieve a new key for it
const { secret } = await parentFauna.query(
Do(
CreateDatabase({
name: "example"
}),
CreateKey({
database: Database("example"),
role: "server"
})
)
)
// You can now connect to the child database
const childFauna = new faunadb.Client({
secret: secret
})

You can use the JS driver (it's not framework-specific) to create the child DB and set up its schema using fauna's Create* functions.

Related

GraphQL requesting fields that don't exist without error

I'm trying to handle backwards compatibility with my GraphQL API.
We have on-premise servers that get periodically updated based off of when they connect to the internet. We have a Mobile app that talks to the on-premise server.
Problem
We get into an issue where the Mobile app is up to date and the on-premise server isn't. When a change in the Schema occurs, it causes issues.
Example
Product version 1
type Product {
name: String
}
Product version 2
type Product {
name: String
account: String
}
New version of mobile app asks for:
product(id: "12345") {
name
account
}
Because account is not valid in version 1, I get the error:
"Cannot query field \"account\" on type \"Product\"."
Does anyone know how I can avoid this issue so I don't recieve this particular error. I'm totally fine with account coming back with Null or just some other plan of attack for updating Schema's. But having it completely blow up with no response is not good
Your question did not specify what you're actually using on the backend. But it should be possible to customize the validation rules a GraphQL service uses in any implementation based on the JavaScript reference implementation. Here's how you do it in GraphQL.js:
const { execute, parse, specifiedRules, validate } = require('graphql')
const validationRules = specifiedRules.filter(rule => rule.name !== 'FieldsOnCorrectType')
const document = parse(someQuery)
const errors = validate(schema, document, validationRules)
const data = await execute({ schema, document })
By omitting the FieldsOnCorrectType rule, you won't get any errors and unrecognized fields will simply be left off the response.
But you really shouldn't do that.
Modifying the validation rules will result in spec-breaking changes to your server, which can cause issues with client libraries and other tools you use.
This issue really boils down to your deployment process. You should not push new versions of the client that depend on a newer version of the server API until that version is deployed to the server. Period. That would hold true regardless of whether you're using GraphQL, REST, SOAP, etc.

How to reference an initialized embedded RavenDB instance in a Class Library?

My scenario is this:
I have a custom RavenDB membership provider that is implemented in a class library (DLL). This provider needs to access a database to store and retrieve User and Role information. I'd like to use the same app database to store membership information to avoid having one more database.
I don't know how to get a reference to the already initialized database (app database) inside the class library code. I think I'm going the wrong way here... :)
Some code:
bool embeddedStore = Convert.ToBoolean(config["enableEmbeddableDocumentStore"]);
if (embeddedStore)
{
_documentStore = new EmbeddableDocumentStore()
{
// Here I'm using the same connection string used by the app.
// This gives me an error when I try to open a session in the DocumentStore.
ConnectionStringName =
config["connectionStringName"]
};
}
else
{
_documentStore = new DocumentStore()
{
ConnectionStringName =
config["connectionStringName"]
};
}
This is the connection string present in Web.config:
<add name="RavenDB" connectionString="DataDir = ~\App_Data\Database" />
How can I reuse the same database within the custom membership provider? Any ideas?
I thought about moving the class library code files to the Web project. This way I could get a reference to the DocumentStore easily, but the code wouldn't be as organized as I'd like.
I also tried to use 2 RavenDB databases: 1 for the app and 1 for the membership provider, but as I'm running RavenDB in its embeddable fashion I couldn't get it working.
These are the errors I got during my attempts so far:
RavenDB Could not open transactional storage.
Temp path already used by another database instance.
You need to pass the instance of the opened document store to your dll.
You can do that using a container or by providing an API call to do that.
You can't have two instance using the same db.

How can a client query a db4o server?

I've set up a db4o server and client. My client calls are not working.
What's puzzling to me is that the db4o examples show how the client can close the server, but not how to get and save data. See: http://community.versant.com/Documentation/Reference/db4o-7.12/java/reference/Content/client-server/networked/simple_db4o_server.htm
If I start the db4o server, and run netstat, I can see that the port is open. And on the client, I can do things like this:
Debug.WriteLine(db.Ext().IsClosed().ToString());
And that returns False, which is good.
But when I try to get or save data, it doesn't work. When saving data, it appears to work, but I don't see the data in the DB. When trying to retrieve the object, I get this error:
Db4objects.Db4o.Ext.Db4oException: Exception of type 'Db4objects.Db4o.Ext.Db4oException' was thrown. ---> System.ArgumentException: Field '_delegateType' defined on type 'Db4objects.Db4o.Internal.Query.DelegateEnvelope' is not a field on the target object which is of type 'Db4objects.Db4o.Reflect.Generic.GenericObject'.
Here are the client calls to save, then get:
Server server = new Server() { Name = "AppServerFoo" };
IObjectContainer db = GetDatabase();
db.Store(server);
db.Close();
Here's the only line in the GetDatabase() method:
return Db4oClientServer.OpenClient(Db4oClientServer.NewClientConfiguration(), "DellXps", 8484, "user", "password");
And here's the call to get from the DB:
IObjectContainer db = GetDatabase();
Server testServer = db.Query<Server>(server => server.Name == "AppServerFoo").FirstOrDefault();
db.Close();
What am I missing?
Well a server without a reference the persisted classes is a 'risky' thing. A lot of functionally doesn't work and the error which occur are cryptic. I highly recommend to always reference the assembly with the persisted classes on the server.
Another tip: Use LINQ instead of native queries. It works better and has less problems.
A ha! I got it. It took some googling, but the problem was that the server didn't have a reference to the entities. As soon as my server project referenced my client project, it worked. So, it looks like I just need to move my entities to a common project that both the client and server can reference.
Thanks to this link:
http://www.gamlor.info/wordpress/2009/11/db4o-client-server-and-concurrency/
This link looks like a gateway to having the server work without referencing the entities:
http://community.versant.com/Documentation/Reference/db4o-7.12/net2/reference/html/reference/client-server/server_without_persistent_classes_deployed.html

how to pass a target database on H2 database console

I'm using H2 database console as a servlet in my own web application that provides a front end of many databases.
How to skip or help a login step at H2 database console by passing some parameters in my own code?
(I have many databases, so I won't use "saved settings" first.)
imaginary: http://myapp/h2console/login.do?user=scott&password=tiger&url=jdbc:thin:......
Because of the somewhat special session handling of the console, this is not possible just using an fixed URL. (The session handling allows to open multiple connections within multiple tabs from one browser, which is not possible when using cookies.)
However, what you can do is create a URL in the same way as Server.startWebServer(Connection conn) does:
// the server is already running in your case,
// so most likely you don't need the following lines:
WebServer webServer = new WebServer();
Server web = new Server(webServer, new String[] { "-webPort", "0" });
web.start();
Server server = new Server();
server.web = web;
webServer.setShutdownHandler(server);
// this will create a new session and return the URL for it:
String url = webServer.addSession(conn);

Frameworks using Redis

I would like to know if there are any MVC framework compatible with Redis as a database. (Not just as a caching datastore).
Thanks
I would not expect any MVC framework to be tied to a database. Your implementation of the Model would provide access to whatever backing store (either directly or via one or more layers) was appropriate. You should be looking at the clients that Redis supports, with those you should be able to utilise MVC frameworks on any of the support client platforms.
+1 for Padrino.
Another great option is Monk. It includes Ohm(its actually written by some of the same guys) and is based on Sinatra. Its really easy to get started with and very flexible.
In Ruby you can use Ohm as ORM. If you want an MVC framework, it can be plugged to Padrino.
try to investigate cqrs architecture with event sourcing.
And you can download example of this from github.it is Ruby on Rails application with Redis DB
You should definitely check out my C# ServiceStack.Redis Client. The client provides a typed API that can store any type and other high-level functionality, i.e. Strong-typed messaging API, Transactional Support, Pipelining, etc.
Here's is an mini clone of Stack Overflow built with it, using only one page of C#:
Sample Code from Redis StackOverflow:
public User GetOrCreateUser(User user)
{
if (user.DisplayName.IsNullOrEmpty())
throw new ArgumentNullException("DisplayName");
var userIdAliasKey = "id:User:DisplayName:" + user.DisplayName.ToLower();
using (var redis = RedisManager.GetClient())
{
//Get a typed version of redis client that works with <User>
var redisUsers = redis.As<User>();
//Find user by DisplayName if exists
var userKey = redis.GetValue(userIdAliasKey);
if (userKey != null)
return redisUsers.GetValue(userKey);
//Generate Id for New User
if (user.Id == default(long))
user.Id = redisUsers.GetNextSequence();
redisUsers.Store(user);
//Save reference to User key using the DisplayName alias
redis.SetEntry(userIdAliasKey, user.CreateUrn());
return redisUsers.GetById(user.Id);
}
}
grails has redis support in GORM through the redis plugin. Any domain class can be stored in redis (or any one of the other supported nosql stores) instead of a relational database.

Resources