cmille19
 New Member Posts:10

 |
| 15 Nov 2008 11:06 PM |
|
Has anyone tried to get db4o to work with Powershell? I cannot get the sample code to write an object to the db4o database within Powershell. I can when using a simple cmd.exe console application. For example the code in this posting works fine as a console application:
http://developer.db4o.com/forums/post/50440.aspx
However when I create a cmdlet using similar code and execute my newly created cmdlet, the file is created however no classes are written and no error messages:
using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Automation;
using System.Collections;
using Db4objects.Db4o;
using Db4objects.Db4o.Config;
namespace db4o
{
[Cmdlet(VerbsCommon.Set, "Db4o")]
public class SetDb4o : Cmdlet
{
protected override void ProcessRecord()
{
IConfiguration config = Db4oFactory.NewConfiguration();
config.ExceptionsOnNotStorable(true);
IObjectContainer db = Db4oFactory.OpenFile(config, "sampler.db4o");
DateTime myTime = DateTime.Now;
Console.WriteLine("Time is {0}", myTime);
db.Store(new Wrapper(myTime));
db.Commit();
IObjectSet items = db.QueryByExample(DateTime.Now);
WriteObject(items,true);
}
}
public class Wrapper
{
public DateTime _date;
public Wrapper(DateTime date)
{
_date = date;
}
}
}
|
|
|
|
|
marco.shaw Co-Community Director
 Basic Member Posts:195

 |
| 15 Nov 2008 11:22 PM |
|
After learning about it from Jonathan and Hal's podcast, I looked at the site. It seems beyond my current abilities, and anything I can try to learn for the time being. A few things from your code above: 1. You do "OpenFile(config,", yet online it is "OpenFile(config(),". 2. You use Console.WriteLine, which the PowerShell engine won't understand. Use WriteObject in its place like you do a few lines later. |
|
Marco
*Microsoft MVP - Windows PowerShell: http://www.microsoft.com/mvp *PowerGadgets MVP: http://www.powergadgets.com/mvp *Blog: http://marcoshaw.blogspot.com |
|
|
meson3902
 New Member Posts:13

 |
| 16 Nov 2008 12:18 AM |
|
I have been trying to get something to work myself and I have been unable to get it to work. After you have run it as a command line were you able to use an existing utility to examine the database? I actually created a cmdlet that used a datetime object. The cmdlet ran correctly but none of the existing tools such as Object Manager could read the database.
|
|
|
|
|
cmille19
 New Member Posts:10

 |
| 16 Nov 2008 12:25 AM |
|
They're using a seperate method called config, just simplifying a little by directly using a variable config instead. Agreed about console.writeline although it seems to works fine in Powershell. I've also tried a dozen or so variations of my own own code with no success actually writing to the db4o file. I can create the cmdlet successfully and run Set-Db4o from Powershell the file, in the sample code, file sampler.db4o gets created its just that nothing is actually written to file whereas nearly identical code in a classic console application works fine.
This is a difficult challenge, db4o is implemented through interfaces which Powershell without implementing a provider has little understanding of. In addition db4o as mentioned in the original link requires a true class and cannot work with value types. It also cannot work with PSobject type (the db4o file will fill with several hundred MB of data for even simple objects before having to kill it). And then there's another problem of db4o requiring strong static types where in Powershell we don't have that issue. There might be some things in .NET 3.5 to get around the typing issues, however since we're using Powershell V1 we have to use .NET 2.0 .
But, for now I'm just trying to do the most basic thing possible with little success. I'm starting to think the challenge is also beyond my current abilities and you would need a deep understanding of db4o internals and implementation to make it work with Powershell. |
|
|
|
|
cmille19
 New Member Posts:10

 |
| 16 Nov 2008 12:35 AM |
|
PostedBy meson3902 on 11/15/2008 4:18 PM
I have been trying to get something to work myself and I have been unable to get it to work. After you have run it as a command line were you able to use an existing utility to examine the database? I actually created a cmdlet that used a datetime object. The cmdlet ran correctly but none of the existing tools such as Object Manager could read the database.
Yes, Object Manager Enterprise plugin for VS 2008 http://developer.db4o.com/files/folders/ome/default.aspx was able to read both the console generated yap/db4o file and the Powershell generated. The console generated file shows 1 class in the file and the Powershell generated shows 0 classes. In my Set cmdlet I also do a db4o "Query By Example" immediately after storing the class, nothing is returned. Again the classic console version seems to work fine.
|
|
|
|
|
marco.shaw Co-Community Director
 Basic Member Posts:195

 |
| 16 Nov 2008 12:41 AM |
|
You mention "PowerShell v1 and .NET 2.0"... Remember that even v2 will be built against .NET 2.0. I'll ask the PowerShell dev team what they think... |
|
Marco
*Microsoft MVP - Windows PowerShell: http://www.microsoft.com/mvp *PowerGadgets MVP: http://www.powergadgets.com/mvp *Blog: http://marcoshaw.blogspot.com |
|
|
cmille19
 New Member Posts:10

 |
