There is no table accessible from sqlline.bat in ApacheIgnite - ignite

I have this code and I expected that when I run !table command in sqlline.bat I will see table called Person, but there is no table.
What I have to do to see the table there?
Am I expecting correctly, that there should be created table automatically for each cache?
Thank you
class Program
{
static void Main()
{
var cfg = new IgniteConfiguration
{
BinaryConfiguration = new BinaryConfiguration(typeof(Person),
typeof(PersonFilter))
};
IIgnite ignite = Ignition.Start(cfg);
ICache<int, Person> cache = ignite.GetOrCreateCache<int, Person>("persons");
cache[1] = new Person { Name = "John Doe", Age = 27 };
cache[2] = new Person { Name = "Jane Moe", Age = 43 };
var scanQuery = new ScanQuery<int, Person>(new PersonFilter());
IQueryCursor<ICacheEntry<int, Person>> queryCursor = cache.Query(scanQuery);
foreach (ICacheEntry<int, Person> cacheEntry in queryCursor)
Console.WriteLine(cacheEntry);
Console.ReadKey();
}
}
class Person
{
[QuerySqlField]
public string Name { get; set; }
[QuerySqlField]
public int Age { get; set; }
public override string ToString()
{
return $"Person [Name={Name}, Age={Age}]";
}
}
class PersonFilter : ICacheEntryFilter<int, Person>
{
public bool Invoke(ICacheEntry<int, Person> entry)
{
return entry.Value.Age > 30;
}
}

SQL table shouldn't be created automatically for the cache. To add SQL table, you should define the schema: https://apacheignite-sql.readme.io/docs/schema-and-indexes
It can be done using annotations, QueryEntiny configuration, or by creating the cache using DDL(CREATE TABLE command).

Related

Autocad.net Save complex Object

I'm working on a project in AutoCAD using c#, my application data is stored in complex objects
(String, double, objectId, arrays, list...) and I would like to save data for later using (serialize or saved in AutoCAD drawing) and if I re-open AutoCAD and reload my project, I can find all data in my object
Sorry for my English
So You need to use XData.
Details and sample You can find here:
https://www.keanw.com/2007/04/adding_xdata_to.html
You could serialize your class into a binary stream and then you can save it in the drawing as a bunch of binary chunks (see this topic)
But most of the time you should directly store data in Xrecords of a DBDictionary.
public abstract class RecordableObject
{
protected ObjectId dictionaryId;
protected Database database;
public string Key { get; }
protected RecordableObject(string key, Database db = null)
{
database = db ?? HostApplicationServices.WorkingDatabase;
Key = key;
using (var tr = database.TransactionManager.StartOpenCloseTransaction())
{
var NOD = (DBDictionary)tr.GetObject(database.NamedObjectsDictionaryId, OpenMode.ForRead);
DBDictionary dictionary;
if (NOD.Contains(Key))
{
dictionaryId = NOD.GetAt(Key);
}
else
{
NOD.UpgradeOpen();
dictionary = new DBDictionary();
dictionaryId = NOD.SetAt(Key, dictionary);
tr.AddNewlyCreatedDBObject(dictionary, true);
}
tr.Commit();
}
}
public abstract void SavePropertiesToDictionary();
public abstract void SetPropertiesFromDictionary();
protected void SaveData(string key, params TypedValue[] values)
{
using (var tr = database.TransactionManager.StartOpenCloseTransaction())
{
var dictionary = (DBDictionary)tr.GetObject(dictionaryId, OpenMode.ForRead);
Xrecord xrecord;
if (dictionary.Contains(key))
{
xrecord = (Xrecord)tr.GetObject(dictionary.GetAt(key), OpenMode.ForWrite);
}
else
{
xrecord = new Xrecord();
dictionary.UpgradeOpen();
dictionary.SetAt(key, xrecord);
tr.AddNewlyCreatedDBObject(xrecord, true);
}
xrecord.Data = new ResultBuffer(values);
tr.Commit();
}
}
protected T GetData<T>(string key)
{
using (var tr = database.TransactionManager.StartOpenCloseTransaction())
{
var dictionary = (DBDictionary)tr.GetObject(dictionaryId, OpenMode.ForRead);
if (dictionary.Contains(key))
{
var xrecord = (Xrecord)tr.GetObject(dictionary.GetAt(key), OpenMode.ForRead);
if (xrecord.Data != null)
return (T)xrecord.Data.AsArray()[0].Value;
}
return default;
}
}
protected T[] GetDataArray<T>(string key)
{
using(var tr = database.TransactionManager.StartOpenCloseTransaction())
{
var dictionary = (DBDictionary)tr.GetObject(dictionaryId, OpenMode.ForRead);
if (dictionary.Contains(key))
{
var xrecord = (Xrecord)tr.GetObject(dictionary.GetAt(key), OpenMode.ForRead);
if (xrecord.Data != null)
return xrecord.Data.AsArray().Select(tv => (T)tv.Value).ToArray();
}
return default;
}
}
}
Derived class example:
public class RecordableExample : RecordableObject
{
public double Size { get; set; }
public ObjectId ObjectId { get; set; }
public int[] Ints { get; set; }
public RecordableExample(string key, Database db = null) : base(key, db) { }
public override void SavePropertiesToDictionary()
{
SaveData(nameof(Size), new TypedValue((int)DxfCode.Real, Size));
SaveData(nameof(ObjectId), new TypedValue((int)DxfCode.Handle, ObjectId.Handle));
if (Ints != null)
SaveData(nameof(Ints), Ints.Select(i => new TypedValue((int)DxfCode.Int32, i)).ToArray());
}
public override void SetPropertiesFromDictionary()
{
Size = GetData<double>(nameof(Size));
Ints = GetDataArray<int>(nameof(Ints));
var handle = new Handle(Convert.ToInt64(GetData<string>(nameof(ObjectId))));
if (database.TryGetObjectId(handle, out var id))
ObjectId = id;
}
}

