Archive for the '18097' Category

SharpMongo en C# (3) Implementando el REPL

Tuesday, June 17th, 2014

Anterior Post

Quería describir hoy algo de la implementación del REPL (Read Eval Print Loop) que implementé para SharpMongo en:

https://github.com/ajlopez/SharpMongo

Recordemos, SharpMongo es una base NoSQL basada en documentos, inspirada en MongoDB. Es trabajo en progreso, pero el núcleo ya está bastante implementado. El REPL es un utilitario de consola que sirve para probar algunos comandos.

Para implementar cosas como atender:

> db.people.insert({ Name: 'Adam', Age: 800 })
> db.people.insert({ Name: 'Eve', Age: 700 })
> show collections
people  

tuve que manejar un objeto Database que tuviera propiedades, y que esa propiedad (por ejemplo .people en el código de arriba) fuera una colección de documentos, incluso una no existente.

Curiosamente, la implementación de un objeto así está basada en los propios DynamicObject que tiene el núcleo de SharpMongo: los documentos que mantiene SharpMongo en memoria son objetos del tipo DynamicObject, y los objetos que maneje el REPL, también.

He aquí la implementación actual de DbObject

https://github.com/ajlopez/SharpMongo/blob/master/Src/SharpMongo.Language/DbObject.cs

public class DbObject : DynamicObject
{
    private DocumentBase dbase;

    public DbObject(DocumentBase dbase)
    {
        this.dbase = dbase;
    }

    public DocumentBase DocumentBase { get { return this.dbase; } }

    public override object GetMember(string name)
    {
        return new CollectionObject(this.dbase.GetOrCreateCollection(name));
    }
}

La forma de implementar la propiedad dinámica .people es redefinir el método que consigue una propiedad por nombre. En vez de basarse en el método de la clase madre, que mantiene un diccionario de las propiedades, en el código de arriba se devuelve una colección de documentos dentro de la base de documentos que estemos trabajando. Si ven el código y la historia del proyecto, todo esto fue programando usando TDD.

Próximos posts: implementación del objecto Collection en el REPL, parser, lexer, operadores

Nos leemos!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

SharpMongo (2) Un REPL

Sunday, September 15th, 2013

Anterior Post

Sigo trabajando en mi proyecto de almacén de documentos en memoria, en proceso, escrito en C#

https://github.com/ajlopez/SharpMongo

Intenta implementar las operaciones de MongoDB: tener document bases, collections, documents, objetos dinámicos, etc. Pero con la diferencia: todo en memoria, en el mismo proceso. La persistencia a disco será una especie de plugin.

Una de las herramientas que quería tener es un REPL (Read Eval Print Loop), un programa de consola que emulara las principales funciones del programa MongoDB cliente consola original (ese cliente se conecta con un servidor; en el caso actual, SharpMongo funciona directamente en el mismo proceso, y en la misma memoria del programa de consola)

El proyecto es SharpMongo.Console, y produce un assembly sharpmongo.exe. Lanzándolo desde una línea de comando, comienza a ejecutar lo que le ingresemos por línea en el prompt:

SharpMongo 0.0.1
> show dbs
> show collections
> use foo
> show dbs
foo  

Ahora estamos en una db (document base) llamada ‘foo’. Podemos directamente crear una collection insertando documentos dinámicos (en un formato tipo JSON):

> db.people.insert({ Name: 'Adam', Age: 800 })
> db.people.insert({ Name: 'Eve', Age: 700 })
> show collections
people  

Podemos buscar todos los elementos de la collection:

  > db.people.find()
{ "Name": "Adam", "Age": 800, "Id": 4d802e11-a038-468e-bd26-38e96ad6f7d8 }
{ "Name": "Eve", "Age": 700, "Id": b29917f1-70f1-4f6c-95bb-f789fa9bf3c0 }  

O podemos buscar los que cumplan con un criterio, expresado en un objeto dinámico query (tipo query by example):

  > db.people.find({ Name: 'Adam' })
{ "Name": "Adam", "Age": 800, "Id": 4d802e11-a038-468e-bd26-38e96ad6f7d8 }  

Podemos seguir insertando documentos y ver el resultado

