Skip to content

Commit

Permalink
Merge pull request #16 from zhouyuguangsc/v3.0.0
Browse files Browse the repository at this point in the history
update version to 3.0.0
  • Loading branch information
shyboylpf authored Mar 14, 2022
2 parents bdb89da + 4580013 commit f4cf860
Show file tree
Hide file tree
Showing 304 changed files with 2,397 additions and 121,858 deletions.
39 changes: 29 additions & 10 deletions GraphClientExample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using NebulaNet;
using System;
using System.Net;
using System.Text;
using System.Threading.Tasks;

Expand All @@ -9,32 +10,50 @@ internal class Program
{
private static async Task Main(string[] args)
{
GraphClient graphClient = new GraphClient("127.0.0.1", 9669);
graphClient.Authenticate("root", "nebula");
Console.WriteLine(graphClient.sessionId);
NebulaConnection graphClient = new NebulaConnection();
await graphClient.OpenAsync("127.0.0.1", 9669);
var authResponse = await graphClient.AuthenticateAsync("root", "123456");
Console.WriteLine(authResponse.Session_id);

StringBuilder sb = new StringBuilder();
sb.Append("CREATE SPACE IF NOT EXISTS test(vid_type=FIXED_STRING(30));");
sb.Append("USE test;");
sb.Append("CREATE TAG IF NOT EXISTS person(name string, age int);");
sb.Append("CREATE EDGE like (likeness double);");

var executionResponse = await graphClient.Execute(sb.ToString());
var executionResponse = await graphClient.ExecuteAsync(authResponse.Session_id, sb.ToString());

await Task.Delay(10000);

executionResponse = await graphClient.Execute("INSERT VERTEX person(name, age) VALUES \"Bob\":(\"Bob\", 10), \"Lily\":(\"Lily\", 9);");
executionResponse = await graphClient.ExecuteAsync(authResponse.Session_id, "INSERT VERTEX person(name, age) VALUES \"Bob\":(\"Bob\", 10), \"Lily\":(\"Lily\", 9);");
await Task.Delay(5000);
executionResponse = await graphClient.Execute("INSERT EDGE like(likeness) VALUES \"Bob\"->\"Lily\":(80.0);");
executionResponse = await graphClient.ExecuteAsync(authResponse.Session_id, "INSERT EDGE like(likeness) VALUES \"Bob\"->\"Lily\":(80.0);");
await Task.Delay(5000);
executionResponse = await graphClient.Execute("FETCH PROP ON person \"Bob\" YIELD vertex as node;");
executionResponse = await graphClient.ExecuteAsync(authResponse.Session_id, "FETCH PROP ON person \"Bob\" YIELD vertex as node;");
await Task.Delay(5000);
executionResponse = await graphClient.Execute("FETCH PROP ON like \"Bob\"->\"Lily\" YIELD edge as e;");
executionResponse = await graphClient.ExecuteAsync(authResponse.Session_id, "FETCH PROP ON like \"Bob\"->\"Lily\" YIELD edge as e;");
await Task.Delay(5000);
executionResponse = await graphClient.Execute("DROP SPACE test;");

//
var testDtos = await graphClient.ExecuteAsync(authResponse.Session_id, "FETCH PROP ON person \"Bob\",\"Lily\" YIELD properties(vertex).name AS name,properties(vertex).age AS age;")
.ToListAsync<TestDto>();
foreach (var item in testDtos)
{
Console.WriteLine($"1.name:{item.Name},age:{item.Age}");
}

executionResponse = await graphClient.ExecuteAsync(authResponse.Session_id, "DROP SPACE test;");
await Task.Delay(5000);

await graphClient.SignOff();
await graphClient.SignOutAsync(authResponse.Session_id);


Console.ReadKey();
}
}
public class TestDto
{
public string Name { get; set; }
public long Age { get; set; }
}
}
53 changes: 53 additions & 0 deletions NebulaNet/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using Nebula.Graph;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace NebulaNet
{
public static class EnumerableExtensions
{
public static async Task<T[]> ToArrayAsync<T>(this Task<ExecutionResponse> executionTask)
{
var executionResponse = await executionTask;
if (executionResponse.Data == null)
return default;
if (executionResponse.Data.Rows.Count != 1)
return default;//不能解析多行

return (T[])executionResponse.Data.Rows[0].Values[0].Mapping(typeof(T[]));
}
public static async Task<IList<T>> ToListAsync<T>(this Task<ExecutionResponse> executionTask)
{
var executionResponse = await executionTask;
if (executionResponse.Data == null)
return default;

//获取列名
var columnNames = executionResponse.Data.Column_names
.Select(x => Encoding.UTF8.GetString(x).ToLower()).ToArray();

//查找可用属性和数据索引
var indexAndProps = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)//BindingFlags.IgnoreCase
.Select(x => new { Index = Array.IndexOf(columnNames, x.Name.ToLower()), Prop = x })
.Where(x => x.Index >= 0);

//映射对象
var result = new List<T>();
foreach (var row in executionResponse.Data.Rows)
{
var o = Activator.CreateInstance<T>();
foreach (var item in indexAndProps)
{
item.Prop.SetValue(o, row.Values[item.Index].Mapping(item.Prop.PropertyType));
}
result.Add(o);
}

return result;
}
}
}
37 changes: 37 additions & 0 deletions NebulaNet/Extensions/NebulaServiceExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Microsoft.Extensions.ObjectPool;
using NebulaNet;
using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.Extensions.DependencyInjection
{
public static class NebulaServiceExtension
{
public static IServiceCollection AddNebulaGraph(this IServiceCollection services,Action<NebulaConfig> configProvider)
{
var config = new NebulaConfig(configProvider);

services.AddSingleton<ObjectPool<NebulaConnection>>(serviceProvider =>
{
var objectPoolProvider = new DefaultObjectPoolProvider();
objectPoolProvider.MaximumRetained = 30;
return objectPoolProvider.Create(new NebulaConnPoolPolicy(config));
});
services.AddSingleton<ObjectPool<SessionId>>(serviceProvider =>
{
var objectPoolProvider=new DefaultObjectPoolProvider();
objectPoolProvider.MaximumRetained = 30;
return objectPoolProvider.Create(new NebulaSessionIdPoolPolicy());
});
services.AddSingleton(serviceProvider =>
{
var connPool = serviceProvider.GetRequiredService<ObjectPool<NebulaConnection>>();
var sessionIdPool = serviceProvider.GetRequiredService<ObjectPool<SessionId>>();
return new NebulaPool(connPool, sessionIdPool, config);
});

return services;
}
}
}
147 changes: 147 additions & 0 deletions NebulaNet/Extensions/ValueMappingExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
using Nebula.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;

