Creating new database in code, RavenDB - ravendb

I'm running RavenDB.Client 2.0.2173-Unstable. I'm creating a multi-tenant system, and as part of my registration process, i would like to create a new Raven database.
I have three simple lines of code..
string newDBName = "1234";
IDocumentStore documentStore = new DocumentStore { Url = "http://myserver:8080", DefaultDatabase = newDbName};
documentStore.Initialize();
documentStore.DatabaseCommands.EnsureDatabaseExists(newDBName);
Per suggestion, I also tried this:
string newDBName = "1234";
IDocumentStore documentStore = new DocumentStore { Url = "http://myserver:8080"};
documentStore.Initialize();
documentStore.DatabaseCommands.EnsureDatabaseExists(newDBName);
I get an InvalidOperationException on the last line, Raven is telling me it could not figure out what to do.
<h1>Could not figure out what to do</h1>
<p>Your request didn't match anything that Raven knows to do, sorry...</p>
I know my connection/server works, because I'm able to read/write from the default database.
Is it a permissions issue?

You can't create a database from the database you're already in. Leave the DefaultDatabase field blank so you connect to the RavenDB system database. You should then be able to create the new tenant database.
You should also make sure to pass the tenant database name when opening sessions, creating indexes, and using DatabaseCommands.

In Ravendb v4, you can use the CreateDatabaseOperation to create a new database on the server.
store.Maintenance.Server.Send(
new CreateDatabaseOperation(new DatabaseRecord("MyNewDatabase")));

Related

How to access files stored in SQL Server's FileTable?

As I know SQL Server since version 2012 has a new feature, FileTable. It allows us to store files in the file system and to use them from T-SQL.
I am trying to use this feature and I have no idea how to do it properly.
Generally, I don't know how to access files stored in the file table. Let's suppose I have asp.net MVC app and there are a lot of images which I show on web pages in img tags. I would like to store these images in Filetable and access them as files from the filesystem. But I don't know where these files are stored and how to use them as files. Now my images are stored in web application directory in folder images and I write something like this:
<img src='/images/mypicture.png' />
And if I move my images to file table what I should write in src?
<img src='path-toimage-in-filetable' />
I don't think you still need this, anyways I'll post my answer for anyone else interested.
First, a filetable still being a table, so, if you want to access to data from it you need to use a Select SQL statement. So you'd need something like:
select name, file_stream from filetable_name
where
name = 'file_name',
file_type = 'file_extension'
just execute an statement like this in your asp.net app, then fetch the results and use the file_stream column to get the binary data of the stored file. If you want to retrieve the file from HTML, first you need to create an action in your controller, which will return the retrieved file:
public ActionResult GetFile(){
..
return File(file.file_stream,file.file_type);
}
After this, put in you HTML tag something like:
<img src="/controller/GetFile" />
hope this could help!
If you want to know the schema of a filetable see
here
I assume by FileTable you actually mean FileStream. A couple notes about that:
This feature is best used if your files are actually files
The files should be, on average, greater than 1mb - although there can be exceptions to this rule, if they're smaller than 1mb on average, you may be better off using a VARBINARY(MAX) or XML data type as appropriate. If your images are very small on average (only a few KB), consider using a VARBINARY(MAX) column.
Accessing these files will require an open transaction and that the database is properly configured for FILESTREAM
You can get some significant advantages bypassing the normal SQL engine/database file method of data access by telling SQL Server that you want to access the file directly, however it's not meant for directly accessing the file on the file system and attempting to do so can break SQL's management of these files (transactional consistency, tracking, locking, etc.).
It's pretty likely that your use case here would be better served by using a CDN and storing image URLs in the table if you really need SQL for this. You can use FILESTREAM to do this (see code sample below for one implementation), but you'll be hammering your SQL server for every request unless you store the images somewhere else anyway that the browser can properly cache (my example doesn't do that) - and if you store them somewhere else for rendering int he browser you might as well store them there to begin with (you won't have transactional consistency for those images once they're copied to some other drive/disk/location anyway).
With all that said, here's an example of how you'd access the FILESTREAM data using ADO.NET:
public static string connectionString = ...; // get your connection string from encrypted config
// assumes your FILESTREAM data column is called Img in a table called ImageTable
const string sql = #"
SELECT
Img.PathName(),
GET_FILESTREAM_TRANSACTION_CONTEXT()
FROM ImageTagble
WHERE ImageId = #id";
public string RetreiveImage(int id)
{
string serverPath;
byte[] txnToken;
string base64ImageData = null;
using (var ts = new TransactionScope())
{
using (var conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add("#id", SqlDbType.Int).Value = id;
using (SqlDataReader rdr = cmd.ExecuteReader())
{
rdr.Read();
serverPath = rdr.GetSqlString(0).Value;
txnToken = rdr.GetSqlBinary(1).Value;
}
}
using (var sfs = new SqlFileStream(serverPath, txnToken, FileAccess.Read))
{
// sfs will now work basically like a FileStream. You can either copy it locally or return it as a base64 encoded string
using (var ms = new MemoryStream())
{
sfs.CopyTo(ms);
base64ImageData = Convert.ToBase64String(ms.ToArray());
}
}
}
ts.Complete();
// assume this is PNG image data, replace PNG with JPG etc. as appropraite. Might store in table if it will vary...
return "data:img/png;base64," + base64ImageData;
}
}
Obviously, if you have lots of images to handle like this this is not an ideal method - don't try to make an instance of SQL server into what you should be using a CDN for.... However, if you have other really good reasons, you should try to grab as many images as possible in a single request/transaction (e.g. if you know you're displaying 50 images on a page, get all 50 with a single transaction scope, don't use 50 transaction scopes - this code won't handle that).