> db.people.insert({ Name: 'Cain', Age: 600 })
> db.people.insert({ Name: 'Abel', Age: 500 })
> db.people.find()
{ "Name": "Adam", "Age": 800, "Id": 4d802e11-a038-468e-bd26-38e96ad6f7d8 }
{ "Name": "Eve", "Age": 700, "Id": b29917f1-70f1-4f6c-95bb-f789fa9bf3c0 }
{ "Name": "Cain", "Age": 600, "Id": a5a3e1af-7e5c-4c16-829e-c07f94bc8697 }
{ "Name": "Abel", "Age": 500, "Id": c1da0055-8ded-4540-876f-5c032f514ed3 }  

Podemos insertar y remover

> db.people.insert({ Name: 'Pluto' })
> db.people.find()
{ "Name": "Adam", "Age": 800, "Id": 4d802e11-a038-468e-bd26-38e96ad6f7d8 }
{ "Name": "Eve", "Age": 700, "Id": b29917f1-70f1-4f6c-95bb-f789fa9bf3c0 }
{ "Name": "Cain", "Age": 600, "Id": a5a3e1af-7e5c-4c16-829e-c07f94bc8697 }
{ "Name": "Abel", "Age": 500, "Id": c1da0055-8ded-4540-876f-5c032f514ed3 }
{ "Name": "Pluto", "Id": 0561864a-470a-4437-9467-773ffb5a438a }
> db.people.remove({ Name: 'Pluto' })
> db.people.find()
{ "Name": "Adam", "Age": 800, "Id": 4d802e11-a038-468e-bd26-38e96ad6f7d8 }
{ "Name": "Eve", "Age": 700, "Id": b29917f1-70f1-4f6c-95bb-f789fa9bf3c0 }
{ "Name": "Cain", "Age": 600, "Id": a5a3e1af-7e5c-4c16-829e-c07f94bc8697 }
{ "Name": "Abel", "Age": 500, "Id": c1da0055-8ded-4540-876f-5c032f514ed3 }   

Hay varias cosas que faltan, del MongoDB original, la más importante debe ser el soporte de operadores en los objetos query, que permiten buscar por otros criterios más allá de la igualdad por campo, y operadores en los objetos update. Pero todo vendrá, como siempre, usando TDD

Nos leemos!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

SharpMongo (1) Primeras Clases

Sunday, September 8th, 2013

Siguiente Post

Ya saben que estoy estudiando MongoDB. En un proyecto no público, mi cliente lo está usando y yo estoy desarrollando una alternativa OLAP en memoria, una extensión de mi Memolap. Como me gusta implementar almacenes en memoria, decidí construir uno en C#, en memoria, en proceso:

https://github.com/ajlopez/SharpMongo

Como siempre, el desarrollo usando TDD:

https://github.com/ajlopez/SharpMongo/commits/master

y dejando evidencia prácticamente por tests. También lo estoy implementando en JavaScript/Node.js, pero está mucho menos adelantado:

https://github.com/ajlopez/SimpleMongo

Espero presentar el estado de mi trabajo en la próxima meetup de MongoDB acá en Buenos Aires (así como ejemplos sencillos de MongoDB real con Node.js).

Si ven el estado actual de SharpMongo, tiene:

– Proyecto de clases SharpMongo.Core
– Proyecto de tests SharpMongo.Core.Tests
– Proyecto de clases SharpMongo.Language, donde estoy implementando un lenguaje sencillo para un cliente de consola
– Proyecto de tests SharpMongo.Language.Tests
– Proyecto de consola SharpMongo.Console

Hoy quería comentar sobre las clases de base que tengo:

Engine tiene una lista de DocumentBase. Un DocumentBase puede tener varias Collection. Los documents y objetos dinámicos:

Un Collection contiene DynamicDocuments. La diferencia entre un DynamicObject y un DynamicDocument es que este último tiene un Id. Ya tengo implementado en Collection los métodos:

– Insert
– Find (con query y projection)
– Remove (con query)
– Save (con y sin Id previo)
– Update

Y el proyecto de consola tiene varios comandos implementados. Pero eso ya es tema para otro post.

Próximos pasos:

– Operadores en Find
– Count
– Arreglos y Objetos Dinámicos anidados en DynamicObject
– Mejor impresión en el programa de consola

Luego, una vez estabilizado eso, tendría que encarar el manejo de concurrencia (o establecer que las modificaciones son serializadas). Si les parece, puede agregar:

– Servidor que revisa líneas por TCP, que describan en JSON plano los comandos a ejecutar, y devuelva JSON

– Clientes en C#, JavaScript, PHP?

Tantas ideas 😉

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez