Karmencita: an object query language for .NET
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 24.03.06 09:06
Оценка: 10 (2)
Karmencita: an object query language for .NET

Karmencita is an object query language for .NET. Its purpose is to allow easy querying from in-memory structured data.

[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Karmencita: an object query language for .NET
От: Cyberax Марс  
Дата: 24.03.06 09:39
Оценка:
SchweinDeBurg wrote:
> Karmencita: an object query language for .NET
> <http://www.codeproject.com/csharp/Karmencita.asp&gt;
> Karmencita is an object query language for .NET. Its purpose is to allow
> easy querying from in-memory structured data.
Лучше бы OGNL (http://www.ognl.org/) портировали...
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re: Karmencita: an object query language for .NET
От: Oyster Украина https://github.com/devoyster
Дата: 24.03.06 09:43
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>

SDB>Karmencita is an object query language for .NET. Its purpose is to allow easy querying from in-memory structured data.


Судя по примерам, там только фильтрация данных осуществляется... или я неправ?
Re[2]: Karmencita: an object query language for .NET
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 24.03.06 09:48
Оценка: 1 (1)
Здравствуйте, Oyster, Вы писали:

O>Судя по примерам, там только фильтрация данных осуществляется... или я неправ?


Насколько я понимаю — прав.
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Karmencita: an object query language for .NET
От: c-smile Канада http://terrainformatica.com
Дата: 24.03.06 18:57
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Karmencita: an object query language for .NET


SDB>

SDB>Karmencita is an object query language for .NET. Its purpose is to allow easy querying from in-memory structured data.


Примерно то же самое но для Java в исполнении Константина Книжника:

JSQL: http://www.garret.ru/~knizhnik/jsql/readme.htm
Re: ;)
От: Зверёк Харьковский  
Дата: 25.03.06 07:28
Оценка:
// initialize the data source
// (in this case a Stack of Customers)
Stack<Customer> customers = .....

// initialize Karmencita with
// the type of object to be queries
ObjectQuery<Customer> oq = new ObjectQuery<Customer>();

// write the query
string query = "Name = [Thor the Mighty]" + 
               " and IsMale = true and BirthDate" + 
               " < [1,1,1910]";

//run the query
Customer[] result = (Customer[]) oq.Select(customers, query);

Это Карменсита ваша.

# initialize the data source
customers = ...

# creating block, which receives customer and test it
oq = proc {|cust| cust.name == "Thor the Mighty" &&
                  cust.male? && cust.birth_date < Date.new(1910) }

# using Array::select
result = customers.select(&oq)

А это Руби

ЗЫ: не флейма очередного ради. Просто — м.б. кого-то это натолкнет на вумные мысли
FAQ — це мiй ай-кью!
Re[2]: ;)
От: Cyberax Марс  
Дата: 25.03.06 10:46
Оценка:
Зверёк Харьковский wrote:
> # initialize the data source
> customers = ...
>
> # creating block, which receives customer and test it
> oq = proc {|cust| cust.name == "Thor the Mighty" &&
> cust.male? && cust.birth_date < Date.new(1910) }
>
> # using Array::select
> result = customers.select(&oq)
> А это Руби
Раз уж пошла такая пьянка...
BOOST_RTL_DEFINE_COLUMN(std::string, Name);
BOOST_RTL_DEFINE_COLUMN(bool, IsMale);
BOOST_RTL_DEFINE_COLUMN(gregorian::date, BirthDate);

typedef boost::mpl::vector3<Name,IsMale,BirthDate> fld_list;
struct People : table_info<fld_list>{};

expr_type epxr=select((m_people),
    col<0, People::Name>() == "Thor The Mighty" &&
    col<0, People::IsMale>() == true &&
    col<0, People::BirthDate>() < gregorian::date("1/1/1910")
    ;

selection(expr,table);

Boost.Relational_Template_Library (сейчас в очереди на review)

Все типы контролируются во время компиляции.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[2]: ;)
От: Oyster Украина https://github.com/devoyster
Дата: 25.03.06 11:28
Оценка: +2
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>ЗЫ: не флейма очередного ради. Просто — м.б. кого-то это натолкнет на вумные мысли


Я тоже вначале подумал, что всё то же самое можно сделать с помощью анонимных методов C# 2.0. Например, приведённый тобой пример будет выглядеть где-то вот так:

// Initialize
List<Customer> customers = ...;

// Filter
customers = customers.FindAll(
    delegate(Customer cust)
    {
        return
            cust.Name == "Thor the Mighty" &&
            cust.IsMale &&
            cust.BirthDate.Year < 1910;
    });

Но фишка Karmencita, естественно, не в этом. Её фишка в том, что единообразно можно фильтровать наборы данных разной структуры. Такие, например, как List, DataTable и XmlDocument. При этом последние два не содержат объектов вообще — в них данные хранятся в совершенно другом виде, который не должен при фильтрации "преобразовываться" к коллекции объектов (например, при фильтрации DataTable нам надо получить на выходе именно коллекцию DataRow и ничто иное).
Re[3]: ;)
От: Зверёк Харьковский  
Дата: 25.03.06 13:18
Оценка:
Здравствуйте, Oyster, Вы писали:

O>Здравствуйте, Зверёк Харьковский, Вы писали:


ЗХ>>ЗЫ: не флейма очередного ради. Просто — м.б. кого-то это натолкнет на вумные мысли


O>Я тоже вначале подумал, что всё то же самое можно сделать с помощью анонимных методов C# 2.0. Например, приведённый тобой пример будет выглядеть где-то вот так:


[зверьковыгрызено]

O>Но фишка Karmencita, естественно, не в этом. Её фишка в том, что единообразно можно фильтровать наборы данных разной структуры. Такие, например, как List, DataTable и XmlDocument. При этом последние два не содержат объектов вообще — в них данные хранятся в совершенно другом виде, который не должен при фильтрации "преобразовываться" к коллекции объектов (например, при фильтрации DataTable нам надо получить на выходе именно коллекцию DataRow и ничто иное).


Не совсем понял, о том ли я говорю, но... в руби достаточно реализовать в классе метод each (обход всех объектов "коллекции"), и "примешать" к классу модуль Enumerable, и метод select, который я продемонстрировал, будет работать.
Давай кодом покажу:

#где-то уже есть класс DataTable. Но в руби все классы открытые, поэтому пишем здесь:

class DataTable
  def each #естественно, это все надо только если у DataTable еще нет метода each, что вряд ли.
    #каким-то образом перебираем все DataRow, для каждого вызывая
    yield row
  end
  
  include Enumerable #а это мы подмешали модуль Enumerable
end

#используем:

dt = load_data_table_from_somewhere

dt.select {|cust| cust.name == "Thor the Mighty" && cust.male? && cust.birth_date < Date.new(1910) }


Ы?
FAQ — це мiй ай-кью!
Re[4]: ;)
От: Oyster Украина https://github.com/devoyster
Дата: 25.03.06 13:23
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Ы?


Видимо, таки не понял. Цитата из моего сообщения:

При этом последние два не содержат объектов вообще — в них данные хранятся в совершенно другом виде, который не должен при фильтрации "преобразовываться" к коллекции объектов (например, при фильтрации DataTable нам надо получить на выходе именно коллекцию DataRow и ничто иное).


Выделенное читай как "мы не хотим временно конструировать новый объект типа Customer для каждого DataRow".

[офф]
Кстати, в C# 2.0 мы тоже можем унаследовать любой наш класс от IEnumerable, загнать результат енумерации в List<T> и дальше делать что хотим.
[/офф]
Re[5]: ;)
От: Зверёк Харьковский  
Дата: 25.03.06 13:27
Оценка:
Здравствуйте, Oyster, Вы писали:

ЗХ>>Ы?


O>Видимо, таки не понял. Цитата из моего сообщения:


O>

O>При этом последние два не содержат объектов вообще — в них данные хранятся в совершенно другом виде, который не должен при фильтрации "преобразовываться" к коллекции объектов (например, при фильтрации DataTable нам надо получить на выходе именно коллекцию DataRow и ничто иное).


O>Выделенное читай как "мы не хотим временно конструировать новый объект типа Customer для каждого DataRow".


Мняяя... Что-то я сегодня совсем торможу... А почему это понадобится его конструировать?

O>[офф]

O>Кстати, в C# 2.0 мы тоже можем унаследовать любой наш класс от IEnumerable, загнать результат енумерации в List<T> и дальше делать что хотим.
O>[/офф]

Не сомневаюсь. Моя идея, как обычно, не в том, что <любимый мной на данный момент язык> == манна небесная, просто интересно сравнить подходы.
FAQ — це мiй ай-кью!
Re[6]: ;)
От: Oyster Украина https://github.com/devoyster
Дата: 25.03.06 13:38
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Мняяя... Что-то я сегодня совсем торможу... А почему это понадобится его конструировать?


