Skip to content

Commit

Permalink
feat(csharp): adding csharp project (#25)
Browse files Browse the repository at this point in the history
* feat: add csharp to readme

* feat: add csharp logo

* feat: include csharp links to getting started

* feat: add csharp tutorial

* feat: add build with csharp

* fix: remove console.writeline

* feat: add cli

* feat: add README to csharp cli

* feat: add csharp cli

* fix: readme

* fix: modifications accordingly code review

* fix: markdown comment
  • Loading branch information
fernanduandrade authored Sep 25, 2023
1 parent e7b0428 commit 73b4239
Show file tree
Hide file tree
Showing 15 changed files with 1,092 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ You can find language-specific implementations in their corresponding folder:
- [Rust](/docs/source/build-with-rust.md)
- [Ruby](/docs/source/build-with-ruby.md)
- [Elixir](/docs/source/build-with-elixir.md)
- [Csharp](/docs/source/build-with-csharp.md)


## Sample Projects
Expand All @@ -41,6 +42,7 @@ We also built the full project with some extra features for you use as study gui
- [Python Project](/python)
- [Ruby Project](/ruby)
- [Elixir Project](/elixir)
- [Csharp Project](/csharp)


## Contributing
Expand Down
134 changes: 134 additions & 0 deletions csharp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.sln.docstates

# Build results

[Dd]ebug/
[Rr]elease/
x64/
[Bb]in/
[Oo]bj/
.idea

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.svclog
*.scc

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile

# Visual Studio profiler
*.psess
*.vsp
*.vspx

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# Click-Once directory
publish/

# Publish Web Output
*.Publish.xml
*.pubxml
*.azurePubxml

# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
packages/
## TODO: If the tool you use requires repositories.config, also uncomment the next line
!packages/repositories.config

# Windows Azure Build Output
csx/
*.build.csdef

# Windows Store app package directory
AppPackages/

# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
![Ss]tyle[Cc]op.targets
~$*
*~
*.dbmdl
*.[Pp]ublish.xml

*.publishsettings

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
App_Data/*.mdf
App_Data/*.ldf

# =========================
# Windows detritus
# =========================

# Windows image file caches
Thumbs.db
ehthumbs.db

# Folder config file
Desktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Mac desktop service store files
.DS_Store

_NCrunch*
203 changes: 203 additions & 0 deletions csharp/Cli.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
using MediaPlayer.Helper;
using MediaPlayer.Models;

namespace MediaPlayer;

public class Cli
{
private readonly DataBase _dataBase;

public Cli(string[] args)
{
var isConnectionValid = ValidateArguments(args);
if(isConnectionValid)
_dataBase = new DataBase(args);
else
throw new SystemException("See ya!");
}

public async Task Intro()
{
Console.WriteLine("------------------------------------");
Console.WriteLine("- ScyllaDB Cloud Rust Media Player -");
Console.WriteLine("------------------------------------");
Console.WriteLine("- Leave a star on the repo -");
Console.WriteLine("- https://bit.ly/scy-gh -");
Console.WriteLine("------------------------------------");
await _dataBase.Migrate();
Console.WriteLine("-----------------------------------");

}

private void DisplayHint()
{
Console.WriteLine("------------------------------------");
Console.WriteLine("Here some possibilities");
Console.WriteLine(" !add - add new song");
Console.WriteLine(" !list - list all songs");
Console.WriteLine(" !delete - delete a specific song");
Console.WriteLine(" !stress - stress testing with mocked data");
Console.WriteLine("------------------------------------");
}

public async Task Start()
{
try
{
bool lifeTimeCli = true;
DisplayHint();

while (lifeTimeCli)
{
var command = GetCommand();
switch (command)
{
case "!add":
await AddSong();
break;
case "!list":
await ListSongs();
break;
case "!delete":
await DeleteSong();
break;
case "!stress":
await Stress();
break;
case "!q":
await Exit();
break;
default:
await Start();
break;
}
DisplayHint();
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}

private string GetCommand()
{
Console.Write("Type any command: ");
var command = Console.ReadLine();

Console.WriteLine("");
if (string.IsNullOrEmpty(command))
{
DisplayHint();
GetCommand();
}

return command;
}

private async Task AddSong()
{
Console.Write($"Song name: ");
string title = Console.ReadLine();

Console.Write($"Album: ");
string album = Console.ReadLine();

Console.Write($"Artist: ");
string artist = Console.ReadLine();

var song = new Song()
{
Id = Guid.NewGuid(),
Album = album,
Artist = artist,
Title = title
};

Console.WriteLine($"Song {song.Title} from artist {song.Artist} Added!");

await _dataBase.Add(song);
}

private async Task ListSongs()
{
Console.WriteLine($"Here is the songs added so far: ");
Console.WriteLine($"-----------------------------------");

var songs = await _dataBase.ListSongs();

ShowSongList(songs);
Console.WriteLine($"-----------------------------------");
Console.WriteLine("");
}

private async Task Stress()
{
var start = DateTime.Now;
Console.WriteLine("------------------------------------");
Console.WriteLine("Inserting 100.000 records into the database...");
Console.WriteLine("> Starting...");

var interation = 100000;
var insertAsync = new List<Task>();
for (int i = 0; i < interation; i++)
{
insertAsync.Add(InsertSong());
}

await Task.WhenAll(insertAsync);

var timeElapsedToSecond = DateTime.Now - start;
await Console.Out.WriteLineAsync($"> Time elapsed: {timeElapsedToSecond.Seconds} seconds");
}

private async Task InsertSong()
{
var song = new Song()
{
Id = Guid.NewGuid(),
Album = "Test Album",
Artist = "Test Artist",
Title = "Test Song"
};

await _dataBase.Add(song);
}

private async Task DeleteSong()
{
var songs = await _dataBase.ListSongs();
ShowSongList(songs, true);
Console.Write("Select a index to be deleted: ");
var indexSelected = Console.ReadLine();
var song = songs[Convert.ToInt32(indexSelected) - 1];
Console.WriteLine($"Song {song.Title} from artist {song.Artist} Deleted!");
await _dataBase.Delete(song);

}

private bool ValidateArguments(string[] args)
{
return args.Length switch
{
0 => ValidationHelper.ArgsValidation("Missing all arguments."),
1 => ValidationHelper.ArgsValidation("Missing password credential."),
2 => ValidationHelper.ArgsValidation("0 of 3 nodes were provided."),
3 => ValidationHelper.ArgsValidation("1 of 3 nodes were provided."),
4 => ValidationHelper.ArgsValidation("2 of 3 nodes were provided."),
5 => true,
_ => ValidationHelper.ArgsValidation("Too many arguments")
};
}

private void ShowSongList(List<Song> songs, bool withIndex = false)
{
foreach (var (song, index) in songs.Select((v, i)=>(v, i)))
{
Console.WriteLine($"{(withIndex ? $"Index: {index + 1}" : $"ID: {song.Id}")} | Song: {song.Title} | Album: {song.Album} | Artist: {song.Artist} | Created At: {song.CreatedAt}");
}
}

private Task Exit()
=> throw new SystemException("See ya!");
}
15 changes: 15 additions & 0 deletions csharp/Constants/Queries.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace MediaPlayer.Constants;

public static class Queries
{
public static string CreateKeyspaceIfDoesntExistQuery => "CREATE KEYSPACE prod_media_player WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3'} AND durable_writes = true";
public static string CheckKeyspaceQuery => "SELECT keyspace_name FROM system_schema.keyspaces WHERE keyspace_name=?";
public static string CreateTableSongExistQuery => "CREATE TABLE prod_media_player.songs (id uuid, title text, album text, artist text, created_at timestamp, PRIMARY KEY (id, created_at))";
public static string CreateTableSongCounterQuery => "CREATE TABLE prod_media_player.song_counter (song_id uuid, times_played counter, PRIMARY KEY (song_id))";
public static string CheckTableQuery => "select keyspace_name, table_name from system_schema.tables where keyspace_name = ? AND table_name = ?";
public static string CreateSongQuery => "INSERT INTO prod_media_player.songs (id,title,artist,album,created_at) VALUES (?,?,?,?,?)";
public static string DeleteSongQuery => "DELETE FROM prod_media_player.songs WHERE id = ?";
public static string UpdateSongCounterQuery =>
"UPDATE prod_media_player.song_counter SET amount = amount + 1 WHERE id = 1";
public static string ListSongsQuery => "SELECT id, title, album, artist, created_at FROM prod_media_player.songs LIMIT 10";
}
Loading

0 comments on commit 73b4239

Please sign in to comment.