Skip to content

Commit

Permalink
Implemented client side Oid generation with automatic insertion when …
Browse files Browse the repository at this point in the history
…missing.

Implemented Database.SendCommand() and converted some code to use it.
  • Loading branch information
samus committed Sep 30, 2009
1 parent effd6bf commit 0899d98
Show file tree
Hide file tree
Showing 12 changed files with 217 additions and 62 deletions.
8 changes: 3 additions & 5 deletions MongoDB.Net-Tests/MongoDB.Driver.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,8 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.core, Version=2.5.0.9122, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="nunit.framework, Version=2.5.0.9122, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<Reference Include="NUnit.Framework">
<HintPath>$(SharpDevelopBinPath)\Tools\NUnit\NUnit.Framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
Expand Down Expand Up @@ -87,6 +84,7 @@
<Compile Include="Bson\TestBsonRegex.cs" />
<Compile Include="TestMongoExceptions.cs" />
<Compile Include="TestOid.cs" />
<Compile Include="TestOidGenerator.cs" />
<Compile Include="TestPairedConnection.cs" />
<Compile Include="Bson\TestBsonCode.cs" />
</ItemGroup>
Expand Down
29 changes: 25 additions & 4 deletions MongoDB.Net-Tests/TestOid.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@


using System;

using NUnit.Framework;