Changing IdentityUser's Id column's type to int

I am using .net core identity. When I create a new user in db, I can see that its ID column is GUID and it is string. I want to make it int so that User IDs can be 1,2,3 ...
How can I do that?
Usually we don't do that, It seems like it will be more complicated than simply adding a new id property with type int in your derived user class. But there still one way you can do it. Here's what plugging in guids instead of strings should look for example:
public class GuidRole : IdentityRole<Guid, GuidUserRole> {
public GuidRole() {
Id = Guid.NewGuid();
}
public GuidRole(string name) : this() { Name = name; }
}
public class GuidUserRole : IdentityUserRole<Guid> { }
public class GuidUserClaim : IdentityUserClaim<Guid> { }
public class GuidUserLogin : IdentityUserLogin<Guid> { }
public class GuidUser : IdentityUser<Guid, GuidUserLogin, GuidUserRole, GuidUserClaim> {
public GuidUser() {
Id = Guid.NewGuid();
}
public GuidUser(string name) : this() { UserName = name; }
}
private class GuidUserContext : IdentityDbContext<GuidUser, GuidRole, Guid, GuidUserLogin, GuidUserRole, GuidUserClaim> { }
private class GuidUserStore : UserStore<GuidUser, GuidRole, Guid, GuidUserLogin, GuidUserRole, GuidUserClaim> {
public GuidUserStore(DbContext context)
: base(context) {
}
}
private class GuidRoleStore : RoleStore<GuidRole, Guid, GuidUserRole> {
public GuidRoleStore(DbContext context)
: base(context) {
}
}
[TestMethod]
public async Task CustomUserGuidKeyTest() {
var manager = new UserManager<GuidUser, Guid>(new GuidUserStore(new GuidUserContext()));
GuidUser[] users = {
new GuidUser() { UserName = "test" },
new GuidUser() { UserName = "test1" },
new GuidUser() { UserName = "test2" },
new GuidUser() { UserName = "test3" }
};
foreach (var user in users) {
UnitTestHelper.IsSuccess(await manager.CreateAsync(user));
}
foreach (var user in users) {
var u = await manager.FindByIdAsync(user.Id);
Assert.IsNotNull(u);
Assert.AreEqual(u.UserName, user.UserName);
}
}

RavenDB static index on dictionary