Чтобы делегат сработал. Конкретно в DataRow данные хранятся "без имени" — массив колонок и массив значений, грубо говоря.

ЗХ>Не сомневаюсь. Моя идея, как обычно, не в том, что <любимый мной на данный момент язык> == манна небесная, просто интересно сравнить подходы.


Вообще поход C# мне тут не очень симпатичен... Не хватает, например, статических методов вроде FindAll в стандартной библиотеке (ну как в STL — стандартные алгоритмы, подходящие для любого контейнера).
Re[2]: ;)
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.03.06 13:41
Оценка: 1 (1) +1
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>
ЗХ># initialize the data source
ЗХ>customers = ...

ЗХ># creating block, which receives customer and test it
ЗХ>oq = proc {|cust| cust.name == "Thor the Mighty" &&
ЗХ>                  cust.male? && cust.birth_date < Date.new(1910) }

ЗХ># using Array::select
ЗХ>result = customers.select(&oq)
ЗХ>

ЗХ>А это Руби

О! Массовая пенисометрия!
И меня с Немерлом запишите пожалуйста!
def result = customers.Filter(fun(cust)
{
  cust.Name == "Thor the Mighty" && cust.IsMale && cust.BirthDate.Year < 1910
});


А вот так будет выглядить полный тест:
using System;
using System.Console;

[Record]
class Customer
{
  public Name      : string;
  public IsMale    : bool;
  public BirthDate : DateTime;
  
  public override ToString() : string
  {
    $"Name: '$Name' Is male: $IsMale  Birth date: $BirthDate";
  }
}

def customers = [Customer("Ivan",            true, DateTime(1910, 1, 1)),
                 Customer("Vlad",            true, DateTime(1974, 4, 25)),
                 Customer("Vika",           false, DateTime(1911, 2, 1)),
                 Customer("Thor the Mighty", true, DateTime(1900, 2, 1))];

def result = customers.Filter(fun(cust)
{
  cust.Name == "Thor the Mighty" && cust.IsMale && cust.BirthDate.Year < 1910
});

WriteLine(result);

Он выведет:
[Name: 'Thor the Mighty' Is male: True  Birth date: 01.02.1900 00:00:00]


Забавно будет сравнить полные тесты на разных языках. В том что С++ и C# сольют по краткости и понятности я даже не сомневаюсь. А вот с Руби посоревнаваться действительно забавно. Все же динамически типизированный скрипт обязан выглядеть лучше статически типизрованного компилируемого языка. И если это не так, или разница несущественна, то в пору задуматься, над необходимостью этих скриптов.


ЗХ>ЗЫ: не флейма очередного ради. Просто — м.б. кого-то это натолкнет на вумные мысли


Ага. Например, на то, что скрипты лишились последних аргументов в свою защиту.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: ;)
От: Oyster Украина https://github.com/devoyster
Дата: 25.03.06 13:43
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>О! Массовая пенисометрия!

VD>И меня с Немерлом запишите пожалуйста!

Как раз думал — выкладывать пример на Nemerle или нет...
Re[5]: ;)
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.03.06 13:58
Оценка:
Здравствуйте, Oyster, Вы писали:


O>Кстати, в C# 2.0 мы тоже можем унаследовать любой наш класс от IEnumerable, загнать результат енумерации в List<T> и дальше делать что хотим.


Зачем в List<T>? В C# 2.0 есть итераторы. Можно так же как в Руби только типизированно:
IEnumerable<int> Ints()
{
    for (int i = 0;; i++)
        yield return i; 
}

В Немерле можно так же, а можно рекурсией взять.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: ;)
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.03.06 13:58
Оценка: +1
Здравствуйте, Oyster, Вы писали:

O>Вообще поход C# мне тут не очень симпатичен... Не хватает, например, статических методов вроде FindAll в стандартной библиотеке


Да есть они. Только для конкретных типов коллекций. Ну, а написать статические функнции для IEnumerable<T> ничего не стоит:
static IEnumerable<T> Filter(IEnumerable<T> seq, Predicate<T> predicate)
{
    foreach (T elem in seq)
        if (predicate(elem))
            yield return elem;
}


В C# 3.0 будут методы расширения которые позволят вызывать статические методы через точку.

O>(ну как в STL — стандартные алгоритмы, подходящие для любого контейнера).


Вряд ли бинарный поиск может подойти для хэш-таблицы. Так что это не так. А универсальные вещи и на C# пишутеся влет.