namespace MongoDB.Driver
Expand All @@ -9,8 +10,7 @@ namespace MongoDB.Driver
public class TestOid
{
[Test]
public void TestIDLength()
{
public void TestIDLength(){
bool thrown = false;
try{
new Oid("BAD0");
Expand All @@ -35,7 +35,7 @@ public void TestIDCharacters(){
public void TestNullValue(){
bool thrown = false;
try{
new Oid(null);
new Oid(String.Empty);
}catch(Exception){
thrown = true;
}
Expand All @@ -49,9 +49,30 @@ public void TestCtor(){
new Oid("4a7067c30a57000000008ecb");
}catch(ArgumentException ae){
thrown = true;
System.Console.WriteLine(ae.ToString());
}
Assert.IsFalse(thrown,"ID should be fine.");
}

[Test]
public void TestDecode(){
string hex = "4a7067c30a57000000008ecb";
Oid oid = new Oid(hex);

Assert.AreEqual(hex,oid.ToString());
}

[Test]
public void TestEquals(){
string hex = "4a7067c30a57000000008ecb";
Assert.AreEqual(new Oid(hex), new Oid(hex));

}
[Test]
public void TestNotEquals(){
string hex = "4a7067c30a57000000008ecb";
string hex2 = "4a7067c30a57000000008ecc";
Assert.AreNotEqual(new Oid(hex), new Oid(hex2));

}
}
}
18 changes: 18 additions & 0 deletions MongoDB.Net-Tests/TestOidGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@


using System;
using NUnit.Framework;

namespace MongoDB.Driver
{
[TestFixture]
public class TestOidGenerator
{
[Test]
public void TestGenerate(){
OidGenerator ogen = new OidGenerator();
Oid oid = ogen.Generate();
Console.WriteLine(oid.ToString());
}
}
}
20 changes: 1 addition & 19 deletions MongoDBDriver/Bson/BsonOid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,7 @@ public byte[] Val {
public BsonOid(){}

public BsonOid(Oid oid){
//have to do some conversion here.
string oidstr = oid.Value;
if(oidstr.Length % 2 == 1){
oidstr = "0" + oidstr;
}
int numberChars = oidstr.Length;

byte[] bytes = new byte[numberChars / 2];
for (int i = 0; i < numberChars; i += 2){
try{
bytes[i / 2] = Convert.ToByte(oidstr.Substring(i, 2), 16);
}
catch{
//failed to convert these 2 chars, they may contain illegal charracters
bytes[i / 2] = 0;
}
}
this.Val = bytes;

this.val = oid.Value;
}

public int Size {
Expand Down
18 changes: 9 additions & 9 deletions MongoDBDriver/Collection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@

namespace MongoDB.Driver
{
/// <summary>
/// Description of Collection.
/// </summary>
public class Collection
{
private Connection connection;
Expand All @@ -36,7 +33,9 @@ public CollectionMetaData MetaData {
}
return metaData;
}
}
}

private static OidGenerator oidGenerator = new OidGenerator();

public Collection(string name, Connection conn, string dbName)
{
Expand Down Expand Up @@ -79,12 +78,11 @@ public long Count(){

public long Count(Document spec){
Database db = new Database(this.connection, this.dbName);
Collection cmd = db["$cmd"];
Document ret = cmd.FindOne(new Document().Append("count",this.Name).Append("query",spec));
if(ret.Contains("ok") && (double)ret["ok"] == 1){
try{
Document ret = db.SendCommand(new Document().Append("count",this.Name).Append("query",spec));
double n = (double)ret["n"];
return Convert.ToInt64(n);
}else{
}catch(MongoCommandException){
//FIXME This is an exception condition when the namespace is missing. -1 might be better here but the console returns 0.
return 0;
}
Expand All @@ -101,6 +99,7 @@ public void Insert(IEnumerable<Document> docs){
im.FullCollectionName = this.FullName;
List<BsonDocument> bdocs = new List<BsonDocument>();
foreach(Document doc in docs){
if(doc.Contains("_id") == false) doc["_id"] = oidGenerator.Generate();
bdocs.Add(BsonConvert.From(doc));
}
im.BsonDocuments = bdocs.ToArray();
Expand All @@ -127,10 +126,11 @@ public void Update(Document doc){
//otherwise just set the upsert flag to 1 to insert and send onward.
Document selector = new Document();
int upsert = 0;
if(doc["_id"] != null){
if(doc.Contains("_id") & doc["_id"] != null){
selector["_id"] = doc["_id"];
}else{
//Likely a new document
doc["_id"] = oidGenerator.Generate();
upsert = 1;
}
this.Update(doc, selector, upsert);
Expand Down
2 changes: 1 addition & 1 deletion MongoDBDriver/CollectionMetaData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public void CreateIndex(Document fieldsAndDirections, bool unique){
public void DropIndex(string name){
Document cmd = new Document();
cmd.Append("deleteIndexes",this.name).Append("index",name);
db["$cmd"].FindOne(cmd);
db.SendCommand(cmd);
this.refresh();
}

Expand Down
39 changes: 29 additions & 10 deletions MongoDBDriver/Database.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ namespace MongoDB.Driver
public class Database
{
private Connection connection;

private Collection command;

private String name;
public string Name {
get { return name; }
Expand All @@ -30,6 +31,7 @@ public DatabaseMetaData MetaData {
public Database(Connection conn, String name){
this.connection = conn;
this.name = name;
this.command = this["$cmd"];
}

public List<String> GetCollectionNames(){
Expand Down Expand Up @@ -60,8 +62,7 @@ public Document FollowReference(DBRef reference){
}

public bool Authenticate(string username, string password){
Collection cmd = this["$cmd"];
Document nonceResult = cmd.FindOne(new Document().Append("getnonce", 1.0));
Document nonceResult = this.SendCommand("getnonce");
String nonce = (String)nonceResult["nonce"];
if (nonce == null){
throw new MongoException("Error retrieving nonce", null);
Expand All @@ -73,25 +74,43 @@ public bool Authenticate(string username, string password){
auth.Add("user", username);
auth.Add("nonce", nonce);
auth.Add("key", Database.Hash(nonce + username + pwd));
Document authResult = cmd.FindOne(auth);
return (1.0 == (double)authResult["ok"]);
try{
this.SendCommand(auth);
return true;
}catch(MongoCommandException){
return false;
}
}
}

public void Logout(){
Collection cmd = this["$cmd"];
Document logoutResult = cmd.FindOne(new Document().Append("logout", 1.0));
double ok = (double)logoutResult["ok"];
this.SendCommand("logout");
}

public Document SendCommand(string str){
Document cmd = new Document().Append(str,1.0);
return this.SendCommand(cmd);
}

public Document SendCommand(Document cmd){
Document result = this.command.FindOne(cmd);
double ok = (double)result["ok"];
if (ok != 1.0){
throw new MongoException(String.Format("Error logging out: {0}",(string)logoutResult["msg"]), null);
string msg;
if(result.Contains("msg")){
msg = (string)result["msg"];
}else{
msg = string.Empty;
}
throw new MongoCommandException(msg,result,cmd);
}
return result;
}

internal static string Hash(string text){
MD5 md5 = MD5.Create();
byte[] hash = md5.ComputeHash(Encoding.Default.GetBytes(text));
return BitConverter.ToString(hash).Replace("-","").ToLower();
}

}
}
7 changes: 3 additions & 4 deletions MongoDBDriver/DatabaseMetaData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public Collection CreateCollection(String name){
public Collection CreateCollection(String name, Document options){
Document cmd = new Document();
cmd.Append("create", name).Update(options);
db["$cmd"].FindOne(cmd);
db.SendCommand(cmd);
return new Collection(name, connection, this.name);
}

Expand All @@ -35,7 +35,7 @@ public Boolean DropCollection(Collection col){
}

public Boolean DropCollection(String name){
Document result = db["$cmd"].FindOne(new Document().Append("drop",name));
Document result = db.SendCommand(new Document().Append("drop",name));
return result.Contains("ok") && ((double)result["ok"] == 1);
}

Expand All @@ -47,8 +47,7 @@ public void AddUser(string username, string password){
Collection users = db["system.users"];
string pwd = Database.Hash(username + ":mongo:" + password);
Document user = new Document().Append("user", username).Append("pwd", pwd);
Document userExists = users.FindOne(new Document().Append("user",username));
if (userExists != null){
if (FindUser(username) != null){
throw new MongoException("A user with the name " + username + " already exists in this database.", null);
}
else{
Expand Down
1 change: 1 addition & 0 deletions MongoDBDriver/MongoDB.Driver.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
<Compile Include="IO\DeleteMessage.cs" />
<Compile Include="IO\UpdateMessage.cs" />
<Compile Include="MongoRegex.cs" />
<Compile Include="OidGenerator.cs" />
<Compile Include="PairedConnection.cs" />
<Compile Include="Bson\BsonCodeWScope.cs" />
<Compile Include="Code.cs" />
Expand Down
18 changes: 18 additions & 0 deletions MongoDBDriver/MongoExceptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,22 @@ public MongoCommException(string message, Connection conn, Exception inner):base
this.port = conn.Port;
}
}

public class MongoCommandException : MongoException
{
private Document error;
public Document Error {
get {return error;}
}

private Document command;
public Document Command{
get {return command;}
}

public MongoCommandException(string message, Document error, Document command):base(message,null){
this.error = error;
this.command = command;
}
}
}
Loading

0 comments on commit 0899d98

Please sign in to comment.