StackExchange.Redis Connect to multiple db

I am using stackexchange redis client, I want to connect to multiple db not only one How can I handle it ?
https://github.com/StackExchange/StackExchange.Redis/blob/master/Docs/Basics.md
You have to pass the DB number in the getDatabase() Method
ConnectionMultiplexer redis = ConnectionMultiplexer.connect("local host");
IDatabase db = redis.GetDatabase(databaseNumber);
if you are using it in .Net Core, I have created a wrapper class which you can use like this:
var redisConnectionString = "{Your Redis Cache Connection String}";
var rest = new Restme(redisConnectionString);
//get cache data (support Generic cast)
var cacheResult = rest.Get("home:testKey");
var cacheResult2 = rest.Get<bool>("home:testKey2");
var cacheResult3 = rest.Get<ObjectType>("home:testKey3");
//set cache data
rest.Post("home:testKey","value");
rest.Post<bool>("home:testKey2",true);
it's actually a simple wrapper of StackExchange.Redis, so if you want to conect to multiple databases, just simply instantiate multiple Restme() objects as separate variables, each contains different Redis db connection.
The source code is in github: https://github.com/oelite/RESTme

Automatically Sync SQL Databases across two computers

I am using a cloud backup/sync service (SpiderOak) which automatically Syncs folders across several computers / devices.
I am trying to figure out a way to automatically sync all my databases across my work computer and personal laptop, without actually needing to backup/restore from one instance to the other.
So what I am thinking of is to create a new sql instance on my laptop which is identical to my work desktop instance, then to pick both SQL Server directories in Program Files to sync with each other using SpiderOak (the whole root SQL Server folders).
Will this be enough for my two instances to Sync with each other? Meaning if I create a new database on my computer at work, will I see this database on my laptop when I open SQL Server Database Management Studio?
I am almost sure if databases already exist they will sync with each other (since the root folders contain the mdf & ldf files - but correct me if I am wrong). however, I am not sure if a new database will be created if it doesn't already exist on one of the machines.
Is there any other folders that I need to sync other than the ones I specified already?
You could use Sql Sync Framework, you can download it here
some more readfood
It works for Sql Server 2005
Download and import references and include with the default ones:
using System.Data.Sql;
using System.Data.SqlClient;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Data;
using Microsoft.Synchronization.Data.SqlServer;
using System.Diagnostics;
using System.Reflection;
using System.Net;
Than the actual code:
private void SyncTables()
{
SqlConnection ConStringOnline = new SqlConnection("connstring");
SqlConnection ConStringOffline = new SqlConnection("connString");
SyncOrchestrator sync = new SyncOrchestrator();
sync.Direction = SyncDirectionOrder.Download; //or DownloadAndUpload
//the 'scope1' is important, read more about it in the articles
var provider1 = new SqlSyncProvider("scope1", ConStringOnline);
var provider2 = new SqlSyncProvider("scope1", ConStringOffline);
PrepareServerForProvisioning(provider1);
PrepareClientForProvisioning(provider2, ConStringOnline);
sync.LocalProvider = provider2;
sync.RemoteProvider = provider1;
sync.Synchronize();
}
private static void PrepareServerForProvisioning(SqlSyncProvider provider)
{
SqlConnection connection = (SqlConnection)provider.Connection;
SqlSyncScopeProvisioning config = new SqlSyncScopeProvisioning(connection);
if (!config.ScopeExists(provider.ScopeName))
{
DbSyncScopeDescription scopeDesc = new DbSyncScopeDescription(provider.ScopeName);
scopeDesc.Tables.Add(SqlSyncDescriptionBuilder.GetDescriptionForTable("TABLENAME", connection));
config.PopulateFromScopeDescription(scopeDesc);
config.SetCreateTableDefault(DbSyncCreationOption.CreateOrUseExisting);
config.Apply();
}
}
private static void PrepareClientForProvisioning(SqlSyncProvider provider, SqlConnection sourceConnection)
{
SqlSyncScopeProvisioning config = new SqlSyncScopeProvisioning((SqlConnection)provider.Connection);
if (!config.ScopeExists(provider.ScopeName))
{
DbSyncScopeDescription scopeDesc = SqlSyncDescriptionBuilder.GetDescriptionForScope(provider.ScopeName, sourceConnection);
config.PopulateFromScopeDescription(scopeDesc);
config.Apply();
}
}
The downside of using Sync Framework: It is a pain in the a** to add these prerequisites to your application before publishing, no problem if you just use an application for yourself or for your company, but when you would like to publish it online it is a bit harder. I already had a topic about that
However, when using tools like InnoScript, you can install the prerequisites easily while installing the application. Here is how.
Now for the ScopeName: It is important that you don't use twice the same name, I believe. I had multiple tables so I just named them scope1,scope2,scope3,scope4. Apparently Sync Framework does the rest of the work for you. It also automatically adds _tracking tables to your database, this is just metadata to store information to synchronize properly.

