mirror of
https://github.com/awatertrevi/xamarin-neo4j.git
synced 2026-09-22 09:05:29 +00:00
connection string management + listing databases
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Acr.UserDialogs;
|
||||
using Android.App;
|
||||
using Android.Content.PM;
|
||||
using Android.Runtime;
|
||||
@@ -8,8 +9,7 @@ using Android.OS;
|
||||
|
||||
namespace Xamarin.Neo4j.Android
|
||||
{
|
||||
[Activity(Label = "Xamarin.Neo4j", Theme = "@style/MainTheme", MainLauncher = true,
|
||||
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
|
||||
[Activity(Label = "Xamarin.Neo4j", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
|
||||
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
|
||||
{
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
@@ -17,9 +17,22 @@ namespace Xamarin.Neo4j.Android
|
||||
TabLayoutResource = Resource.Layout.Tabbar;
|
||||
ToolbarResource = Resource.Layout.Toolbar;
|
||||
|
||||
UserDialogs.Init(this);
|
||||
|
||||
base.OnCreate(savedInstanceState);
|
||||
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
|
||||
|
||||
Essentials.Platform.Init(this, savedInstanceState);
|
||||
|
||||
Forms.Forms.Init(this, savedInstanceState);
|
||||
|
||||
LoadApplication(new App());
|
||||
}
|
||||
|
||||
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
|
||||
{
|
||||
Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.Xamarin.Neo4j">
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29" />
|
||||
<application android:label="Xamarin.Neo4j.Android"></application>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,6 @@
|
||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
|
||||
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
|
||||
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
|
||||
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
|
||||
</PropertyGroup>
|
||||
@@ -39,36 +38,36 @@
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Android"/>
|
||||
<Reference Include="System"/>
|
||||
<Reference Include="System.Core"/>
|
||||
<Reference Include="System.Xml.Linq"/>
|
||||
<Reference Include="System.Xml"/>
|
||||
<Reference Include="Mono.Android" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2012"/>
|
||||
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2196" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MainActivity.cs"/>
|
||||
<Compile Include="Resources\Resource.Designer.cs"/>
|
||||
<Compile Include="Properties\AssemblyInfo.cs"/>
|
||||
<Compile Include="MainActivity.cs" />
|
||||
<Compile Include="Resources\Resource.Designer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\AboutResources.txt"/>
|
||||
<None Include="Assets\AboutAssets.txt"/>
|
||||
<None Include="Properties\AndroidManifest.xml"/>
|
||||
<None Include="Resources\AboutResources.txt" />
|
||||
<None Include="Assets\AboutAssets.txt" />
|
||||
<None Include="Properties\AndroidManifest.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\layout\Tabbar.axml"/>
|
||||
<AndroidResource Include="Resources\layout\Toolbar.axml"/>
|
||||
<AndroidResource Include="Resources\values\styles.xml"/>
|
||||
<AndroidResource Include="Resources\values\colors.xml"/>
|
||||
<AndroidResource Include="Resources\layout\Tabbar.axml" />
|
||||
<AndroidResource Include="Resources\layout\Toolbar.axml" />
|
||||
<AndroidResource Include="Resources\values\styles.xml" />
|
||||
<AndroidResource Include="Resources\values\colors.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Xamarin.Neo4j\Xamarin.Neo4j.csproj">
|
||||
<Project>{25571B13-BB88-40F9-8C68-E66B1F4320A9}</Project>
|
||||
<Project>{756232D0-DBB0-4AEB-B1CF-1F5CA12CAC85}</Project>
|
||||
<Name>Xamarin.Neo4j</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets"/>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
</Project>
|
||||
|
||||
@@ -21,7 +21,8 @@ namespace Xamarin.Neo4j.iOS
|
||||
//
|
||||
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
|
||||
{
|
||||
global::Xamarin.Forms.Forms.Init();
|
||||
Forms.Forms.Init();
|
||||
|
||||
LoadApplication(new App());
|
||||
|
||||
return base.FinishedLaunching(app, options);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>$(AppIdentifierPrefix)nl.awater-enterprises.xamarin-neo4j</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Xamarin.Neo4j</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.companyname.Xamarin.Neo4j</string>
|
||||
<string>nl.resoftware.xamarin-neo4j</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
<MtouchArch>x86_64</MtouchArch>
|
||||
<MtouchLink>None</MtouchLink>
|
||||
<MtouchDebug>true</MtouchDebug>
|
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||
<CodesignKey>iPhone Developer</CodesignKey>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
|
||||
<DebugType>none</DebugType>
|
||||
@@ -35,6 +37,7 @@
|
||||
<MtouchLink>None</MtouchLink>
|
||||
<MtouchArch>x86_64</MtouchArch>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
<CodesignKey>iPhone Developer</CodesignKey>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -49,6 +52,7 @@
|
||||
<CodesignKey>iPhone Developer</CodesignKey>
|
||||
<MtouchDebug>true</MtouchDebug>
|
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||
<MtouchLink>SdkOnly</MtouchLink>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
|
||||
<DebugType>none</DebugType>
|
||||
@@ -60,6 +64,7 @@
|
||||
<ConsolePause>false</ConsolePause>
|
||||
<CodesignKey>iPhone Developer</CodesignKey>
|
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||
<MtouchLink>SdkOnly</MtouchLink>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' ">
|
||||
<DebugType>none</DebugType>
|
||||
@@ -73,6 +78,7 @@
|
||||
<CodesignProvision>Automatic:AdHoc</CodesignProvision>
|
||||
<CodesignKey>iPhone Distribution</CodesignKey>
|
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||
<MtouchLink>SdkOnly</MtouchLink>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' ">
|
||||
<DebugType>none</DebugType>
|
||||
@@ -85,6 +91,7 @@
|
||||
<CodesignProvision>Automatic:AppStore</CodesignProvision>
|
||||
<CodesignKey>iPhone Distribution</CodesignKey>
|
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||
<MtouchLink>SdkOnly</MtouchLink>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Main.cs" />
|
||||
@@ -106,11 +113,11 @@
|
||||
<Reference Include="Xamarin.iOS" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2012" />
|
||||
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2196" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Xamarin.Neo4j\Xamarin.Neo4j.csproj">
|
||||
<Project>{25571B13-BB88-40F9-8C68-E66B1F4320A9}</Project>
|
||||
<Project>{756232D0-DBB0-4AEB-B1CF-1F5CA12CAC85}</Project>
|
||||
<Name>Xamarin.Neo4j</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Xamarin.Neo4j.App">
|
||||
<Application.Resources>
|
||||
<Color x:Key="Glitter">#e4ecf5</Color>
|
||||
<Color x:Key="EbonyClay">#31333b</Color>
|
||||
|
||||
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeBrands">
|
||||
<On Platform="Android" Value="FontAwesome5Brands.ttf#Regular" />
|
||||
<On Platform="iOS" Value="FontAwesome5Brands-Regular" />
|
||||
@@ -17,5 +20,18 @@
|
||||
<On Platform="Android" Value="FontAwesome5Regular.ttf#Regular" />
|
||||
<On Platform="iOS" Value="FontAwesome5Free-Regular" />
|
||||
</OnPlatform>
|
||||
|
||||
<Style TargetType="ContentPage" ApplyToDerivedTypes="True">
|
||||
<Setter Property="BackgroundColor" Value="{StaticResource Glitter}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="ListView">
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="NavigationPage">
|
||||
<Setter Property="BarBackgroundColor" Value="{StaticResource EbonyClay}"/>
|
||||
<Setter Property="BarTextColor" Value="White" />
|
||||
</Style>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// ConnectionStringManager.cs
|
||||
//
|
||||
// Trevi Awater
|
||||
// 13-11-2021
|
||||
//
|
||||
// © Xamarin.Neo4j
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Neo4j.Models;
|
||||
|
||||
namespace Xamarin.Neo4j.Managers
|
||||
{
|
||||
public class ConnectionStringManager
|
||||
{
|
||||
private const string ConnectionStringsKey = "connection_strings";
|
||||
|
||||
public static async Task<List<Neo4jConnectionString>> GetConnectionStrings()
|
||||
{
|
||||
var json = await SecureStorage.GetAsync(ConnectionStringsKey);
|
||||
|
||||
if (string.IsNullOrEmpty(json))
|
||||
return new List<Neo4jConnectionString>();
|
||||
|
||||
return JsonConvert.DeserializeObject<List<Neo4jConnectionString>>(json);
|
||||
}
|
||||
|
||||
public static async Task AddConnectionString(Neo4jConnectionString connectionString)
|
||||
{
|
||||
var connectionStrings = await GetConnectionStrings();
|
||||
|
||||
connectionStrings.Add(connectionString);
|
||||
|
||||
await SaveConnectionStrings(connectionStrings);
|
||||
}
|
||||
|
||||
private static async Task SaveConnectionStrings(IEnumerable<Neo4jConnectionString> connectionStrings)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(connectionStrings);
|
||||
|
||||
await SecureStorage.SetAsync(ConnectionStringsKey, json);
|
||||
}
|
||||
|
||||
public static async Task DeleteConnectionString(Neo4jConnectionString neo4JConnectionString)
|
||||
{
|
||||
var connectionStrings = await GetConnectionStrings();
|
||||
|
||||
connectionStrings = connectionStrings.Where(cs => cs.Id != neo4JConnectionString.Id)
|
||||
.ToList();
|
||||
|
||||
await SaveConnectionStrings(connectionStrings);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Xamarin.Neo4j/Xamarin.Neo4j/Xamarin.Neo4j/Models/Database.cs
Normal file
22
Xamarin.Neo4j/Xamarin.Neo4j/Xamarin.Neo4j/Models/Database.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// Database.cs
|
||||
//
|
||||
// Trevi Awater
|
||||
// 13-11-2021
|
||||
//
|
||||
// © Xamarin.Neo4j
|
||||
//
|
||||
|
||||
namespace Xamarin.Neo4j.Models
|
||||
{
|
||||
public class Database
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Status { get; set; }
|
||||
|
||||
public bool Default { get; set; }
|
||||
|
||||
public string DisplayName => Name + (Default ? " 🏠" : string.Empty);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Neo4jConnectionString.cs
|
||||
//
|
||||
// Trevi Awater
|
||||
// 13-11-2021
|
||||
//
|
||||
// © Xamarin.Neo4j
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace Xamarin.Neo4j.Models
|
||||
{
|
||||
public class Neo4jConnectionString
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Database { get; set; }
|
||||
|
||||
public string Host { get; set; }
|
||||
|
||||
public int Port { get; set; }
|
||||
|
||||
public string Username { get; set; }
|
||||
|
||||
public string Password { get; set; }
|
||||
|
||||
public bool Encrypted { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
Title="Add Connection"
|
||||
x:Class="Xamarin.Neo4j.Pages.AddConnectionPage">
|
||||
<ContentPage.Content>
|
||||
<ScrollView>
|
||||
@@ -15,6 +16,33 @@
|
||||
<Label Text="Port:" FontAttributes="Bold" FontSize="Small" />
|
||||
<Entry Text="{Binding Port}" Keyboard="Numeric" />
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout Spacing="4">
|
||||
<Label Text="Encryption:" FontAttributes="Bold" FontSize="Small" />
|
||||
<Switch IsToggled="{Binding Encryption}" />
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout Spacing="4">
|
||||
<Label Text="Username:" FontAttributes="Bold" FontSize="Small" />
|
||||
<Entry Text="{Binding Username}" Keyboard="Numeric" />
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout Spacing="4">
|
||||
<Label Text="Password:" FontAttributes="Bold" FontSize="Small" />
|
||||
<Entry Text="{Binding Password}" IsPassword="True" />
|
||||
</StackLayout>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Column="0" Text="Connect" Command="{Binding Commands[Connect]}" />
|
||||
<Button Grid.Column="1" Text="Test" Command="{Binding Commands[Test]}" />
|
||||
<Button Grid.Column="2" Text="Save" Command="{Binding Commands[Save]}" />
|
||||
</Grid>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</ContentPage.Content>
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
||||
x:Class="Xamarin.Neo4j.Pages.ConnectionsPage"
|
||||
x:Name="connectionsPage"
|
||||
Title="Connections">
|
||||
<ContentPage.IconImageSource>
|
||||
<FontImageSource
|
||||
FontFamily="{StaticResource FontAwesomeSolid}"
|
||||
Glyph="{x:Static fonts:FontAwesomeSolid.Server}"
|
||||
Size="20" />
|
||||
</ContentPage.IconImageSource>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Command="{Binding Commands[AddConnection]}">
|
||||
<ToolbarItem.IconImageSource>
|
||||
<FontImageSource
|
||||
FontFamily="{StaticResource FontAwesomeSolid}"
|
||||
Glyph="{x:Static fonts:FontAwesomeSolid.PlusCircle}" Size="20" />
|
||||
</ToolbarItem.IconImageSource>
|
||||
</ToolbarItem>
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ContentPage.Content>
|
||||
<ListView ItemsSource="{Binding ConnectionStrings}" ItemTapped="StartSession">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextCell Text="{Binding Name}" Detail="{Binding Host}">
|
||||
<TextCell.ContextActions>
|
||||
<MenuItem Text="Delete" Command="{Binding BindingContext.Commands[DeleteConnectionString], Source={x:Reference connectionsPage} }" CommandParameter="{Binding .}" IsDestructive="true" />
|
||||
</TextCell.ContextActions>
|
||||
</TextCell>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using Xamarin.Neo4j.Models;
|
||||
using Xamarin.Neo4j.ViewModels;
|
||||
|
||||
namespace Xamarin.Neo4j.Pages
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class ConnectionsPage : ContentPage
|
||||
{
|
||||
private ConnectionsViewModel ViewModel => (ConnectionsViewModel)BindingContext;
|
||||
|
||||
public ConnectionsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = new ConnectionsViewModel(Navigation);
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
ViewModel.LoadConnectionStrings();
|
||||
|
||||
base.OnAppearing();
|
||||
}
|
||||
|
||||
private async void StartSession(object sender, ItemTappedEventArgs e)
|
||||
{
|
||||
var connectionString = (Neo4jConnectionString)e.Item;
|
||||
|
||||
await Navigation.PushAsync(new SessionPage(connectionString));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
||||
Title="Queries"
|
||||
x:Class="Xamarin.Neo4j.Pages.QueriesPage">
|
||||
<ContentPage.IconImageSource>
|
||||
<FontImageSource
|
||||
FontFamily="{StaticResource FontAwesomeSolid}"
|
||||
Glyph="{x:Static fonts:FontAwesomeSolid.Code}"
|
||||
Size="20" />
|
||||
</ContentPage.IconImageSource>
|
||||
|
||||
<ContentPage.Content>
|
||||
<StackLayout>
|
||||
<Label Text="Hello, world!"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalOptions="CenterAndExpand" />
|
||||
</StackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using Xamarin.Neo4j.ViewModels;
|
||||
|
||||
namespace Xamarin.Neo4j.Pages
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class QueriesPage : ContentPage
|
||||
{
|
||||
public QueriesPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = new QueriesViewModel(Navigation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
||||
xmlns:pages="clr-namespace:Xamarin.Neo4j.Pages;assembly=Xamarin.Neo4j"
|
||||
x:Class="Xamarin.Neo4j.Pages.RootPage">
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Command="{Binding Commands[AddConnection]}">
|
||||
<ToolbarItem.IconImageSource>
|
||||
<FontImageSource
|
||||
FontFamily="{StaticResource FontAwesomeSolid}"
|
||||
Glyph="{x:Static fonts:FontAwesomeSolid.PlusCircle}" Size="20" />
|
||||
</ToolbarItem.IconImageSource>
|
||||
</ToolbarItem>
|
||||
</ContentPage.ToolbarItems>
|
||||
</ContentPage>
|
||||
<TabbedPage.Children>
|
||||
<pages:ConnectionsPage />
|
||||
<pages:QueriesPage />
|
||||
</TabbedPage.Children>
|
||||
</TabbedPage>
|
||||
|
||||
@@ -6,18 +6,22 @@ using System.Threading.Tasks;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using Xamarin.Neo4j.ViewModels;
|
||||
|
||||
namespace Xamarin.Neo4j.Pages
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class RootPage : ContentPage
|
||||
public partial class RootPage : TabbedPage
|
||||
{
|
||||
public RootPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
BindingContext = new RootViewModel(Navigation);
|
||||
protected override void OnCurrentPageChanged()
|
||||
{
|
||||
Title = CurrentPage.Title;
|
||||
|
||||
base.OnCurrentPageChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
||||
x:Class="Xamarin.Neo4j.Pages.SessionPage">
|
||||
<NavigationPage.TitleView>
|
||||
<StackLayout Spacing="0">
|
||||
<Label TextColor="White" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Tapped="FocusDatabasePicker" />
|
||||
</Label.GestureRecognizers>
|
||||
<Label.FormattedText>
|
||||
<FormattedString>
|
||||
<Span Text="{Binding CurrentDatabase.DisplayName}" />
|
||||
<Span Text=" " />
|
||||
<Span Text="{x:Static fonts:FontAwesomeSolid.CaretDown}" FontFamily="{StaticResource FontAwesomeSolid}" />
|
||||
</FormattedString>
|
||||
</Label.FormattedText>
|
||||
</Label>
|
||||
|
||||
<Picker x:Name="databasePicker" ItemsSource="{Binding AvailableDatabases}" ItemDisplayBinding="{Binding DisplayName}" SelectedItem="{Binding CurrentDatabase}" IsVisible="False" />
|
||||
</StackLayout>
|
||||
</NavigationPage.TitleView>
|
||||
|
||||
<ContentPage.Content>
|
||||
<StackLayout>
|
||||
<Editor Text="{Binding Query}" AutoSize="TextChanges" />
|
||||
<Button Text="Run Query" Command="{Binding Commands[RunQuery]}" />
|
||||
</StackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using Xamarin.Neo4j.Models;
|
||||
using Xamarin.Neo4j.ViewModels;
|
||||
|
||||
namespace Xamarin.Neo4j.Pages
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class SessionPage : ContentPage
|
||||
{
|
||||
public SessionPage(Neo4jConnectionString connectionString)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = new SessionViewModel(Navigation, connectionString);
|
||||
}
|
||||
|
||||
private void FocusDatabasePicker(object sender, EventArgs e)
|
||||
{
|
||||
databasePicker.Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// Neo4jService.cs
|
||||
//
|
||||
// Trevi Awater
|
||||
// 13-11-2021
|
||||
//
|
||||
// © Xamarin.Neo4j
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Neo4j.Driver;
|
||||
using Neo4jClient;
|
||||
using Neo4jClient.Cypher;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Neo4j.Models;
|
||||
using Xamarin.Neo4j.Services;
|
||||
[assembly: Dependency(typeof(Neo4jService))]
|
||||
namespace Xamarin.Neo4j.Services
|
||||
{
|
||||
public class Neo4jService
|
||||
{
|
||||
private BoltGraphClient GraphClient { get; set; }
|
||||
|
||||
public async Task<bool> EstablishConnection(Neo4jConnectionString connectionString)
|
||||
{
|
||||
var boltUri = $"bolt://{connectionString.Host}:{connectionString.Port}";
|
||||
|
||||
var driver = GraphDatabase.Driver(boltUri, AuthTokens.Basic(connectionString.Username, connectionString.Password), builder =>
|
||||
{
|
||||
builder.WithEncryptionLevel(connectionString.Encrypted ? EncryptionLevel.Encrypted : EncryptionLevel.None);
|
||||
});
|
||||
|
||||
GraphClient = new BoltGraphClient(driver);
|
||||
|
||||
try
|
||||
{
|
||||
await GraphClient.ConnectAsync();
|
||||
}
|
||||
|
||||
catch (AuthenticationException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<List<Database>> LoadDatabases()
|
||||
{
|
||||
var session = GraphClient.Driver.AsyncSession(d => d.WithDatabase("system"));
|
||||
var cursor = await session.RunAsync("SHOW DATABASES;");
|
||||
|
||||
var databases = new List<Database>();
|
||||
|
||||
while (await cursor.FetchAsync())
|
||||
{
|
||||
var name = cursor.Current.Values["name"].As<string>();
|
||||
var status = cursor.Current.Values["currentStatus"].As<string>();
|
||||
var @default = cursor.Current.Values["default"].As<bool>();
|
||||
|
||||
databases.Add(new Database()
|
||||
{
|
||||
Name = name,
|
||||
Status = status,
|
||||
Default = @default
|
||||
});
|
||||
}
|
||||
|
||||
return databases;
|
||||
}
|
||||
|
||||
public async Task ExecuteQuery(string query, string database)
|
||||
{
|
||||
var session = GraphClient.Driver.AsyncSession(d => d.WithDatabase(database));
|
||||
var cursor = await session.RunAsync(query);
|
||||
|
||||
while (await cursor.FetchAsync())
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,17 @@
|
||||
// © Xamarin.Neo4j
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Acr.UserDialogs;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Neo4j.Annotations;
|
||||
using Xamarin.Neo4j.Managers;
|
||||
using Xamarin.Neo4j.Models;
|
||||
using Xamarin.Neo4j.Pages;
|
||||
using Xamarin.Neo4j.Services;
|
||||
|
||||
namespace Xamarin.Neo4j.ViewModels
|
||||
{
|
||||
@@ -22,9 +29,53 @@ namespace Xamarin.Neo4j.ViewModels
|
||||
|
||||
private int _port;
|
||||
|
||||
private readonly Neo4jService _neo4jService;
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public AddConnectionViewModel(INavigation navigation) : base(navigation)
|
||||
{
|
||||
InitializeDefaultValues();
|
||||
|
||||
_neo4jService = DependencyService.Resolve<Neo4jService>();
|
||||
|
||||
Commands.Add("Test", new Command(async () =>
|
||||
{
|
||||
// TODO: Validate input.
|
||||
|
||||
var connectionString = BuildConnectionString();
|
||||
|
||||
var couldConnect = await _neo4jService.EstablishConnection(connectionString);
|
||||
|
||||
await UserDialogs.Instance.AlertAsync(couldConnect ? "Connection successful." : "Connection failed.");
|
||||
}));
|
||||
|
||||
Commands.Add("Save", new Command(async () =>
|
||||
{
|
||||
// TODO: Validate input.
|
||||
|
||||
var connectionString = BuildConnectionString();
|
||||
|
||||
var namePromptResult = await UserDialogs.Instance.PromptAsync("How do you want to name this connection?", "Save Connection", "Save", "Cancel");
|
||||
|
||||
if (!namePromptResult.Ok || string.IsNullOrWhiteSpace(namePromptResult.Value))
|
||||
return;
|
||||
|
||||
connectionString.Name = namePromptResult.Value;
|
||||
|
||||
await ConnectionStringManager.AddConnectionString(connectionString);
|
||||
|
||||
await Navigation.PopAsync();
|
||||
}));
|
||||
|
||||
Commands.Add("Connect", new Command(async () =>
|
||||
{
|
||||
// TODO: Validate input.
|
||||
|
||||
var connectionString = BuildConnectionString();
|
||||
|
||||
await Navigation.PushAsync(new SessionPage(connectionString));
|
||||
}));
|
||||
}
|
||||
|
||||
private void InitializeDefaultValues()
|
||||
@@ -33,14 +84,25 @@ namespace Xamarin.Neo4j.ViewModels
|
||||
Port = 7687;
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
private Neo4jConnectionString BuildConnectionString()
|
||||
{
|
||||
return new Neo4jConnectionString
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Host = Host,
|
||||
Port = Port,
|
||||
Username = Username,
|
||||
Password = Password,
|
||||
Encrypted = Encrypted
|
||||
};
|
||||
}
|
||||
|
||||
#region Bindable Properties
|
||||
|
||||
public bool Encrypted
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// ConnectionsViewModel.cs
|
||||
//
|
||||
// Trevi Awater
|
||||
// 13-11-2021
|
||||
//
|
||||
// © Xamarin.Neo4j
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Neo4j.Annotations;
|
||||
using Xamarin.Neo4j.Managers;
|
||||
using Xamarin.Neo4j.Models;
|
||||
using Xamarin.Neo4j.Pages;
|
||||
|
||||
namespace Xamarin.Neo4j.ViewModels
|
||||
{
|
||||
public class ConnectionsViewModel : ViewModelBase, INotifyPropertyChanged
|
||||
{
|
||||
private IEnumerable<Neo4jConnectionString> _connectionStrings;
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public ConnectionsViewModel(INavigation navigation) : base(navigation)
|
||||
{
|
||||
Commands.Add("AddConnection", new Command(() =>
|
||||
{
|
||||
Navigation.PushAsync(new AddConnectionPage());
|
||||
}));
|
||||
|
||||
Commands.Add("DeleteConnectionString", new Command(async (o) =>
|
||||
{
|
||||
if (!(o is Neo4jConnectionString neo4jConnectionString))
|
||||
return;
|
||||
|
||||
await ConnectionStringManager.DeleteConnectionString(neo4jConnectionString);
|
||||
|
||||
LoadConnectionStrings();
|
||||
}));
|
||||
}
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public async void LoadConnectionStrings()
|
||||
{
|
||||
ConnectionStrings = await ConnectionStringManager.GetConnectionStrings();
|
||||
}
|
||||
|
||||
#region Bindable Properties
|
||||
|
||||
public IEnumerable<Neo4jConnectionString> ConnectionStrings
|
||||
{
|
||||
get => _connectionStrings;
|
||||
|
||||
set
|
||||
{
|
||||
_connectionStrings = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// RootViewModel.cs
|
||||
// QueriesViewModel.cs
|
||||
//
|
||||
// Trevi Awater
|
||||
// 13-11-2021
|
||||
@@ -11,22 +11,18 @@ using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Neo4j.Annotations;
|
||||
using Xamarin.Neo4j.Pages;
|
||||
|
||||
namespace Xamarin.Neo4j.ViewModels
|
||||
{
|
||||
public class RootViewModel : ViewModelBase, INotifyPropertyChanged
|
||||
public class QueriesViewModel : ViewModelBase, INotifyPropertyChanged
|
||||
{
|
||||
public RootViewModel(INavigation navigation) : base(navigation)
|
||||
{
|
||||
Commands.Add("AddConnection", new Command(() =>
|
||||
{
|
||||
Navigation.PushAsync(new AddConnectionPage());
|
||||
}));
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public QueriesViewModel(INavigation navigation) : base(navigation)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// SessionViewModel.cs
|
||||
//
|
||||
// Trevi Awater
|
||||
// 13-11-2021
|
||||
//
|
||||
// © Xamarin.Neo4j
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Acr.UserDialogs;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Neo4j.Annotations;
|
||||
using Xamarin.Neo4j.Models;
|
||||
using Xamarin.Neo4j.Services;
|
||||
|
||||
namespace Xamarin.Neo4j.ViewModels
|
||||
{
|
||||
public class SessionViewModel : ViewModelBase, INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private readonly Neo4jService _neo4jService;
|
||||
|
||||
private Database _currentDatabase;
|
||||
|
||||
private List<Database> _availableDatabases;
|
||||
|
||||
private string _query;
|
||||
|
||||
public SessionViewModel(INavigation navigation, Neo4jConnectionString connectionString) : base(navigation)
|
||||
{
|
||||
_neo4jService = DependencyService.Resolve<Neo4jService>();
|
||||
|
||||
Commands.Add("RunQuery", new Command(async () =>
|
||||
{
|
||||
_neo4jService.ExecuteQuery(Query, CurrentDatabase.Name);
|
||||
}));
|
||||
|
||||
InitializeConnection(connectionString);
|
||||
}
|
||||
|
||||
private async void InitializeConnection(Neo4jConnectionString connectionString)
|
||||
{
|
||||
await _neo4jService.EstablishConnection(connectionString);
|
||||
|
||||
AvailableDatabases = await _neo4jService.LoadDatabases();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(connectionString.Database))
|
||||
CurrentDatabase = AvailableDatabases.SingleOrDefault(ad => ad.Name == connectionString.Database);
|
||||
|
||||
if (CurrentDatabase == null)
|
||||
CurrentDatabase = AvailableDatabases.Single(ad => ad.Default);
|
||||
}
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
#region Bindable Properties
|
||||
|
||||
public Database CurrentDatabase
|
||||
{
|
||||
get => _currentDatabase;
|
||||
|
||||
set
|
||||
{
|
||||
_currentDatabase = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public List<Database> AvailableDatabases
|
||||
{
|
||||
get => _availableDatabases;
|
||||
|
||||
set
|
||||
{
|
||||
_availableDatabases = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string Query
|
||||
{
|
||||
get => _query;
|
||||
|
||||
set
|
||||
{
|
||||
_query = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,13 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Acr.UserDialogs" Version="7.2.0.534" />
|
||||
<PackageReference Include="Neo4jClient" Version="4.1.18" />
|
||||
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2012" />
|
||||
<PackageReference Include="Xamarin.Essentials" Version="1.7.0" />
|
||||
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2196" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Converters" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user