namespace NebulaNet
{
internal static class ValueMappingExtensions
{
internal static object Mapping(this @Value value, Type targetType)
{
Type mapType = null;
switch (targetType.Name)
{
case "Bool":
return value.BVal;
case "Int64":
return value.IVal;
case "Double":
return value.FVal;
case "String":
return Encoding.UTF8.GetString(value.SVal);
case "Nebula.Common.Date":
return value.DVal;
case "Nebula.Common.Time":
return value.TVal;
case "DateTime":
return value.DtVal;
case "Vertex":
return new NotImplementedException(); //value.VVal;
case "Edge":
return new NotImplementedException(); // value.EVal;
case "Path":
return new NotImplementedException(); // value.PVal;
case "Dictionary":
return new NotImplementedException(); //value.MVal;
case "HashSet":
return new NotImplementedException(); //value.UVal;
case "DataSet":
return new NotImplementedException(); //value.GVal;
case "Geography":
return new NotImplementedException(); //value.GgVal;
case "Duration":
return new NotImplementedException(); //value.DuVal;
case "List`1"://List<T>
mapType = targetType.GetGenericArguments()[0];
if (mapType.Name== "Int64")
{
return value.LVal.Values.Select(x => x.Mapping(mapType)).Cast<long>().ToList();
}
if (mapType.Name == "String")
{
return value.LVal.Values.Select(x => x.Mapping(mapType)).Cast<string>().ToList();
}
return new TypeLoadException();
default:
if (targetType.IsArray)//数组
{
mapType = targetType.GetElementType();
if (mapType.Name == "Int64")
{
return value.LVal.Values.Select(x => x.Mapping(mapType)).Cast<long>().ToArray();
}
if (mapType.Name == "String")
{
return value.LVal.Values.Select(x => x.Mapping(mapType)).Cast<string>().ToArray();
}
return new TypeLoadException();
}
return new TypeLoadException();
}
}

/// <summary>
/// 将一个对象转换为指定类型
/// </summary>
/// <param name="obj">待转换的对象</param>
/// <param name="type">目标类型</param>
/// <returns>转换后的对象</returns>
private static object ConvertToObject(object obj, Type type)
{
if (type == null) return obj;
if (obj == null) return type.IsValueType ? Activator.CreateInstance(type) : null;

Type underlyingType = Nullable.GetUnderlyingType(type);
// 如果待转换对象的类型与目标类型兼容,则无需转换
if (type.IsInstanceOfType(obj))
{
return obj;
}
// 如果待转换的对象的基类型为枚举
else if ((underlyingType ?? type).IsEnum)
{
// 如果目标类型为可空枚举,并且待转换对象为null 则直接返回null值
if (underlyingType != null && string.IsNullOrEmpty(obj.ToString()))
{
return null;
}
else
{
return Enum.Parse(underlyingType ?? type, obj.ToString());
}
}
// 如果目标类型的基类型实现了IConvertible,则直接转换
else if (typeof(IConvertible).IsAssignableFrom(underlyingType ?? type))
{
try
{
return Convert.ChangeType(obj, underlyingType ?? type, null);
}
catch
{
return underlyingType == null ? Activator.CreateInstance(type) : null;
}
}
else
{
TypeConverter converter = TypeDescriptor.GetConverter(type);
if (converter.CanConvertFrom(obj.GetType()))
{
return converter.ConvertFrom(obj);
}
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
if (constructor != null)
{
object o = constructor.Invoke(null);
PropertyInfo[] propertys = type.GetProperties();
Type oldType = obj.GetType();
foreach (PropertyInfo property in propertys)
{
PropertyInfo p = oldType.GetProperty(property.Name);
if (property.CanWrite && p != null && p.CanRead)
{
property.SetValue(o, ConvertToObject(p.GetValue(obj, null), property.PropertyType), null);
}
}
return o;
}
}
return obj;
}

}
}
Loading

0 comments on commit f4cf860

Please sign in to comment.