Execute arbitrary SQL inside a plug-in?

Posts   
 
    
jungans
User
Posts: 18
Joined: 23-Jul-2006
# Posted on: 23-Jun-2009 22:13:32   

Hi, Is it possible to read the contents of a given db table from inside a plug-in?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 24-Jun-2009 03:34:27   

I think that isn't intended for that. It might be possible, but I think it isn't recommended. What do you want to do?

David Elizondo | LLBLGen Support Team
jungans
User
Posts: 18
Joined: 23-Jul-2006
# Posted on: 24-Jun-2009 05:16:51   

I'd like to build an enum from the contents of a specific column so I can refer to rows in a typed way. Is there a way to do this using LLBL's code generation engine?

Walaa avatar
Walaa
Support Team
Posts: 14987
Joined: 21-Aug-2005
# Posted on: 24-Jun-2009 09:09:52   

Would an enum TypeConverter solve your problem. Please check this thread: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7355

jungans
User
Posts: 18
Joined: 23-Jul-2006
# Posted on: 25-Jun-2009 00:34:46   

I came up with a plug-in that automatically solves the problem. The code is not pretty nor is it platform independent, but it serves us well. Also, I know I asked about enums but then I wanted to go one step further. The plug-in runs after code generation has finished. It scans all entities looking for a special field (of type string). When an entity with such field is found, the plug-in generates one static method named after the value of the special field for each row. An example would be:


PaymentMethodId   Description   Accepted
1                             Cash              1
2                             Paypal            1
3                             Credit Card   0

Lets say our special field for this entity is 'Description'. The plug-in would query the PaymentMethod table and generate something like:

public class PaymentMethod
{
    static Dictionary<string, PaymentMethodEntity> _cache = null;
    static PaymentMethodEntity get(string code)
    {
        if (_cache == null)
        {
            (from x in new LinqMetaData().PaymentMethod 
             where x. Description != null 
             select x).ToDictionary(x => x.Description, y => y);
        }
        if (_cache.ContainsKey(code)) return _cache\[code\];
        throw new Exception(string.Format("Could not find {0} in entity {1}", code, "PaymentMethod"));
    }
    public static void ResetCache()
    {
        _cache = null;
    }
    public static PaymentMethodEntity Cash
    {
        get { return get("Cash"); }
    }
    public static PaymentMethodEntity Paypal
    {
        get { return get("Paypal"); }
    }
    public static PaymentMethodEntity CreditCard
    {
        get { return get("Credit Card"); }
    }
}

This way, I can use

PaymentMethod.Cash

to refer to the first row of the table (it could not be the first row in another instance of the db). Plus I get a cache for all instances of this entity.

I know the best way to implement such functionality would have been a TaskPerformer but I didn't have much time so I just went ahead with the plug-in method.

The code is a bit messy and only runs on SQL Server databases. Let me know if you are interested and I'll post it.

Thanks. Iván.