| 16 Nov 2008 01:11 AM |
|
BTW I'm using db4o 7.4 (I also tried 6.4 and 7.7) and I'm using Object Manager Enterprise 7.7 VS 2008 Plugin to open the yap/db4o file: http://developer.db4o.com/files/folders/ome/entry51766.aspx |
|
|
|
|
meson3902
 New Member Posts:13

 |
| 16 Nov 2008 01:27 AM |
|
this is what I have:
using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Automation;
using System.Collections;
using Db4objects.Db4o;
namespace DB4O
{
[Cmdlet(VerbsCommon.Add, "db4oRecord", SupportsShouldProcess = true)]
public class Add_db4oRecord : PSCmdlet
{
private string _FileName;
private PSObject _Value;
IObjectContainer database;
#region Parameters
[Parameter(Position = 0,
Mandatory = true,
ValueFromPipelineByPropertyName = false,
HelpMessage = "To be written")]
[ValidateNotNullOrEmpty]
public string FileName
{
set { _FileName = value; }
}
[Parameter(Position = 0,
Mandatory = true,
ValueFromPipeline = true,
HelpMessage = "To be written")]
[ValidateNotNullOrEmpty]
public PSObject Value
{
set
{
_Value = value;
}
}
#endregion
protected override void BeginProcessing()
{
base.BeginProcessing();
}
protected override void ProcessRecord()
{
try
{
Db4oFactory.Configure().ExceptionsOnNotStorable(true);
//
database = Db4oFactory.OpenFile(_FileName);
//DateTime Test = new DateTime(2008, 12, 25);
TestClass ThisTest = new TestClass();
ThisTest.Property = "Something";
database.Store(ThisTest);
database.Close();
//database.Store(_Value.BaseObject);
}
catch (Exception)
{
}
}
protected override void EndProcessing()
{
base.EndProcessing();
}
}
}
|
|
|
|
|
halr9000 PowerShell MVP, Site Admin
 Basic Member Posts:335

 |
|
EBGreen
 New Member Posts:64

 |
| 17 Nov 2008 03:30 PM |
|
I think this is a very vluable discussion because it extends the understanding of how to do things in Powershell, but I was curious what advantage DB4O would give over simply using Export-CliXML to preserve object state? |
|
|
|
|
cmille19
 New Member Posts:10

 |
| 18 Nov 2008 05:02 PM |
|
Using Export-CLIXML is basically equivalent to using file based storage for each object. Let's say you have 12 objects you'll end up with 12 files. Using a database, in this case db4o, the physical implementation of files is abstracted away and you only have to write your objects to one database. The database, db4o, also implements a query language which is supposed to make retrieving objects more efficient and simplier than XML serialization. |
|
|
|
|
dschoeck
 New Member Posts:3

 |
| 20 Nov 2008 03:44 AM |
|
I've been trying to access DB4O from within the Powershell Console directly, with little success. I have gotten 2 different results on writing a database file from Powershell, one I believe is correct and the other is a spurious result. I am accessing the .dll via reflection.assembly. Drop your database file onto notepad or add the extension ".txt" to the filename to trick Notepad into opening it. On one of the variations there is some type code that appears to be Powershell writing a bogus file, but on the one I think is working correctly I get a file with 2 fields visible... "Name" and "Value". I think that this is the default for an empty DB4O container. I have been unable as of yet to get any objects to successfully store in the containers. Right now I am on a different machine than the one I have been testing on so I can't access the code at this point, but the notepad trick works well to see what is going on inside the files that are being written. I've tried piping objects into a container, but it hasn't worked yet. I do not know if that is due to syntax or other issues. Accessing dotNet assemblies from within Powershell seems to be very non-intuitive at times. BTW, I am also the guy who originally wrote Hal asking about this on the podcast. |
|
|
|
|
dschoeck
 New Member Posts:3

 |