Так что могу согласиться только с тем, что в дотнете на сегодня нет универсальных методов вроде приведенного мной. Но это не проблема языка. Это проблема библиотек.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: ;)
От: Oyster Украина https://github.com/devoyster
Дата: 25.03.06 14:01
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Зачем в List<T>?


Я рассматривал решение для фильтрации коллекции при использовании средств исключительно из BCL.
Re[3]: ;)
От: Зверёк Харьковский  
Дата: 25.03.06 14:08
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А вот так будет выглядить полный тест:

VD>
VD>using System;
VD>using System.Console;

VD>[Record]
VD>class Customer
VD>{
VD>  public Name      : string;
VD>  public IsMale    : bool;
VD>  public BirthDate : DateTime;
  
VD>  public override ToString() : string
VD>  {
VD>    $"Name: '$Name' Is male: $IsMale  Birth date: $BirthDate";
VD>  }
VD>}

VD>def customers = [Customer("Ivan", true, DateTime(1910, 1, 1)),
VD>                 Customer("Vlad", true, DateTime(1974, 4, 25)),
VD>                 Customer("Vika", false, DateTime(1911, 2, 1)),
VD>                 Customer("Thor the Mighty", true, DateTime(1900, 2, 1))];

VD>def result = customers.Filter(fun(cust)
VD>{
VD>  cust.Name == "Thor the Mighty" && cust.IsMale && cust.BirthDate.Year < 1910
VD>});

VD>WriteLine(result);
VD>

VD>Он выведет:
VD>
VD>[Name: 'Thor the Mighty' Is male: True  Birth date: 01.02.1900 00:00:00]
VD>


VD>Забавно будет сравнить с полный тест на разных языках. В том что С++ и C# сольют по краткости и понятности я даже не сомневаюсь. А вот с Руби посоревнаваться действительно забавно. Все же динамически типизированный скрипт обязан выглядеть лучше статически типизрованного компилируемого языка. И если это не так, или разница несущественна, то в пору задуматься, над необходимостью этих скриптов.


Пожалуйста:

class Customer 
    attr_accessor :name, :isMale, :birth

    def initialize(name, male, birth)
        @name, @isMale, @birth = name, male, birth
    end

    def to_s
        "Name: #{@name} Is male: #{@isMale}  Birth date: #{@birth}"
    end
end

customers = [    Customer.new("Ivan", true, Date.new(1910, 1, 1)),
                Customer.new("Vlad", true, Date.new(1974, 4, 25)),
                Customer.new("Vika", false, Date.new(1911, 2, 1)),
                Customer.new("Thor the Mighty", true, Date.new(1900, 2, 1))]

result = customers.select {|cust|
    cust.name == "Thor the Mighty" && cust.isMale && cust.birth.year < 1910
}

print result.to_s


результат:
Name: Thor the Mighty Is male: true  Birth date: 1900-02-01


Пожалуйста. Код одинаковый до смешного (хотя это мало о чем говорит; поскольку все, что кроме магического "select/Filter" выглядело бы практически так же на любом языке, хоть VB).

Но я ведь влез с рубей не для того, чтобы рассказать, какой я знаю крутой язык. Мне правда интересно, что в этой Карменсите за идея такая хитрая лежит. К сожалению, после диалога с Oyster'ом так и не понял Торможу сегодня.
FAQ — це мiй ай-кью!
Re[7]: ;)
От: Зверёк Харьковский  
Дата: 25.03.06 14:11
Оценка:
Здравствуйте, Oyster, Вы писали:

ЗХ>>Мняяя... Что-то я сегодня совсем торможу... А почему это понадобится его конструировать?


O>Чтобы делегат сработал. Конкретно в DataRow данные хранятся "без имени" — массив колонок и массив значений, грубо говоря.


Коллега, а ты можешь объяснить этот нюанс как для дурака? Т.е. "вот такой код, вот так бы работал без карменситы, карменсита позволяет избежать того-то". А то я чегой-то не проникся покуда
FAQ — це мiй ай-кью!
Re[4]: ;)
От: Cyberax Марс  
Дата: 25.03.06 14:22
Оценка:
Зверёк Харьковский wrote:
> Пожалуйста. Код одинаковый до смешного (хотя это мало о чем говорит;
> поскольку все, что кроме магического "select/Filter" выглядело бы
> практически так же на любом языке, хоть VB).
А как сделать чтобы он искал по имени и дате, используя индексы?

ЗЫ: в RTL это сделано
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.