I have an application that uses documents, that contain list of attributes in a dictionary, for some reason we need to use a static index and query/filter over these attributes.
A prototype looks like this:
class Program
{
static void Main(string[] args)
{
IDocumentStore store = new DocumentStore() { DefaultDatabase = "Test", Url = "http://localhost:8081" };
store.Initialize();
IndexCreation.CreateIndexes(typeof(Program).Assembly, store);
using (var session = store.OpenSession())
{
session.Store(new Document { Id = "1", Name = "doc_name", Attributes = new Dictionary<string, object> { { "Type", "1" }, { "Status", "Active" } } });
session.SaveChanges();
}
using (var session = store.OpenSession())
{
// works
var l1 = session.Query<Document, Documents_Index>().Where(a => a.Attributes["Type"] == "1").ToList();
// not working
var l2 = session.Query<Document, Documents_Index>().Where(a => a.Attributes["Status"] == "Active").ToList();
}
}
}
public class Documents_Index : AbstractIndexCreationTask<Document>
{
public Documents_Index()
{
Map = docs => docs.Select(a =>
new
{
a.Name,
a.Attributes,
Attributes_Type = a.Attributes["Type"]
});
}
}
[Serializable]
public class Document
{
public string Id { get; set; }
public string Name { get; set; }
public Dictionary<string, object> Attributes { get; set; }
}
But since I need to query using any arbitrary Attribute name/value this index does solve our problem. Actually the list of attributes is known at run-time (so we tried modifying the Map expression to inject any number of attribute names, but so far we weren't successful). Is there a way how to define the index in some dynamic fashion?
You need to write it like:
public class Documents_Index : AbstractIndexCreationTask<Document>
{
public Documents_Index()
{
Map = docs => docs.Select(a =>
new
{
a.Name,
_ = a.Attributes.Select(x=>CreateField("Attributes_"+x.Key, x.Value),
});
}
}

Querying a Dictionary with RavenDb

I have a class defined as:
public class Student
{
public string Id { get; set; }
public IDictionary<string, string> Attributes { get; set; }
}
based on the discussion I found here : http://groups.google.com/group/ravendb/browse_thread/thread/88ea52620021ed6c?pli=1
I can store an instance quite easily as :
//creation
using (var session = store.OpenSession())
{
//now the student:
var student = new Student();
student.Attributes = new Dictionary<string, string>();
student.Attributes["NIC"] = "studentsNICnumberGoesHere";
session.Store(student);
session.SaveChanges();
}
However when I query it as below:
//Testing query on attribute
using (var session = store.OpenSession())
{
var result = from student in session.Query<Student>()
where
student.Attributes["NIC"] == "studentsNICnumberGoesHere"
select student;
var test = result.ToList();
}
I get the error "'System.Linq.Expressions.InstanceMethodCallExpressionN' to type 'System.Linq.Expressions.MemberExpression'." as shown:
How can I query based on a key in the dictionary?
This is a bug, it is fixed now.
Will be out in the next build, in about two hours

How do I test "Parameters Passed In Final Call" using RhinoMocks?

What's the best way in Rhino Mocks to test that a particular parameter is passed on the FINAL call to a method? Eg mockview.SetSomething(myObj) might be called any number of times by mockview.Init, but I want to test that the last time it's called as mockview.SetSomething(inParticular).
Now I know I can use GetArgumentsForCallsMadeOn with this, but my problem is that it doesn't work if I've subsequently changed the parameter holding variable. e.g
public interface IView
{
void SetSomething(ViewData data);
}
public class ViewData
{
public int Age { get; set; }
public string Name { get; set; }
public ViewData Person(int age, string name)
{
Age = age;
Name = name;
return (this);
}
}
public class WorkingPresenter
{
public void Init(IView view)
{
var data = new ViewData {Age = 1, Name = "One"};
view.SetSomething(data);
data = new ViewData {Age = 2, Name = "Two"};
view.SetSomething(data);
data = new ViewData {Age = 3, Name = "Three"};
}
}
public class NotWorkingPresenter
{
private ViewData _data;
public void Init(IView view)
{
_data = new ViewData();
view.SetSomething(_data.Person(1, "One"));
view.SetSomething(_data.Person(2, "Two"));
_data.Person(3, "Three");
}
}
then my tests are ...
[Test]
public void GetDataOfLastCall()
{
ViewData dummydata=null;
var view = MockRepository.GenerateStub<IView>();
//Approach 1 : This works
var workingPresenter = new WorkingPresenter();
workingPresenter.Init(view);
var lastCall = view.GetArgumentsForCallsMadeOn(v => v.SetSomething(dummydata)).Count - 1;
var lastParams = view.GetArgumentsForCallsMadeOn(v => v.SetSomething(dummydata))[lastCall];
var lastData = (ViewData)lastParams[0];
//Approach 2: This doesn't
var notWorkingPresenter = new NotWorkingPresenter();
notWorkingPresenter.Init(view);
lastCall = view.GetArgumentsForCallsMadeOn(v => v.SetSomething(dummydata)).Count - 1;
lastParams = view.GetArgumentsForCallsMadeOn(v => v.SetSomething(dummydata))[lastCall];
lastData = (ViewData)lastParams[0];
What I want is to verify that the last call to SetSomething was with {name="Two", age=2}. Now workingPresenter does this but wouldn't you expect notWorkingPresenter to do so too?
There must be something else going on in your code (outside of the mocking). I just threw together a few items:
public interface IView
{
void SetSomething(ViewData data);
}
public class ViewData
{
public int Age { get; set; }
public string Name { get; set; }
}
And I tested it with:
[TestMethod]
public void GetDataOfLastCall()
{
var view = MockRepository.GenerateStub<IView>();
var data = new ViewData {Age = 1, Name = "One"};
view.SetSomething(data);
data = new ViewData { Age = 2, Name = "Two" };
view.SetSomething(data);
data = new ViewData { Age = 3, Name = "Three" };
var lastCall = view.GetArgumentsForCallsMadeOn(v => v.SetSomething(data)).Count - 1;
var lastParams = view.GetArgumentsForCallsMadeOn(v => v.SetSomething(data))[lastCall];
var lastData = (ViewData) lastParams[0];
}
And I got the values of 2 and "Two" inside the ViewData. It appears Rhino.Mocks supports what you want to do. Could you create a failing test case that shows the issue identified in your original question (where you got a reference to the most recent information)?