Upload and Download error synchronizing Sql Server and Sql Azure - Sync Framework

I'm trying to synchronize an Sql Server database with SQL Azure Database (please be patient 'cause I don't fully understand Sync Framework). These are the requirements:
First: synchronize 1 table from Sql Azure to Sql Server
Second: synchronize 13 other tables (including the table I mentioned in the first step) from Sql Server to Azure.
I've created a console application, and this is the code:
1.I create one scope with the 13 tables:
DbSyncScopeDescription myScope = new DbSyncScopeDescription("alltablesyncgroup");
DbSyncTableDescription table = qlSyncDescriptionBuilder.GetDescriptionForTable("tablename", sqlServerConn);
myScope.Tables.Add(table); //repeated 13 times.
2.I Provision both data bases:
SqlSyncScopeProvisioning sqlAzureProv = new SqlSyncScopeProvisioning(sqlAzureConn,myScope);
if (!sqlAzureProv.ScopeExists("alltablesyncgroup"))
{
sqlAzureProv.Apply();
}
SqlSyncScopeProvisioning sqlServerProv = new SqlSyncScopeProvisioning(sqlServerConn, myScope);
if (!sqlServerProv.ScopeExists("alltablesyncgroup"))
{
sqlServerProv.Apply();
}
3.I create the SyncOrchestrator with the SyncDirectionOrder.Download to sync the firts table:
SqlConnection sqlServerConn = new SqlConnection(sqllocalConnectionString);
SqlConnection sqlAzureConn = new SqlConnection(sqlazureConnectionString);
SyncOrchestrator orch = new SyncOrchestrator
{
RemoteProvider = new SqlSyncProvider(scopeName, sqlAzureConn),
LocalProvider = new SqlSyncProvider(scopeName, sqlServerConn),
Direction = SyncDirectionOrder.Download
};
orch.Synchronize();
4.Later, I use the same function only changing the direction SyncDirectionOrder.Upload to sync the 13 remaining tables
SqlConnection sqlServerConn = new SqlConnection(sqllocalConnectionString);
SqlConnection sqlAzureConn = new SqlConnection(sqlazureConnectionString);
SyncOrchestrator orch = new SyncOrchestrator
{
RemoteProvider = new SqlSyncProvider(scopeName, sqlAzureConn),
LocalProvider = new SqlSyncProvider(scopeName, sqlServerConn),
Direction = SyncDirectionOrder.Upload
};
orch.Synchronize();
Now, here is the thing, obviously I'm doing it wrong 'cause when I download, the syncStats shows that a lot of change have been applied BUT I can't see it reflected on any data base and when I try to execute the Upload sync it seems to be going into a loop 'cause the Upload process doesn't stop.
Thanks!!!
first, you mentioned you only want to sync one table from Azure to your SQL Server but you're provisioning 13 tables in the scope. if you want one table, just provision a scope with one table. (e.g. one scope for the download with table, one scope for the upload with the rest of the tables)
to find out why rows are not synching, you can subscribe to the ApplyChangeFailed event for both sides, and check if there are conflicts or errors being encountered.
or you can enable Sync Framework tracing in verbose mode so you can see what's happening underneath.

Failure to create a SQL Azure login with SMO

The following piece of code works with regular SQL and SMO. I'm trying to get it to work with SQL Azure. According to this MSDN article, a limited subset of functionality that I need (database and login creation) should be supported. All the business checking whether an object exists will also fail: server.Logins[loginName] != null or server.Databases.Contains(dbName). I can create a database if I dont check whether it exists or not, but i cant create a login. Anyone else ran into the same problem?
string connectionString =
"Server=tcp:XXXXXX.database.windows.net;Database=MyDatabase;User ID=XXXXXXX;Password=XXXXXX;Trusted_Connection=False;Encrypt=True;TrustServerCertificate=true;"
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
ServerConnection serverConnection = new ServerConnection(connection);
Server server = new Server(serverConnection);
Login login = new Login(server, "NewLogin");
login.LoginType = LoginType.SqlLogin;
login.Create("NewStrongPwd123***");
}
Create failed for Login 'NewLogin'.
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.CreateImpl()
at Microsoft.SqlServer.Management.Smo.Login.Create(SecureString password)
at Microsoft.SqlServer.Management.Smo.Login.Create(String password)
Proposed answers to this question were identified on the MSDN Forum including a working approach. Please take a look at: http://social.msdn.microsoft.com/Forums/en-US/ssdsgetstarted/thread/26e42082-e649-4cde-916d-c1da2275e377