| 22 Nov 2008 05:02 AM |
|
The main thing that started me looking at this initially was the ability to aggregate objects. Put another way, the ability to use objects as properties for other objects. Say you are building a car. The same body can have several engines and several transmissions, as well as several trim packages and accessories. Everyone who looks at a car may want to order it with their own engine/transmission/trim/color combination. Usually this kind of information is stored in a relational database with tables. Each table will hold only a small subset of the information, and in this case, since each combination can be used in several different cars, link tables will be set up with just links from one table to another. Rules need to be set up to keep everything working during transactions and queries, and in a complicated setup this step can be pretty involved. This is usually done in some variation of SQL, and to be maintainable it needs to be set up with great care. Object aggregation allows you to create a set of engine objects (4, 6, and 8 cylinder, for example) add properties (torque, efficiency) and methods (run fast, run slow) and then connect those objects to the main car object. Building the data object for the car can mimic building the real thing. This can be handy, especially when you need to pull different information from each combination and when there are a lot of unique combinations being generated that need to be stored. (Say, for example, you need to calculate a max speed that has to take into account the type of engine(4,6,or8 cylinder), intake (turbo or not), transmission (manual, 3, or 4 speed auto), rear differential gear ratio, tire size, and trim package (aerodynamic or not) - and connect that to an order. The number of variables in a combination like that will require major head-scratching to be able to set up a relational structure to handle it. The flexibility in Aggregation is especially handy with objects when someone decides that changes need to be added after the initial design and build of the database. On a relational database, you need to look at the structure, decide if the information needs to go in a separate table or in existing ones, set up the relationships, SQL queries, etc. A few rounds of this can make a nice database really ugly. The "impedance mismatch" that the DB4O people talk about on the website refers to the need to jump back-and-forth between object space in the programming and relational space in the database design. They require two different frames of mind. With objects, you attach the properties and methods to the affected objects and update the object set. There are downsides, but for rapid design object-based generally wins. I have not found a way to easily aggregate objects in native powershell, but I am fairly new to it. DB4O looked like a good fit, since it is dotNet, and is optimized for handling a few million objects at a time. Like most everyone here, I have poked at DB4O and gotten it to kick back(write files), but it hasn't run in a meaningful way yet(hasn't stored any data in the files. I believe aggregations could be done in Powershell natively, and have found a few bits and pieces in places like Cash Foley's blog (look towards the bottom), but it will take time to explore and develop a set of functions/commands to allow the necessary capabilities. |
|
|
|
|
cmille19
 New Member Posts:10

 |
| 24 Nov 2008 04:23 PM |
|
I noticed the same type of behavior where name, value and the name of my class member along with a GUID are written to the db4o file, however the data for my class member is not written. |
|
|
|
|
dschoeck
 New Member Posts:3

 |
| 05 Dec 2008 02:15 AM |
|
I've found another option in persistent storage. It's called Perst, and it is packaged as a .net .dll and licensed under a dual-licensing scheme similar to DB4O. I have found the interface to be a bit more clear than DB4O, ad the error messages a bit more useful. www.mcobject.com/perst It fails roughly at the same point for me as DB4O, but errors out a bit more gracefully. Example: [reflection.assembly]::loadfrom((resolve-path C:\PerstNet20.dll)) #[reflection.assembly]::loadwithpartialname("Microsoft.VisualStudio.OLE.Interop") # Added as an experiment with the IPersist #object and interfaces in the assembly. Probably will not work. Commented out. $Storage = [Perst.StorageFactory]::get_Instance().CreateStorage() $Storage.Open("C:\Test.dbs", 4096) $Storage.CreateIndex("String","True") $Storage.CreateSet() # Everything works fine to here... $Storage.Root = ("Orders.Class","ClassExtent") #error here is that the object is cast as the wrong type. The mechanism for object-storage is different in principle, in that all objects are cast as an "IPersist" object type. I tried to force a casting for my object, but this threw an error that there was no constructor found for this object type. The above code is probably wrong in a few particulars, but seems to have the basic functions for the library working, and follows pretty closely to the tutorial material supplied with the .dll.
|
|
|
|
|
germanviscuso
 New Member Posts:1

 |
| 11 Dec 2008 11:03 AM |
|
Hi guys. I regret you're experiencing problems with integrating db4o (sounds like a really nice thing to do). I have reviewed the thread and this seems like a bug for storing objects in db4o from Powershell. I have filled in this issue in our jira tracker so that the core team developers can take a look at it: http://tracker.db4o.com/browse/COR-1483 (note that you can vote on and watch the issue on jira) Best regards and thanks guys for giving it a shot. German Viscuso db4objects community manager |
|
|
|
|
halr9000 PowerShell MVP, Site Admin
 Basic Member Posts:335

 |
|
adrianoc
 New Member Posts:2

 |
| 30 Dec 2008 12:50 PM |
|
Hi. First of all, sorry for my english :( IMO your query is falling to find any object because you are using a datetime (which certainly has advanced in time when compared to the saved one). Try to use the same value instead (something like): var date = DateTime.Now; db.Store(new Wrapper(date)); . . . var results = db.QueryByExample(new Wrapper(date)); I have been playing with a cmdlet and I was able to store PSObjects into a db4o database. To do that I just wrote a (very simple) custom typehandler (http://developer.db4o.com/Resources/view.aspx/Reference/Implementation_Strategies/TypeHandlers). I'll do a little more experiment regarding querying. I can attach the whole project if you want. best Adriano |
|
|
|
|
cmille19
 New Member Posts:10

 |
| 01 Jan 2009 04:37 PM |
|
Thanks for taking a look at the issues we were having. It sounds like you've gotten further than the rest us by using a db4o typehandler and you may even have a completed solution. Whenever you're ready, please do post your project either here or on a project hosting site such as CodePlex.
|
|
|
|
|
adrianoc
 New Member Posts:2

 |
| 07 Jan 2009 06:49 PM |
|
Hi, I've just posted a blog entry about my journey writing a simple cmdlet to persist PowerShell objects into Db4o. Surely it has limitations but I think it may be used as a start for a more elaborated one :) Take a look at: http://developer.db4o.com/blogs/product_news/archive/2008/12/30/storing-powershell-objects-into-a-db4o-database.aspx Feel free to comment. Adriano |
|
|
|
|