├── .gitignore
├── NuGet
└── NuGet.exe
├── README.md
├── Tarantool.Net.Examples
├── App.config
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── Tarantool.Net.Examples.csproj
└── packages.config
├── Tarantool.Net.Tests
├── App.config
├── Properties
│ └── AssemblyInfo.cs
├── Tarantool.Net.Tests.csproj
├── TarantoolClientTest.cs
└── packages.config
├── Tarantool.Net.sln
└── Tarantool.Net
├── AuthToken.cs
├── Connection.cs
├── IProto
├── Builders
│ ├── AuthRequestBuilder.cs
│ ├── CallRequestBuilder.cs
│ ├── DeleteRequestBuilder.cs
│ ├── EvalRequestBuilder.cs
│ ├── InsertRequestBuilder.cs
│ ├── OperationsTupleBuilder.cs
│ ├── PingRequestBuilder.cs
│ ├── ReplaceRequestBuilder.cs
│ ├── SelectRequestBuilder.cs
│ ├── TupleBuilder.cs
│ ├── UpdateOperationsTupleBuilder.cs
│ ├── UpdateRequestBuilder.cs
│ └── UpsertRequestBuilder.cs
├── Command.cs
├── GreatingResponse.cs
├── Iterator.cs
├── Key.cs
├── OperationsTuple.cs
├── PacketHeader.cs
├── PacketType.cs
├── Request.cs
├── RequestBody.cs
├── Requests
│ ├── AuthRequest.cs
│ ├── CallRequest.cs
│ ├── DeleteRequest.cs
│ ├── EvalRequest.cs
│ ├── InsertReplaceRequest.cs
│ ├── PingRequest.cs
│ ├── RequestBase.cs
│ ├── SelectRequest.cs
│ ├── UpdateRequest.cs
│ └── UpsertRequest.cs
├── Response.cs
├── Tuple.cs
├── UpdateOperation.cs
└── UpdateOperationCode.cs
├── Properties
└── AssemblyInfo.cs
├── Tarantool.Net.csproj
├── Tarantool.Net.nuspec
├── Tarantool.cs
├── TarantoolConnectionSupervisor.cs
├── app.config
└── packages.config
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | build/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 |
28 | # MSTest test Results
29 | [Tt]est[Rr]esult*/
30 | [Bb]uild[Ll]og.*
31 |
32 | # NUNIT
33 | *.VisualState.xml
34 | TestResult.xml
35 |
36 | # Build Results of an ATL Project
37 | [Dd]ebugPS/
38 | [Rr]eleasePS/
39 | dlldata.c
40 |
41 | # DNX
42 | project.lock.json
43 | artifacts/
44 |
45 | *_i.c
46 | *_p.c
47 | *_i.h
48 | *.ilk
49 | *.meta
50 | *.obj
51 | *.pch
52 | *.pdb
53 | *.pgc
54 | *.pgd
55 | *.rsp
56 | *.sbr
57 | *.tlb
58 | *.tli
59 | *.tlh
60 | *.tmp
61 | *.tmp_proj
62 | *.log
63 | *.vspscc
64 | *.vssscc
65 | .builds
66 | *.pidb
67 | *.svclog
68 | *.scc
69 |
70 | # Chutzpah Test files
71 | _Chutzpah*
72 |
73 | # Visual C++ cache files
74 | ipch/
75 | *.aps
76 | *.ncb
77 | *.opensdf
78 | *.sdf
79 | *.cachefile
80 |
81 | # Visual Studio profiler
82 | *.psess
83 | *.vsp
84 | *.vspx
85 |
86 | # TFS 2012 Local Workspace
87 | $tf/
88 |
89 | # Guidance Automation Toolkit
90 | *.gpState
91 |
92 | # ReSharper is a .NET coding add-in
93 | _ReSharper*/
94 | *.[Rr]e[Ss]harper
95 | *.DotSettings.user
96 |
97 | # JustCode is a .NET coding add-in
98 | .JustCode
99 |
100 | # TeamCity is a build add-in
101 | _TeamCity*
102 |
103 | # DotCover is a Code Coverage Tool
104 | *.dotCover
105 |
106 | # NCrunch
107 | _NCrunch_*
108 | .*crunch*.local.xml
109 |
110 | # MightyMoose
111 | *.mm.*
112 | AutoTest.Net/
113 |
114 | # Web workbench (sass)
115 | .sass-cache/
116 |
117 | # Installshield output folder
118 | [Ee]xpress/
119 |
120 | # DocProject is a documentation generator add-in
121 | DocProject/buildhelp/
122 | DocProject/Help/*.HxT
123 | DocProject/Help/*.HxC
124 | DocProject/Help/*.hhc
125 | DocProject/Help/*.hhk
126 | DocProject/Help/*.hhp
127 | DocProject/Help/Html2
128 | DocProject/Help/html
129 |
130 | # Click-Once directory
131 | publish/
132 |
133 | # Publish Web Output
134 | *.[Pp]ublish.xml
135 | *.azurePubxml
136 | ## TODO: Comment the next line if you want to checkin your
137 | ## web deploy settings but do note that will include unencrypted
138 | ## passwords
139 | #*.pubxml
140 |
141 | *.publishproj
142 |
143 | # NuGet Packages
144 | *.nupkg
145 | # The packages folder can be ignored because of Package Restore
146 | **/packages/*
147 | # except build/, which is used as an MSBuild target.
148 | !**/packages/build/
149 | # Uncomment if necessary however generally it will be regenerated when needed
150 | #!**/packages/repositories.config
151 |
152 | # Windows Azure Build Output
153 | csx/
154 | *.build.csdef
155 |
156 | # Windows Store app package directory
157 | AppPackages/
158 |
159 | # Visual Studio cache files
160 | # files ending in .cache can be ignored
161 | *.[Cc]ache
162 | # but keep track of directories ending in .cache
163 | !*.[Cc]ache/
164 |
165 | # Others
166 | ClientBin/
167 | [Ss]tyle[Cc]op.*
168 | ~$*
169 | *~
170 | *.dbmdl
171 | *.dbproj.schemaview
172 | *.pfx
173 | *.publishsettings
174 | node_modules/
175 | orleans.codegen.cs
176 |
177 | # RIA/Silverlight projects
178 | Generated_Code/
179 |
180 | # Backup & report files from converting an old project file
181 | # to a newer Visual Studio version. Backup files are not needed,
182 | # because we have git ;-)
183 | _UpgradeReport_Files/
184 | Backup*/
185 | UpgradeLog*.XML
186 | UpgradeLog*.htm
187 |
188 | # SQL Server files
189 | *.mdf
190 | *.ldf
191 |
192 | # Business Intelligence projects
193 | *.rdl.data
194 | *.bim.layout
195 | *.bim_*.settings
196 |
197 | # Microsoft Fakes
198 | FakesAssemblies/
199 |
200 | # Node.js Tools for Visual Studio
201 | .ntvs_analysis.dat
202 |
203 | # Visual Studio 6 build log
204 | *.plg
205 |
206 | # Visual Studio 6 workspace options file
207 | *.opt
208 |
209 | # LightSwitch generated files
210 | GeneratedArtifacts/
211 | _Pvt_Extensions/
212 | ModelManifest.xml
213 |
--------------------------------------------------------------------------------
/NuGet/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/donmikel/tarantool-net/894e9adf31dab3586624f3bb26d93b1fc67ce71f/NuGet/NuGet.exe
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tarantool-net [](https://badge.fury.io/nu/Tarantool.NET) [](https://ci.appveyor.com/project/donmikel/tarantool-net)
2 | A .Net client for Tarantool http://tarantool.org written with the Akka.Net I/O package
3 |
4 | This is beta version. It is necessary to increase the test coverage.
5 |
6 |
7 | Some Docs wiil be soon.
8 |
--------------------------------------------------------------------------------
/Tarantool.Net.Examples/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Tarantool.Net.Examples/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Akka;
3 | using Akka.Actor;
4 | using Tarantool.Net.IProto;
5 |
6 | namespace Tarantool.Net.Examples
7 | {
8 | static class Program
9 | {
10 | static ActorSystem _actorSystem;
11 |
12 | [STAThread]
13 | static void Main()
14 | {
15 | _actorSystem = ActorSystem.Create("tarantool");
16 | var connection = _actorSystem.ActorOf(Tarantool.Create());
17 |
18 | connection.Ask(Request
19 | .Select()
20 | .WithSpaceId(512)
21 | .WithIndexId(0)
22 | .WithIterator(Iterator.ALL)
23 | .Build())
24 | .Result
25 | .Match()
26 | .With(f =>
27 | {
28 | Console.WriteLine($"Error: {f.Exception}");
29 | })
30 | .With(r =>
31 | {
32 | foreach (var tuple in r.Body)
33 | {
34 | Console.WriteLine(tuple);
35 | }
36 |
37 | });
38 |
39 | Console.ReadLine();
40 | }
41 |
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Tarantool.Net.Examples/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // Управление общими сведениями о сборке осуществляется с помощью
6 | // набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
7 | // связанные со сборкой.
8 | [assembly: AssemblyTitle("Tarantool.Net.Examples")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Tarantool.Net.Examples")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Параметр ComVisible со значением FALSE делает типы в сборке невидимыми
18 | // для COM-компонентов. Если требуется обратиться к типу в этой сборке через
19 | // COM, задайте атрибуту ComVisible значение TRUE для этого типа.
20 | [assembly: ComVisible(false)]
21 |
22 | // Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
23 | [assembly: Guid("cc7a5732-d9cf-4038-a34b-2e48491df032")]
24 |
25 | // Сведения о версии сборки состоят из следующих четырех значений:
26 | //
27 | // Основной номер версии
28 | // Дополнительный номер версии
29 | // Номер сборки
30 | // Редакция
31 | //
32 | // Можно задать все значения или принять номера сборки и редакции по умолчанию
33 | // используя "*", как показано ниже:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Tarantool.Net.Examples/Tarantool.Net.Examples.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {CC7A5732-D9CF-4038-A34B-2E48491DF032}
8 | Exe
9 | Properties
10 | Tarantool.Net.Examples
11 | Tarantool.Net.Examples
12 | v4.5.2
13 | 512
14 | true
15 |
16 |
17 | x64
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 | ..\packages\Akka.1.0.7\lib\net45\Akka.dll
38 | True
39 |
40 |
41 | ..\packages\MsgPack.Cli.0.6.8\lib\net45\MsgPack.dll
42 | True
43 |
44 |
45 | ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll
46 | True
47 |
48 |
49 |
50 | ..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll
51 | True
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | Designer
71 |
72 |
73 |
74 |
75 | {8EE464C8-B151-42C3-96BF-8D655FF8B6B9}
76 | Tarantool.Net
77 |
78 |
79 |
80 |
87 |
--------------------------------------------------------------------------------
/Tarantool.Net.Examples/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Tarantool.Net.Tests/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Tarantool.Net.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // Управление общими сведениями о сборке осуществляется с помощью
6 | // набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
7 | // связанные со сборкой.
8 | [assembly: AssemblyTitle("Tarantool.Net.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Tarantool.Net.Tests")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Параметр ComVisible со значением FALSE делает типы в сборке невидимыми
18 | // для COM-компонентов. Если требуется обратиться к типу в этой сборке через
19 | // COM, задайте атрибуту ComVisible значение TRUE для этого типа.
20 | [assembly: ComVisible(false)]
21 |
22 | // Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
23 | [assembly: Guid("8462a3a5-8c7d-4cd6-afc8-f487c23da28e")]
24 |
25 | // Сведения о версии сборки состоят из следующих четырех значений:
26 | //
27 | // Основной номер версии
28 | // Дополнительный номер версии
29 | // Номер сборки
30 | // Редакция
31 | //
32 | // Можно задать все значения или принять номера сборки и редакции по умолчанию
33 | // используя "*", как показано ниже:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Tarantool.Net.Tests/Tarantool.Net.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {8462A3A5-8C7D-4CD6-AFC8-F487C23DA28E}
8 | Library
9 | Properties
10 | Tarantool.Net.Tests
11 | Tarantool.Net.Tests
12 | v4.5.2
13 | 512
14 |
15 |
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 | ..\packages\Akka.1.0.7\lib\net45\Akka.dll
37 | True
38 |
39 |
40 | ..\packages\Akka.TestKit.1.0.7\lib\net45\Akka.TestKit.dll
41 | True
42 |
43 |
44 | ..\packages\Akka.TestKit.Xunit2.1.0.7\lib\net45\Akka.TestKit.Xunit2.dll
45 | True
46 |
47 |
48 | ..\packages\MsgPack.Cli.0.6.8\lib\net45\MsgPack.dll
49 | True
50 |
51 |
52 | ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll
53 | True
54 |
55 |
56 |
57 | ..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll
58 | True
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll
69 | True
70 |
71 |
72 | ..\packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll
73 | True
74 |
75 |
76 | ..\packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll
77 | True
78 |
79 |
80 | ..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll
81 | True
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | {8ee464c8-b151-42c3-96bf-8d655ff8b6b9}
95 | Tarantool.Net
96 |
97 |
98 |
99 |
100 |
101 |
102 |
109 |
--------------------------------------------------------------------------------
/Tarantool.Net.Tests/TarantoolClientTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 | using Akka.Actor;
5 | using Akka.TestKit.Xunit2;
6 | using Tarantool.Net.IProto;
7 | using Xunit;
8 | using Xunit.Abstractions;
9 |
10 | namespace Tarantool.Net.Tests
11 | {
12 | public class TarantoolClientTest : TestKit
13 | {
14 | private readonly IActorRef _tarantool;
15 | public TarantoolClientTest()
16 | {
17 | _tarantool = ActorOfAsTestActorRef(Tarantool.Create(port: 3301, listeners: new HashSet { TestActor }));
18 |
19 | ExpectMsg();
20 | ExpectMsg();
21 | }
22 |
23 | [Fact(DisplayName = "Should respond to ping")]
24 | public void Ping()
25 | {
26 | _tarantool.Tell(Request.Ping().Build());
27 | ExpectMsg(r => !r.IsError);
28 | }
29 |
30 | [Fact]
31 | public void Select()
32 | {
33 | _tarantool.Tell(Request
34 | .Select()
35 | .WithSpaceId(513)
36 | .WithIndexId(0)
37 | .WithIterator(Iterator.ALL)
38 | .Build()
39 | );
40 |
41 | ExpectMsg(r => !r.IsError);
42 | }
43 |
44 | [Fact]
45 | public void Pipeline()
46 | {
47 | _tarantool.Tell(Request.Ping().Build());
48 | _tarantool.Tell(Request.Ping().Build());
49 | _tarantool.Tell(Request.Ping().Build());
50 |
51 | ExpectMsg();
52 | ExpectMsg();
53 | ExpectMsg();
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/Tarantool.Net.Tests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Tarantool.Net.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.24720.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tarantool.Net", "Tarantool.Net\Tarantool.Net.csproj", "{8EE464C8-B151-42C3-96BF-8D655FF8B6B9}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tarantool.Net.Tests", "Tarantool.Net.Tests\Tarantool.Net.Tests.csproj", "{8462A3A5-8C7D-4CD6-AFC8-F487C23DA28E}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tarantool.Net.Examples", "Tarantool.Net.Examples\Tarantool.Net.Examples.csproj", "{CC7A5732-D9CF-4038-A34B-2E48491DF032}"
11 | EndProject
12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{35166E13-3CA4-4013-BB47-623FE1894423}"
13 | ProjectSection(SolutionItems) = preProject
14 | README.md = README.md
15 | EndProjectSection
16 | EndProject
17 | Global
18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 | Debug|Any CPU = Debug|Any CPU
20 | Release|Any CPU = Release|Any CPU
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {8EE464C8-B151-42C3-96BF-8D655FF8B6B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {8EE464C8-B151-42C3-96BF-8D655FF8B6B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {8EE464C8-B151-42C3-96BF-8D655FF8B6B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {8EE464C8-B151-42C3-96BF-8D655FF8B6B9}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {8462A3A5-8C7D-4CD6-AFC8-F487C23DA28E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {8462A3A5-8C7D-4CD6-AFC8-F487C23DA28E}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {8462A3A5-8C7D-4CD6-AFC8-F487C23DA28E}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {8462A3A5-8C7D-4CD6-AFC8-F487C23DA28E}.Release|Any CPU.Build.0 = Release|Any CPU
31 | {CC7A5732-D9CF-4038-A34B-2E48491DF032}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32 | {CC7A5732-D9CF-4038-A34B-2E48491DF032}.Debug|Any CPU.Build.0 = Debug|Any CPU
33 | {CC7A5732-D9CF-4038-A34B-2E48491DF032}.Release|Any CPU.ActiveCfg = Release|Any CPU
34 | {CC7A5732-D9CF-4038-A34B-2E48491DF032}.Release|Any CPU.Build.0 = Release|Any CPU
35 | EndGlobalSection
36 | GlobalSection(SolutionProperties) = preSolution
37 | HideSolutionNode = FALSE
38 | EndGlobalSection
39 | GlobalSection(ExtensibilityGlobals) = postSolution
40 | EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.0\lib\NET35
41 | EndGlobalSection
42 | EndGlobal
43 |
--------------------------------------------------------------------------------
/Tarantool.Net/AuthToken.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Tarantool.Net
4 | {
5 | public class AuthToken
6 | {
7 | public AuthToken(string username, string password)
8 | {
9 | Username = username;
10 | Password = password;
11 | }
12 |
13 | public string Username { get; private set; }
14 | public string Password { get; private set; }
15 |
16 | public static AuthToken GuestToken => new AuthToken("guest", string.Empty);
17 | }
18 | }
--------------------------------------------------------------------------------
/Tarantool.Net/Connection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 | using Akka.Actor;
9 | using Akka.Event;
10 | using Akka.IO;
11 | using MsgPack.Serialization;
12 | using Tarantool.Net.IProto;
13 | using Tarantool.Net.IProto.Requests;
14 | using Dns = System.Net.Dns;
15 | using Tuple = System.Tuple;
16 |
17 | namespace Tarantool.Net
18 | {
19 | public class Connection : ReceiveActor
20 | {
21 | private const int SyncMaxValue = int.MaxValue - 100;
22 | private static readonly MessagePackSerializer Serializer =
23 | SerializationContext.Default.GetSerializer();
24 | public class StateChange { }
25 | public class Connecting : StateChange
26 | {
27 | public Connecting(string host, int port)
28 | {
29 | Host = host;
30 | Port = port;
31 | }
32 |
33 | public string Host { get; }
34 | public int Port { get; }
35 | }
36 | public class Connected : StateChange
37 | {
38 | public Connected(string host, int port, string salt, string version)
39 | {
40 | Port = port;
41 | Salt = salt;
42 | Version = version;
43 | Host = host;
44 | }
45 |
46 | public string Version { get; }
47 | public string Salt { get; }
48 | public string Host { get; }
49 | public int Port { get; }
50 | }
51 | public class Disconnected : StateChange
52 | {
53 | public Disconnected(string host, int port)
54 | {
55 | Port = port;
56 | Host = host;
57 | }
58 |
59 | public string Host { get; }
60 | public int Port { get; }
61 | }
62 | public class ConnectionFailed : StateChange
63 | {
64 | public ConnectionFailed(string host, int port)
65 | {
66 | Port = port;
67 | Host = host;
68 | }
69 |
70 | public string Host { get; }
71 | public int Port { get; }
72 | }
73 | private class CommandAck : Tcp.Event
74 | {
75 | public CommandAck(IActorRef sender, int sync)
76 | {
77 | Sender = sender;
78 | Sync = sync;
79 | }
80 |
81 | public IActorRef Sender { get; private set; }
82 | public int Sync { get; private set; }
83 | }
84 | private class Heartbeat
85 | {
86 | public Heartbeat(TimeSpan delay)
87 | {
88 | Delay = delay;
89 | }
90 |
91 | public TimeSpan Delay { get; private set; }
92 | }
93 | internal class Connect
94 | {
95 | }
96 | public class CurrentConnection
97 | {
98 | public CurrentConnection(IActorRef socket, int sync = 10)
99 | {
100 | Sync = sync;
101 | Socket = socket;
102 | }
103 |
104 | public int GetNextSync()
105 | {
106 | if (Sync > SyncMaxValue) Sync = 0;
107 | return Sync++;
108 | }
109 |
110 | public int Sync { get; private set; }
111 | public IActorRef Socket { get; private set; }
112 | }
113 |
114 | private readonly IActorRef _listener;
115 | private readonly string _host;
116 | private readonly int _port;
117 | private readonly TimeSpan _connectionTimeout;
118 | private readonly TimeSpan _heartbeatDelay;
119 | //private readonly Queue _requesterQueue;
120 | private readonly Dictionary _requesterDictionary;
121 | private GreatingResponse _greatingResponse;
122 | private CurrentConnection _currentConnection;
123 | private DateTime _lastDataReceived = DateTime.Now;
124 | private byte[] _responseBuffer;
125 | private ICancelable _heartbeatTimer;
126 |
127 | public Connection(IActorRef listener, string host, int port, TimeSpan connectionTimeout, TimeSpan? heartbeatDelay = null)
128 | {
129 | _listener = listener;
130 | _host = host;
131 | _port = port;
132 | _connectionTimeout = connectionTimeout;
133 | _heartbeatDelay = heartbeatDelay ?? TimeSpan.FromSeconds(2);
134 | _requesterDictionary = new Dictionary();
135 | _responseBuffer = new byte[] { };
136 | Become(EstablishConnect);
137 | }
138 |
139 | protected override void PreStart()
140 | {
141 | Self.Tell(new Connect());
142 | base.PreStart();
143 | }
144 |
145 | private void EstablishConnect()
146 | {
147 | Receive(_ =>
148 | {
149 | IPAddress ip;
150 | if (!IPAddress.TryParse(_host, out ip))
151 | ip = Dns.GetHostAddresses(_host).First();
152 |
153 | var endPoint = new IPEndPoint(ip, _port);
154 | _listener.Tell(new Connecting(_host.ToString(), _port));
155 | Context.System.Tcp().Tell(new Tcp.Connect(endPoint, timeout: _connectionTimeout));
156 | });
157 |
158 | Receive(c =>
159 | {
160 | _currentConnection = new CurrentConnection(Sender);
161 | _currentConnection.Socket.Tell(new Tcp.Register(Self, useResumeWriting: false));
162 | var greatingMessageTimer = Context.System.Scheduler.ScheduleTellOnceCancelable(_connectionTimeout, Self,
163 | ReceiveTimeout.Instance, Self);
164 |
165 | Become(() => WaitingGreating(greatingMessageTimer));
166 | });
167 |
168 | }
169 |
170 |
171 | private void WaitingGreating(ICancelable greatingMessageTimer)
172 | {
173 | Receive(data =>
174 | {
175 | _lastDataReceived = DateTime.Now;
176 | greatingMessageTimer.Cancel();
177 | _greatingResponse = GreatingResponse.Parse(data.Data.ToArray());
178 | var scheduler = Context.System.Scheduler;
179 | var self = Self;
180 | Self.Ask(Request.Ping().Build(), _heartbeatDelay).ContinueWith(t =>
181 | {
182 | StateChange state = new Connected(_host.ToString(), _port, _greatingResponse.Salt, _greatingResponse.Version);
183 | if (t.IsFaulted)
184 | state = new ConnectionFailed(_host.ToString(), _port);
185 | else
186 | {
187 | _heartbeatTimer = scheduler.ScheduleTellRepeatedlyCancelable(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(1), self, new Heartbeat(_heartbeatDelay), self);
188 | }
189 |
190 |
191 | return state;
192 | }, TaskContinuationOptions.AttachedToParent & TaskContinuationOptions.ExecuteSynchronously).PipeTo(_listener);
193 | Become(WaitingAuth);
194 | });
195 |
196 | Receive(t =>
197 | {
198 | _currentConnection.Socket.Tell(Tcp.Close.Instance);
199 | });
200 |
201 | ConnectionManagement();
202 |
203 | }
204 |
205 | private void WaitingAuth()
206 | {
207 | Receive(data =>
208 | {
209 | ReceiveData(data);
210 | Become(ConnectedState);
211 | });
212 |
213 | ConnectionManagement();
214 | }
215 |
216 | private void ReceiveData(Tcp.Received data)
217 | {
218 | _lastDataReceived = DateTime.Now;
219 | var responses = ParseResponse(data.Data.ToArray());
220 |
221 | foreach (var response in responses)
222 | {
223 | if (!_requesterDictionary.ContainsKey(response.Sync))
224 | return;
225 |
226 |
227 | var sender = _requesterDictionary[response.Sync];
228 |
229 | if (sender != null)
230 | {
231 | if (response.IsError)
232 | sender.Tell(new Failure { Exception = new Exception(response.Error) }, Self);
233 | else if (!Equals(sender, Self))
234 | sender.Tell(response);
235 | }
236 | _requesterDictionary.Remove(response.Sync);
237 | }
238 | }
239 |
240 | private void ConnectedState()
241 | {
242 | Receive(data =>
243 | {
244 | ReceiveData(data);
245 | });
246 |
247 | ConnectionManagement();
248 |
249 | }
250 |
251 | private void ConnectionManagement()
252 | {
253 | Receive(_ =>
254 | {
255 | _requesterDictionary.Clear();
256 | _listener.Tell(new Disconnected(_host.ToString(), _port));
257 | _heartbeatTimer.Cancel();
258 | Become(EstablishConnect);
259 | });
260 |
261 | Receive(p => p.Cmd is Tcp.Write, c => _currentConnection.Socket.Tell(c.Cmd));
262 | Receive(p => p.Cmd is Tcp.Connect,
263 | c => _listener.Tell(new ConnectionFailed(_host.ToString(), _port)));
264 |
265 | Receive(s =>
266 | {
267 | _requesterDictionary.Add(s.Sync, s.Sender);
268 | });
269 |
270 | Receive(h =>
271 | {
272 | var idle = DateTime.Now - _lastDataReceived;
273 | var result = Tuple.Create(idle > (h.Delay + h.Delay), idle > h.Delay);
274 | if (result.Item1 && result.Item2)
275 | _currentConnection.Socket.Tell(Tcp.Close.Instance);
276 | else if (!result.Item1 && result.Item2)
277 | Self.Tell(Request.Ping().Build());
278 | });
279 |
280 | ReceiveRequests();
281 | }
282 |
283 | private void ReceiveRequests()
284 | {
285 | Receive(s =>
286 | {
287 | _sender = Sender;
288 | SendRequest(s);
289 | });
290 | }
291 |
292 | private IActorRef _sender = null;
293 | private void SendRequest(RequestBase s)
294 | {
295 | var sync = _currentConnection.GetNextSync();
296 | var message = s.WithSync(sync).GetBytes();
297 | _currentConnection.Socket.Tell(Tcp.Write.Create(ByteString.Create(message), new CommandAck(Sender, sync)));
298 | }
299 |
300 | private List ParseResponse(byte[] response)
301 | {
302 | var result = new List();
303 | int totalLen = response.Length;
304 |
305 | if (_responseBuffer.Length > 0)
306 | {
307 | totalLen = totalLen + _responseBuffer.Length;
308 | var temp = new byte[totalLen];
309 | Array.Copy(_responseBuffer, 0, temp, 0, _responseBuffer.Length);
310 | Array.Copy(response, 0, temp, _responseBuffer.Length, response.Length);
311 | response = temp;
312 | _responseBuffer = new byte[0];
313 | }
314 |
315 | int position = 0;
316 | while (position < totalLen)
317 | {
318 | position++;
319 | if (totalLen - position < 4)
320 | {
321 | position = position - 1;
322 | _responseBuffer = new byte[totalLen - position];
323 | Array.Copy(response, position, _responseBuffer, 0, totalLen - position);
324 | break;
325 | }
326 |
327 | var respLenArray = new byte[4];
328 | Array.Copy(response, position, respLenArray, 0, 4);
329 | Array.Reverse(respLenArray);
330 | var respLen = BitConverter.ToInt32(respLenArray, 0);
331 | position = position + 4;
332 |
333 | if (totalLen - position < respLen)
334 | {
335 | position = position - 5;
336 | _responseBuffer = new byte[totalLen - position];
337 | Array.Copy(response, position, _responseBuffer, 0, totalLen - position);
338 | break;
339 | }
340 |
341 | var resp = new byte[respLen];
342 | Array.Copy(response, position, resp, 0, respLen);
343 | position = position + respLen;
344 |
345 | result.Add(Serializer.UnpackSingleObject(resp));
346 | }
347 |
348 | return result;
349 | }
350 |
351 | }
352 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/AuthRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using Tarantool.Net.IProto.Requests;
2 |
3 | namespace Tarantool.Net.IProto.Builders
4 | {
5 | public class AuthRequestBuilder : RequestBuilder
6 | {
7 | private readonly AuthRequest _authRequest;
8 |
9 | public AuthRequestBuilder(AuthRequest authRequest) : base(authRequest)
10 | {
11 | _authRequest = authRequest;
12 | }
13 |
14 | public override RequestBase Build()
15 | {
16 | WithHeader(Command.AUTH)
17 | .WithInstruction(Key.USER_NAME, _authRequest.Username)
18 | .WithTuple(_authRequest.GetAuthTuple());
19 | return this;
20 | }
21 |
22 | public AuthRequestBuilder UserName(string userName)
23 | {
24 | _authRequest.Username = userName;
25 | return this;
26 | }
27 |
28 | public AuthRequestBuilder Password(string password)
29 | {
30 | _authRequest.Password = password;
31 | return this;
32 | }
33 |
34 | public AuthRequestBuilder Salt(string salt)
35 | {
36 | _authRequest.SetSalt(salt);
37 | return this;
38 | }
39 |
40 | public static implicit operator AuthRequest(AuthRequestBuilder authRequestBuilder)
41 | {
42 | return authRequestBuilder._authRequest;
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/CallRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using Tarantool.Net.IProto.Requests;
4 |
5 | namespace Tarantool.Net.IProto.Builders
6 | {
7 | public class CallRequestBuilder : RequestBuilder
8 | {
9 | private readonly CallRequest _callRequest;
10 |
11 | public CallRequestBuilder(CallRequest callRequest) : base(callRequest)
12 | {
13 | _callRequest = callRequest;
14 | }
15 |
16 | public CallRequestBuilder WithFunction(string name)
17 | {
18 | _callRequest.FunctionName = name;
19 | return this;
20 | }
21 |
22 | public CallRequestBuilder WithParams(params object[] parameters)
23 | {
24 | _callRequest.Params = parameters.ToList();
25 | return this;
26 | }
27 |
28 | public override RequestBase Build()
29 | {
30 | WithHeader(Command.CALL)
31 | .WithInstruction(Key.FUNCTION, _callRequest.FunctionName)
32 | .WithParams(_callRequest.Params);
33 |
34 | return this;
35 | }
36 |
37 | public static implicit operator CallRequest(CallRequestBuilder callRequestBuilder)
38 | {
39 | return callRequestBuilder._callRequest;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/DeleteRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Tarantool.Net.IProto.Requests;
3 |
4 | namespace Tarantool.Net.IProto.Builders
5 | {
6 | public class DeleteRequestBuilder : RequestBuilder
7 | {
8 | private readonly DeleteRequest _deleteRequest;
9 |
10 | public DeleteRequestBuilder(DeleteRequest deleteRequest) : base(deleteRequest)
11 | {
12 | _deleteRequest = deleteRequest;
13 | }
14 |
15 | public DeleteRequestBuilder WithSpaceId(UInt32 spaceId)
16 | {
17 | _deleteRequest.SpaceId = spaceId;
18 | return this;
19 | }
20 |
21 | public DeleteRequestBuilder WithIndexId(UInt32 indexId)
22 | {
23 | _deleteRequest.IndexId = indexId;
24 | return this;
25 | }
26 |
27 | public DeleteRequestBuilder WithKey(Func tupleBuilder)
28 | {
29 | var tb = new TupleBuilder(_deleteRequest.Key);
30 | _deleteRequest.Key = tupleBuilder(tb);
31 | return this;
32 | }
33 |
34 | public override RequestBase Build()
35 | {
36 | WithHeader(Command.DELETE)
37 | .WithInstruction(Key.SPACE, _deleteRequest.SpaceId)
38 | .WithInstruction(Key.INDEX, _deleteRequest.IndexId)
39 | .WithInstruction(Key.KEY, _deleteRequest.Key);
40 |
41 | return this;
42 | }
43 |
44 | public static implicit operator DeleteRequest(DeleteRequestBuilder deleteRequestBuilder)
45 | {
46 | return deleteRequestBuilder._deleteRequest;
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/EvalRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Tarantool.Net.IProto.Requests;
3 |
4 | namespace Tarantool.Net.IProto.Builders
5 | {
6 | public class EvalRequestBuilder : RequestBuilder
7 | {
8 | private readonly EvalRequest _evalRequest;
9 |
10 | public EvalRequestBuilder(EvalRequest evalRequest) : base(evalRequest)
11 | {
12 | _evalRequest = evalRequest;
13 | }
14 |
15 | public EvalRequestBuilder WithExpression(string expression)
16 | {
17 | _evalRequest.Expression = expression;
18 | return this;
19 | }
20 |
21 | public EvalRequestBuilder WithTuple(Func evalTupleBuilder)
22 | {
23 | var etb = new TupleBuilder(_evalRequest.Tuple);
24 | _evalRequest.Tuple = evalTupleBuilder(etb);
25 | return this;
26 | }
27 |
28 | public override RequestBase Build()
29 | {
30 | WithHeader(Command.EVAL)
31 | .WithInstruction(Key.EXPRESSION, _evalRequest.Expression)
32 | .WithTuple(_evalRequest.Tuple);
33 |
34 | return this;
35 | }
36 |
37 | public static implicit operator EvalRequest(EvalRequestBuilder evalRequestBuilder)
38 | {
39 | return evalRequestBuilder._evalRequest;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/InsertRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Tarantool.Net.IProto.Requests;
3 |
4 | namespace Tarantool.Net.IProto.Builders
5 | {
6 | public class InsertRequestBuilder : RequestBuilder
7 | {
8 | private readonly InsertReplaceRequest _insertReplaceRequest;
9 |
10 | public InsertRequestBuilder(InsertReplaceRequest insertReplaceRequest) : base(insertReplaceRequest)
11 | {
12 | _insertReplaceRequest = insertReplaceRequest;
13 | }
14 |
15 | ///
16 | /// Set Space Id
17 | ///
18 | /// Space Id
19 | ///
20 | public InsertRequestBuilder WithSpaceId(UInt32 spaceId)
21 | {
22 | _insertReplaceRequest.SpaceId = spaceId;
23 | return this;
24 | }
25 |
26 | public InsertRequestBuilder WithTuple(Func insertTupleBuilder)
27 | {
28 | var tb = new TupleBuilder(_insertReplaceRequest.Tuple);
29 | _insertReplaceRequest.Tuple = insertTupleBuilder(tb);
30 | return this;
31 | }
32 |
33 | public InsertRequestBuilder WithTuple(object[] tuple)
34 | {
35 | _insertReplaceRequest.Tuple = new Tuple(tuple);
36 | return this;
37 | }
38 |
39 | public override RequestBase Build()
40 | {
41 | WithHeader(Command.INSERT)
42 | .WithInstruction(Key.SPACE, _insertReplaceRequest.SpaceId)
43 | .WithTuple(_insertReplaceRequest.Tuple);
44 |
45 | return this;
46 | }
47 |
48 | public static implicit operator InsertReplaceRequest(InsertRequestBuilder insertRequestBuilder)
49 | {
50 | return insertRequestBuilder._insertReplaceRequest;
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/OperationsTupleBuilder.cs:
--------------------------------------------------------------------------------
1 | namespace Tarantool.Net.IProto.Builders
2 | {
3 | public class OperationsTupleBuilder
4 | {
5 | protected readonly OperationsTuple _tuple;
6 | public OperationsTupleBuilder(OperationsTuple tuple)
7 | {
8 | _tuple = tuple;
9 | }
10 |
11 | public OperationsTupleBuilder Addition(int fieldNumber, int argument)
12 | {
13 | return AddOperation(UpdateOperationCode.Addition, fieldNumber, argument);
14 | }
15 |
16 | public OperationsTupleBuilder Subtraction(int fieldNumber, int argument)
17 | {
18 | return AddOperation(UpdateOperationCode.Subtraction, fieldNumber, argument);
19 | }
20 |
21 | public OperationsTupleBuilder Delete(int fieldNumber, T argument)
22 | {
23 | return AddOperation(UpdateOperationCode.Delete, fieldNumber, argument);
24 | }
25 |
26 | public OperationsTupleBuilder Insert(int fieldNumber, T argument)
27 | {
28 | return AddOperation(UpdateOperationCode.Insert, fieldNumber, argument);
29 | }
30 |
31 | public OperationsTupleBuilder Assign(int fieldNumber, T argument)
32 | {
33 | return AddOperation(UpdateOperationCode.Assign, fieldNumber, argument);
34 | }
35 |
36 | protected OperationsTupleBuilder AddOperation(string operationType, int fieldNumber, T argument)
37 | {
38 | _tuple.AddField(new UpdateOperation
39 | {
40 | Code = operationType,
41 | FieldNo = (uint)fieldNumber,
42 | Arg = argument
43 | });
44 |
45 | return this;
46 | }
47 |
48 | public static implicit operator OperationsTuple(OperationsTupleBuilder tupleBuilder)
49 | {
50 | return tupleBuilder._tuple;
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/PingRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using Tarantool.Net.IProto.Requests;
2 |
3 | namespace Tarantool.Net.IProto.Builders
4 | {
5 | public class PingRequestBuilder : RequestBuilder
6 | {
7 | private readonly PingRequest _pingRequest;
8 |
9 | public PingRequestBuilder(PingRequest pingRequest) : base(pingRequest)
10 | {
11 | _pingRequest = pingRequest;
12 | }
13 |
14 | public override RequestBase Build()
15 | {
16 | WithHeader(Command.PING);
17 | return this;
18 | }
19 |
20 | public static implicit operator PingRequest(PingRequestBuilder pingRequestBuilder)
21 | {
22 | return pingRequestBuilder._pingRequest;
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/ReplaceRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Tarantool.Net.IProto.Requests;
3 |
4 | namespace Tarantool.Net.IProto.Builders
5 | {
6 | public class ReplaceRequestBuilder : RequestBuilder
7 | {
8 | private readonly InsertReplaceRequest _insertReplaceRequest;
9 |
10 | public ReplaceRequestBuilder(InsertReplaceRequest insertReplaceRequest) : base(insertReplaceRequest)
11 | {
12 | _insertReplaceRequest = insertReplaceRequest;
13 | }
14 |
15 | ///
16 | /// Set Space Id
17 | ///
18 | /// Space Id
19 | ///
20 | public ReplaceRequestBuilder WithSpaceId(UInt32 spaceId)
21 | {
22 | _insertReplaceRequest.SpaceId = spaceId;
23 | return this;
24 | }
25 |
26 | public ReplaceRequestBuilder WithTuple(Func insertTupleBuilder)
27 | {
28 | var tb = new TupleBuilder(_insertReplaceRequest.Tuple);
29 | _insertReplaceRequest.Tuple = insertTupleBuilder(tb);
30 | return this;
31 | }
32 |
33 | public override RequestBase Build()
34 | {
35 | WithHeader(Command.REPLACE)
36 | .WithInstruction(Key.SPACE, _insertReplaceRequest.SpaceId)
37 | .WithTuple(_insertReplaceRequest.Tuple);
38 |
39 | return this;
40 | }
41 |
42 | public static implicit operator InsertReplaceRequest(ReplaceRequestBuilder replaceRequestBuilder)
43 | {
44 | return replaceRequestBuilder._insertReplaceRequest;
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/SelectRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Tarantool.Net.IProto.Requests;
3 |
4 | namespace Tarantool.Net.IProto.Builders
5 | {
6 | public class SelectRequestBuilder : RequestBuilder
7 | {
8 | private readonly SelectRequest _selectRequest;
9 |
10 | public SelectRequestBuilder(SelectRequest selectRequest) : base(selectRequest)
11 | {
12 | _selectRequest = selectRequest;
13 | }
14 |
15 | public override RequestBase Build()
16 | {
17 | WithHeader(Command.SELECT)
18 | .WithInstruction(Key.SPACE, _selectRequest.SpaceId)
19 | .WithInstruction(Key.INDEX, _selectRequest.IndexId)
20 | .WithInstruction(Key.LIMIT, _selectRequest.Limit)
21 | .WithInstruction(Key.OFFSET, _selectRequest.Offset)
22 | .WithInstruction(Key.ITERATOR, (int) _selectRequest.Iterator)
23 | .WithInstruction(Key.KEY, _selectRequest.Key);
24 |
25 | return this;
26 | }
27 |
28 | public SelectRequestBuilder WithSpaceId(UInt32 spaceId)
29 | {
30 | _selectRequest.SpaceId = spaceId;
31 | return this;
32 | }
33 |
34 | public SelectRequestBuilder WithIndexId(UInt32 indexId)
35 | {
36 | _selectRequest.IndexId = indexId;
37 | return this;
38 | }
39 |
40 | public SelectRequestBuilder WithOffset(UInt32 offset)
41 | {
42 | _selectRequest.Offset = offset;
43 | return this;
44 | }
45 |
46 | public SelectRequestBuilder WithLimit(UInt32 limit)
47 | {
48 | _selectRequest.Limit = limit;
49 | return this;
50 | }
51 | public SelectRequestBuilder WithIterator(Iterator iterator)
52 | {
53 | _selectRequest.Iterator = iterator;
54 | return this;
55 | }
56 | public SelectRequestBuilder WithKey(Func tupleBuilder)
57 | {
58 | var tb = new TupleBuilder(_selectRequest.Key);
59 | _selectRequest.Key = tupleBuilder(tb);
60 | return this;
61 | }
62 |
63 | public static implicit operator SelectRequest(SelectRequestBuilder selectRequestBuilder)
64 | {
65 | return selectRequestBuilder._selectRequest;
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/TupleBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Tarantool.Net.IProto.Builders
4 | {
5 | public class TupleBuilder
6 | {
7 | private readonly Tuple _tuple;
8 |
9 | public TupleBuilder(Tuple tuple)
10 | {
11 | _tuple = tuple;
12 | }
13 |
14 | public TupleBuilder AddField(object data)
15 | {
16 | _tuple.AddField(data);
17 | return this;
18 | }
19 |
20 |
21 | public static implicit operator Tuple(TupleBuilder tupleBuilder)
22 | {
23 | return tupleBuilder._tuple;
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/UpdateOperationsTupleBuilder.cs:
--------------------------------------------------------------------------------
1 | using Tarantool.Net.IProto.Requests;
2 |
3 | namespace Tarantool.Net.IProto.Builders
4 | {
5 | public class UpdateOperationsTupleBuilder : OperationsTupleBuilder
6 | {
7 |
8 | public UpdateOperationsTupleBuilder(OperationsTuple tuple) : base(tuple)
9 | {
10 | }
11 |
12 | ///
13 | /// Addition OP='+' .space[][] +=
14 | ///
15 | /// Field Number
16 | /// Argument
17 | ///
18 | public new UpdateOperationsTupleBuilder Addition(int fieldNumber, int argument)
19 | {
20 | return (UpdateOperationsTupleBuilder)base.Addition(fieldNumber, argument);
21 | }
22 |
23 | ///
24 | /// Subtraction OP='-' .space[][] -=
25 | ///
26 | /// Field Number
27 | /// Argument
28 | ///
29 | public UpdateOperationsTupleBuilder Subtraction(int fieldNumber, int argument)
30 | {
31 | return (UpdateOperationsTupleBuilder)base.Subtraction(fieldNumber, argument);
32 | }
33 |
34 | ///
35 | /// Bitwise AND OP='&' .space[][] &=
36 | ///
37 | /// Field Number
38 | /// Argument
39 | ///
40 | public UpdateOperationsTupleBuilder BitwiseAnd(int fieldNumber, int argument)
41 | {
42 | return AddOperation(UpdateOperationCode.BitwiseAnd, fieldNumber, argument);
43 | }
44 |
45 | // ReSharper disable once InconsistentNaming
46 | public UpdateOperationsTupleBuilder BitwiseXOR(int fieldNumber, int argument)
47 | {
48 | return AddOperation(UpdateOperationCode.BitwiseXOR, fieldNumber, argument);
49 | }
50 |
51 | public UpdateOperationsTupleBuilder BitwiseOr(int fieldNumber, int argument)
52 | {
53 | return AddOperation(UpdateOperationCode.BitwiseOr, fieldNumber, argument);
54 | }
55 |
56 | ///
57 | /// Delete fields starting from in the space[]
58 | ///
59 | ///
60 | ///
61 | ///
62 | public new UpdateOperationsTupleBuilder Delete(int fieldNumber, T argument)
63 | {
64 | return (UpdateOperationsTupleBuilder)base.Delete(fieldNumber, argument);
65 | }
66 |
67 | public new UpdateOperationsTupleBuilder Insert(int fieldNumber, T argument)
68 | {
69 | return (UpdateOperationsTupleBuilder)base.Insert(fieldNumber, argument);
70 | }
71 |
72 | public new UpdateOperationsTupleBuilder Assign(int fieldNumber, T argument)
73 | {
74 | return (UpdateOperationsTupleBuilder)base.Assign(fieldNumber, argument);
75 | }
76 |
77 | private new UpdateOperationsTupleBuilder AddOperation(string operationType, int fieldNumber, T argument)
78 | {
79 | return (UpdateOperationsTupleBuilder)base.AddOperation(operationType, fieldNumber, argument);
80 | }
81 |
82 | ///
83 | /// Splice OP=':' take the string from space[][] and substitute bytes from with
84 | ///
85 | /// Field Number
86 | /// Offset
87 | /// Argument
88 | /// Possition
89 | ///
90 | public UpdateOperationsTupleBuilder Splice(int fieldNumber, int possition, int offset, string argument)
91 | {
92 | _tuple.AddField(new SpliceUpdateOperation
93 | {
94 | Offset = (uint)offset,
95 | Position = (uint)possition,
96 | FieldNo = (uint)fieldNumber,
97 | Arg = argument
98 | });
99 | return this;
100 | }
101 |
102 | public static implicit operator OperationsTuple(UpdateOperationsTupleBuilder tupleBuilder)
103 | {
104 | return tupleBuilder._tuple;
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/UpdateRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Tarantool.Net.IProto.Requests;
3 |
4 | namespace Tarantool.Net.IProto.Builders
5 | {
6 | public class UpdateRequestBuilder : RequestBuilder
7 | {
8 | private readonly UpdateRequest _updateRequest;
9 |
10 | public UpdateRequestBuilder(UpdateRequest updateRequest) : base(updateRequest)
11 | {
12 | _updateRequest = updateRequest;
13 | }
14 |
15 | ///
16 | /// Set Space Id
17 | ///
18 | /// Space Id
19 | ///
20 | public UpdateRequestBuilder WithSpaceId(UInt32 spaceId)
21 | {
22 | _updateRequest.SpaceId = spaceId;
23 | return this;
24 | }
25 |
26 | ///
27 | /// Set Index Id
28 | ///
29 | /// Index Id
30 | ///
31 | public UpdateRequestBuilder WithIndexId(UInt32 indexId)
32 | {
33 | _updateRequest.IndexId = indexId;
34 | return this;
35 | }
36 |
37 | ///
38 | /// Set Key Tuple
39 | ///
40 | /// Key tuple
41 | ///
42 | public UpdateRequestBuilder WithKeys(object[] keys)
43 | {
44 | _updateRequest.Key = new Tuple(keys);
45 | return this;
46 | }
47 |
48 | ///
49 | /// Set Key Tuple
50 | ///
51 | /// Key Builder
52 | ///
53 | public UpdateRequestBuilder WithKeys(Func keyTupleBuilder)
54 | {
55 | var ktb = new TupleBuilder(_updateRequest.Key);
56 | _updateRequest.Key = keyTupleBuilder(ktb);
57 | return this;
58 | }
59 |
60 | ///
61 | /// Set Key Tuple
62 | ///
63 | /// Key tuple
64 | ///
65 | public UpdateRequestBuilder WithKey(object key)
66 | {
67 | return WithKeys(t => t.AddField(key));
68 | }
69 |
70 | ///
71 | /// Set Update Operations
72 | ///
73 | /// Create Operation Tuple Action
74 | ///
75 | public UpdateRequestBuilder WithOperation(Func operationTupleBuilder)
76 | {
77 | var uotp = new UpdateOperationsTupleBuilder(_updateRequest.UpdateOperations);
78 | _updateRequest.UpdateOperations = operationTupleBuilder(uotp);
79 | return this;
80 | }
81 |
82 | public override RequestBase Build()
83 | {
84 | WithHeader(Command.UPDATE)
85 | .WithInstruction(Key.SPACE, _updateRequest.SpaceId)
86 | .WithInstruction(Key.INDEX, _updateRequest.IndexId)
87 | .WithInstruction(Key.KEY, _updateRequest.Key)
88 | .WithTuple(_updateRequest.UpdateOperations);
89 |
90 | return this;
91 | }
92 |
93 | public static implicit operator UpdateRequest(UpdateRequestBuilder updateRequestBuilder)
94 | {
95 | return updateRequestBuilder._updateRequest;
96 | }
97 | }
98 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Builders/UpsertRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Tarantool.Net.IProto.Requests;
3 |
4 | namespace Tarantool.Net.IProto.Builders
5 | {
6 | public class UpsertRequestBuilder : RequestBuilder
7 | {
8 | private readonly UpsertRequest _upsertRequest;
9 |
10 | public UpsertRequestBuilder(UpsertRequest upsertRequest) : base(upsertRequest)
11 | {
12 | _upsertRequest = upsertRequest;
13 | }
14 |
15 | ///
16 | /// Set Space Id
17 | ///
18 | /// Space Id
19 | ///
20 | public UpsertRequestBuilder WithSpaceId(UInt32 spaceId)
21 | {
22 | _upsertRequest.SpaceId = spaceId;
23 | return this;
24 | }
25 |
26 | ///
27 | /// Set Tuple
28 | ///
29 | /// Tuple
30 | ///
31 | public UpsertRequestBuilder WithTuple(object[] tuple)
32 | {
33 | _upsertRequest.Tuple = new Tuple(tuple);
34 | return this;
35 | }
36 |
37 | ///
38 | /// Set Tuple
39 | ///
40 | /// Key Builder
41 | ///
42 | public UpsertRequestBuilder WithTuple(Func tupleBuilder)
43 | {
44 | var tb = new TupleBuilder(_upsertRequest.Tuple);
45 | _upsertRequest.Tuple = tupleBuilder(tb);
46 | return this;
47 | }
48 |
49 | ///
50 | /// Set Tuple
51 | ///
52 | /// One element tuple
53 | ///
54 | public UpsertRequestBuilder WithTuple(object field)
55 | {
56 | return WithTuple(t => t.AddField(field));
57 | }
58 |
59 | public UpsertRequestBuilder WithOperation(Func operationTupleBuilder)
60 | {
61 | var uotp = new OperationsTupleBuilder(_upsertRequest.UpsertOperations);
62 | _upsertRequest.UpsertOperations = operationTupleBuilder(uotp);
63 | return this;
64 | }
65 |
66 | public override RequestBase Build()
67 | {
68 | WithHeader(Command.UPSERT)
69 | .WithInstruction(Key.SPACE, _upsertRequest.SpaceId)
70 | .WithTuple(_upsertRequest.Tuple)
71 | .WithInstruction(Key.UPSERT_OPS, _upsertRequest.UpsertOperations);
72 |
73 | return this;
74 | }
75 |
76 | public static implicit operator UpsertRequest(UpsertRequestBuilder upsertRequestBuilder)
77 | {
78 | return upsertRequestBuilder._upsertRequest;
79 | }
80 | }
81 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Command.cs:
--------------------------------------------------------------------------------
1 | // ReSharper disable InconsistentNaming
2 | namespace Tarantool.Net.IProto
3 | {
4 | public enum Command
5 | {
6 | SELECT = 0x01,
7 | INSERT = 0x02,
8 | REPLACE = 0x03,
9 | UPDATE = 0x04,
10 | DELETE = 0x05,
11 | CALL = 0x06,
12 | AUTH = 0x07,
13 | EVAL = 0x08,
14 | UPSERT = 0x09,
15 | // Admin command codes
16 | PING = 0x40
17 | }
18 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/GreatingResponse.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | namespace Tarantool.Net.IProto
5 | {
6 | public class GreatingResponse
7 | {
8 | public GreatingResponse(string version, string salt)
9 | {
10 | Version = version;
11 | Salt = salt;
12 | }
13 |
14 | public string Version { get; private set; }
15 | public string Salt { get; private set; }
16 |
17 | public static GreatingResponse Parse(byte[] value)
18 | {
19 | byte[] ver = new byte[63];
20 | Array.Copy(value, 0, ver, 0, 63);
21 |
22 | byte[] salt = new byte[44];
23 | Array.Copy(value, 64, salt, 0, 44);
24 |
25 | return new GreatingResponse(Encoding.ASCII.GetString(ver), Encoding.ASCII.GetString(salt));
26 | }
27 |
28 | }
29 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Iterator.cs:
--------------------------------------------------------------------------------
1 | // ReSharper disable InconsistentNaming
2 | namespace Tarantool.Net.IProto
3 | {
4 | public enum Iterator
5 | {
6 | EQ = 0,
7 | REQ = 1,
8 | ALL = 2,
9 | LT = 3,
10 | LE = 4,
11 | GE = 5,
12 | GT = 6,
13 | BITSET_ALL_SET = 7,
14 | BITSET_ANY_SET = 8,
15 | BITSET_ALL_NOT_SET = 9
16 | }
17 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Key.cs:
--------------------------------------------------------------------------------
1 | // ReSharper disable InconsistentNaming
2 | namespace Tarantool.Net.IProto
3 | {
4 | public enum Key
5 | {
6 | CODE = 0x00,
7 | SYNC = 0x01,
8 |
9 | SCHEMA_ID = 0x05,
10 |
11 | SPACE = 0x10,
12 | INDEX = 0x11,
13 | LIMIT = 0x12,
14 | OFFSET = 0x13,
15 | ITERATOR = 0x14,
16 |
17 | KEY = 0x20,
18 | TUPLE = 0x21,
19 | FUNCTION = 0x22,
20 | USER_NAME = 0x23,
21 | EXPRESSION = 0x27,
22 | UPSERT_OPS = 0x28,
23 | DATA = 0x30,
24 | ERROR = 0x31
25 | }
26 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/OperationsTuple.cs:
--------------------------------------------------------------------------------
1 | namespace Tarantool.Net.IProto
2 | {
3 | public class OperationsTuple : Tuple
4 | {
5 |
6 | }
7 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/PacketHeader.cs:
--------------------------------------------------------------------------------
1 | namespace Tarantool.Net.IProto
2 | {
3 | public class PacketHeader
4 | {
5 | public PacketHeader(Command command, int sync, int schemaId = 0)
6 | {
7 | Command = command;
8 | SchemaId = schemaId;
9 | Sync = sync;
10 | }
11 |
12 | public Command Command { get; private set; }
13 |
14 | public int SchemaId { get; private set; }
15 | public int Sync { get; private set; }
16 |
17 | public byte[] Raw
18 | {
19 | get
20 | {
21 | var temp = new byte[]
22 | {
23 | 0x82, (byte)Key.CODE, (byte)Command, (byte)Key.SYNC, 0xce, (byte)(Sync >> 24), (byte)(Sync >> 16),
24 | (byte)(Sync >> 8), (byte)Sync
25 | };
26 |
27 | return temp;
28 | }
29 | }
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/PacketType.cs:
--------------------------------------------------------------------------------
1 | namespace Tarantool.Net.IProto
2 | {
3 | public enum PacketType
4 | {
5 | Insert = 13,
6 | Select = 17,
7 | Update = 19,
8 | Delete = 21,
9 | Call = 22,
10 | Ping = 65280
11 | }
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Request.cs:
--------------------------------------------------------------------------------
1 | using Tarantool.Net.IProto.Builders;
2 | using Tarantool.Net.IProto.Requests;
3 |
4 | namespace Tarantool.Net.IProto
5 | {
6 | public class Request
7 | {
8 | public static AuthRequestBuilder Auth()
9 | {
10 | return new AuthRequestBuilder(new AuthRequest());
11 | }
12 |
13 | public static PingRequestBuilder Ping()
14 | {
15 | return new PingRequestBuilder(new PingRequest());
16 | }
17 |
18 | public static SelectRequestBuilder Select()
19 | {
20 | return new SelectRequestBuilder(new SelectRequest());
21 | }
22 |
23 | public static UpdateRequestBuilder Update()
24 | {
25 | return new UpdateRequestBuilder(new UpdateRequest());
26 | }
27 |
28 | public static InsertRequestBuilder Insert()
29 | {
30 | return new InsertRequestBuilder(new InsertReplaceRequest());
31 | }
32 |
33 | public static DeleteRequestBuilder Delete()
34 | {
35 | return new DeleteRequestBuilder(new DeleteRequest());
36 | }
37 |
38 | public static CallRequestBuilder Call()
39 | {
40 | return new CallRequestBuilder(new CallRequest());
41 | }
42 |
43 | public static EvalRequestBuilder Eval()
44 | {
45 | return new EvalRequestBuilder(new EvalRequest());
46 | }
47 |
48 | public static UpsertRequestBuilder Upsert()
49 | {
50 | return new UpsertRequestBuilder(new UpsertRequest());
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/RequestBody.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using MsgPack;
4 | using MsgPack.Serialization;
5 |
6 | namespace Tarantool.Net.IProto
7 | {
8 | public class RequestBody : IPackable
9 | {
10 | private readonly Dictionary _bodyParts = new Dictionary();
11 |
12 | [MessagePackMember(0)]
13 | public Dictionary Parts => _bodyParts;
14 |
15 | public void AddBodyData(Key key, T value)
16 | {
17 | _bodyParts[(UInt32)key] = value;
18 | }
19 |
20 | public void PackToMessage(Packer packer, PackingOptions options)
21 | {
22 | packer.PackMapHeader(_bodyParts.Count);
23 | foreach (var part in _bodyParts)
24 | {
25 | packer.Pack(part.Key);
26 | packer.Pack(part.Value);
27 | }
28 | }
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Requests/AuthRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security.Cryptography;
3 | using System.Text;
4 |
5 | namespace Tarantool.Net.IProto.Requests
6 | {
7 | public class AuthRequest : RequestBase
8 | {
9 | public AuthRequest()
10 | {
11 | Username = "guest";
12 | Password = string.Empty;
13 | }
14 |
15 | public string Username { get; set; }
16 | public string Password { get; set; }
17 |
18 | private string _salt;
19 |
20 | public void SetSalt(string salt)
21 | {
22 | _salt = salt;
23 | }
24 | public Tuple GetAuthTuple()
25 | {
26 | var tuple = new Tuple();
27 | if (string.IsNullOrWhiteSpace(Password))
28 | return tuple;
29 |
30 | var salt = Convert.FromBase64String(_salt);
31 | var sha = new SHA1Managed();
32 | var step1 = sha.ComputeHash(Encoding.UTF8.GetBytes(Password));
33 | var step2 = sha.ComputeHash(step1);
34 | var scrambleSize = 20;
35 |
36 | var saltedHash = new byte[step2.Length + salt.Length];
37 | salt.CopyTo(saltedHash, 0);
38 | step2.CopyTo(saltedHash, salt.Length);
39 | sha.Clear();
40 | sha = new SHA1Managed();
41 |
42 | sha.TransformBlock(salt, 0, scrambleSize, saltedHash, 0);
43 | sha.TransformFinalBlock(step2, 0, step2.Length);
44 |
45 | var step3 = sha.Hash;
46 | sha.Clear();
47 |
48 | var xor = XOR(step1, step3);
49 | tuple.AddField("chap-sha1");
50 | tuple.AddField(xor);
51 | return tuple;
52 | }
53 |
54 | private byte[] XOR(byte[] buffer1, byte[] buffer2)
55 | {
56 | byte[] result = new byte[20];
57 | for (int i = 0; i < buffer1.Length; i++)
58 | result[i] = (byte)(buffer1[i] ^ buffer2[i]);
59 | return result;
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/Tarantool.Net/IProto/Requests/CallRequest.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Tarantool.Net.IProto.Requests
4 | {
5 | public class CallRequest : RequestBase
6 | {
7 | public CallRequest()
8 | {
9 | Params = new List