Compare commits

..

No commits in common. "master" and "DatenbankJonas" have entirely different histories.

29 changed files with 344 additions and 2756 deletions

212
.gitignore vendored
View file

@ -1,5 +1,6 @@
# created by https://www.gitignore.io/api/git,rider,linux,csharp,aspnetcore
# Edit at https://www.gitignore.io/?templates=git,rider,linux,csharp,aspnetcore
# Created by https://www.gitignore.io/api/git,rider,linux,csharp,windows,dotnetcore,aspnetcore,visualstudio,visualstudiocode
# Edit at https://www.gitignore.io/?templates=git,rider,linux,csharp,windows,dotnetcore,aspnetcore,visualstudio,visualstudiocode
### ASPNETCore ###
## Ignore Visual Studio temporary files, build results, and
@ -11,8 +12,6 @@
*.userosscache
*.sln.docstates
*.db
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
@ -478,6 +477,16 @@ healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
### DotnetCore ###
# .NET Core build folders
/bin
/obj
# Common node modules locations
/node_modules
/wwwroot/node_modules
### Git ###
# Created by git for backups. To disable backups in Git:
# $ git config --global mergetool.keepBackup false
@ -577,5 +586,198 @@ fabric.properties
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# End of https://www.gitignore.io/api/git,rider,linux,csharp,aspnetcore
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
### VisualStudio ###
# User-specific files
# User-specific files (MonoDevelop/Xamarin Studio)
# Mono auto generated files
# Build results
# Visual Studio 2015/2017 cache/options directory
# Uncomment if you have tasks that create the project's static files in wwwroot
# Visual Studio 2017 auto generated files
# MSTest test Results
# NUnit
# Build Results of an ATL Project
# Benchmark Results
# .NET Core
# StyleCop
# Files built by Visual Studio
# Chutzpah Test files
# Visual C++ cache files
# Visual Studio profiler
# Visual Studio Trace Files
# TFS 2012 Local Workspace
# Guidance Automation Toolkit
# ReSharper is a .NET coding add-in
# JustCode is a .NET coding add-in
# TeamCity is a build add-in
# DotCover is a Code Coverage Tool
# AxoCover is a Code Coverage Tool
# Visual Studio code coverage results
# NCrunch
# MightyMoose
# Web workbench (sass)
# Installshield output folder
# DocProject is a documentation generator add-in
# Click-Once directory
# Publish Web Output
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
# NuGet Packages
# NuGet Symbol Packages
# The packages folder can be ignored because of Package Restore
# except build/, which is used as an MSBuild target.
# Uncomment if necessary however generally it will be regenerated when needed
# NuGet v3's project.json files produces more ignorable files
# Microsoft Azure Build Output
# Microsoft Azure Emulator
# Windows Store app package directories and files
# Visual Studio cache files
# files ending in .cache can be ignored
# but keep track of directories ending in .cache
# Others
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
# RIA/Silverlight projects
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
# SQL Server files
# Business Intelligence projects
# Microsoft Fakes
# GhostDoc plugin setting file
# Node.js Tools for Visual Studio
# Visual Studio 6 build log
# Visual Studio 6 workspace options file
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
# Visual Studio LightSwitch build output
# Paket dependency manager
# FAKE - F# Make
# CodeRush personal settings
# Python Tools for Visual Studio (PTVS)
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
# Telerik's JustMock configuration file
# BizTalk build output
# OpenCover UI analysis results
# Azure Stream Analytics local run output
# MSBuild Binary and Structured Log
# NVidia Nsight GPU debugger configuration file
# MFractors (Xamarin productivity tool) working folder
# Local History for Visual Studio
# BeatPulse healthcheck temp database
# Backup folder for Package Reference Convert tool in Visual Studio 2017
# End of https://www.gitignore.io/api/git,rider,linux,csharp,windows,dotnetcore,aspnetcore,visualstudio,visualstudiocode

36
.vscode/launch.json vendored
View file

@ -1,36 +0,0 @@
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/netcoreapp3.1/BuecherwurmAPI.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
"action": "openExternally",
"pattern": "^\\s*Now listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}

42
.vscode/tasks.json vendored
View file

@ -1,42 +0,0 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/BuecherwurmAPI.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/BuecherwurmAPI.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/BuecherwurmAPI.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}

View file

@ -1,67 +0,0 @@
using System.Collections.Generic;
using BuecherwurmAPI.Models;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
using Microsoft.Data.Sqlite;
//using Microsoft.EntityFrameworkCore;
namespace BuecherwurmAPI.Controllers
{
[Route("api/inventar")]
[ApiController]
public class ItemController : ControllerBase
{
private readonly ItemModel _repository;
public ItemController(IItem repository)
{
_repository = (ItemModel)repository;
}
// GET api/inventar
[HttpGet]
public ActionResult<IEnumerable<Item>> GetAllItems()
{
var items = _repository.GetAllItems();
return Ok(items);
}
// POST api/inventar
[HttpPost]
public ActionResult<IEnumerable<Item>> NewItem(ItemPost item)
{
var newItem = _repository.NewItem(item);
return Ok(newItem);
}
// GET api/nventar/{id}
[HttpGet("{itemId}")]
public ActionResult<IEnumerable<Item>> GetItemByID(long itemId)
{
var item = _repository.GetItemById(itemId);
if (item != null)
{
return Ok(item);
}
return NotFound();
}
// DELETE api/inventar/{id}
[HttpDelete("{itemId}")]
public ActionResult<IEnumerable<Item>> DeleteItem(long itemId)
{
var item = _repository.GetItemById(itemId);
if(item == null)
{
return NotFound();
}
_repository.DeleteItem(itemId);
return NoContent();
}
}
}

View file

@ -1,79 +0,0 @@
using System.Collections.Generic;
using BuecherwurmAPI.Models;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
//using Microsoft.EntityFrameworkCore;
namespace BuecherwurmAPI.Controllers
{
[Route("api/katalog") ]
[ApiController]
public class KatalogController :ControllerBase
{
private readonly KatalogModel _repository;
public KatalogController (ICatalogue repository)
{
_repository= (KatalogModel)repository;
}
// GET Katalog
[HttpGet]
public ActionResult<IEnumerable<IProduct>> GetAllProducts()
{
var Products =_repository.GetAllProducts();
return Ok(Products);
}
// POST katalog/buch
[HttpPost("buch")]
public ActionResult<Book> AddProduct(BookPost book)
{
var id = _repository.AddProduct(book);
return Ok(_repository.GetProductById(id));
}
// POST katalog/magazin
[HttpPost("magazin")]
public ActionResult<Magazin> AddProduct(MagazinPost book)
{
var id = _repository.AddProduct(book);
return Ok(_repository.GetProductById(id));
}
// GET katalog/{id}
[HttpGet("{id}")]
public ActionResult <IProduct> GetProductByID(long id)
{
var book = _repository.GetProductById(id);
if (book != null)
{
return Ok(book);
}
return NoContent();
}
// PUT Katalog/{id}
[HttpPut("{id}")]
public ActionResult<IProduct> EditProduct(long id, IProduct book)
{
_repository.EditProduct(id, book);
return Ok(book);
}
// DELETE katalog/{id}
[HttpDelete("{id}")]
public ActionResult<IProduct> DeleteProduct (long id)
{
var book = _repository.GetProductById(id);
if(book == null)
{
return NotFound();
}
_repository.DeleteProduct(id);
return NoContent();
}
}
}

View file

@ -1,13 +1,14 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using BuecherwurmAPI.Models;
using BuecherwurmAPI.Data;
using BuecherwurmAPI.DTOs;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.Extensions.Logging;
using Microsoft.Data.Sqlite;
using BuecherwurmAPI.Models;
namespace BuecherwurmAPI.Controllers
{
@ -15,43 +16,48 @@ namespace BuecherwurmAPI.Controllers
[ApiController]
public class LendController : ControllerBase
{
private readonly LendModel _repository;
//private readonly IMapper _mapper;
public LendController(ILend repo)
private readonly IRepository _repository;
private readonly IMapper _mapper;
public LendController(IRepository repository, IMapper mapper)
{
_repository = (LendModel)repo;
//_mapper = mapper;
_repository = repository;
_mapper = mapper;
}
//GET api/leihvorgang
[HttpGet]
public ActionResult<IEnumerable<Lend>> LendsGet()
{
return Ok(_repository.GetAllLends());
}
//POST api/leihvorgang
[HttpPost]
public ActionResult<LendPost> LendsPost(LendPost lend)
public ActionResult<LendReadDTO> LendsPost(Lend lend)
{
var newId = _repository.AddLend(lend);
if (newId > 0)
/*
Internally a lend is stored with an id
but the client shouldn't be allowed to set or change it
therefore the package 'AutoMapper' is used to prevent errors
that could happen when doing this task manually.
It takes the information from the client and maps it to the
corresponding internal object which then will be returned.
Furthermore it could be used to keep some attributes secret.
Another nice effect of this is that the implementation could be changed
while the interface could be retained by some minor changes in the code.
DTO stands for Data Transfer Object
*/
var item = new Lend
{
var item = new Lend
{
Id = newId,
Customer = lend.Customer,
Returned = false,
ItemId = lend.ItemId,
ReturnDate = lend.ReturnDate
};
return Ok(item);
}
else
{
return BadRequest();
}
Id = 256,
Customer = lend.Customer,
Returned = lend.Returned,
ItemId = lend.ItemId,
ReturnDate = lend.ReturnDate
};
return Ok(item);
//return Ok(_mapper.Map<LendReadDTO>(item));
}
@ -64,16 +70,14 @@ namespace BuecherwurmAPI.Controllers
{
return NotFound();
}
return Ok(lend);
}
//PUT api/leihvorgang/{id}
[HttpPut("{id}")]
public ActionResult LendPatchById(long id, LendPost lend)
//PATCH api/leihvorgang/{id}
[HttpPatch("{id}")]
public ActionResult LendPatchById(int id, JsonPatchDocument<Lend> patchDocument)
{
var lendPatch = _repository.insertLendReturningId(id, lend);
return Ok(lendPatch);
return Ok();
}
}
}
}

12
DTOs/LendRead.cs Normal file
View file

@ -0,0 +1,12 @@
using System;
namespace BuecherwurmAPI.DTOs
{
public class LendReadDTO
{
public int ItemId { get; set;}
public DateTime ReturnDate { get; set; }
public string Customer { get; set; }
public bool Returned { get; set; }
}
}

11
Data/ILendRepo.cs Normal file
View file

@ -0,0 +1,11 @@
using System.Collections.Generic;
using BuecherwurmAPI.Models;
namespace BuecherwurmAPI.Data
{
public interface ILendRepo
{
IEnumerable<Lend> GetAllLends();
Lend GetLendById(int id);
}
}

13
Data/IRepository.cs Normal file
View file

@ -0,0 +1,13 @@
using System.Collections.Generic;
using BuecherwurmAPI.Models;
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
namespace BuecherwurmAPI.Data
{
public interface IRepository
{
IEnumerable<Lend> GetAllLends();
Lend GetLendById(long id);
bool IdExits(string table, long id);
}
}

26
Data/MockLendRepo.cs Normal file
View file

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using BuecherwurmAPI.Models;
namespace BuecherwurmAPI.Data
{
public class MockLendRepo : ILendRepo
{
public IEnumerable<Lend> GetAllLends()
{
var lends = new List<Lend>
{
new Lend{Id = 1, Customer = "Nek0", ItemId = 1337, Returned = false, ReturnDate = DateTime.Now},
new Lend{Id = 2, Customer = "Shrubbery", ItemId = 1975, Returned = false, ReturnDate = DateTime.Now},
new Lend{Id = 3, Customer = "Felix", ItemId = 42, Returned = true, ReturnDate = DateTime.Now}
};
return lends;
}
public Lend GetLendById(int id)
{
return new Lend{Id = 1, Customer = "Nek0", ItemId = 1337, Returned = false, ReturnDate = DateTime.Now};
}
}
}

View file

@ -4,19 +4,13 @@ using BuecherwurmAPI.Models;
using Microsoft.Data.Sqlite;
using Microsoft.VisualBasic.CompilerServices;
namespace BuecherwurmAPI.Models
namespace BuecherwurmAPI.Data
{
public interface ILend
{
}
internal class LendModel : ILend
internal class Repository : IRepository
{
private SqliteConnection _dbConnection;
public LendModel()
public Repository()
{
var connectionBuilder = new SqliteConnectionStringBuilder {DataSource = "LongWormMemory.db"};
_dbConnection = new SqliteConnection(connectionBuilder.ConnectionString);
@ -100,55 +94,5 @@ namespace BuecherwurmAPI.Models
}
return null;
}
public long insertLendReturningId(long id, LendPost lend)
{
using (var command = _dbConnection.CreateCommand())
{
command.CommandText = "UPDATE Lends SET (ItemId, ReturnDate, Customer, Returned) = (@itemId, @returnDate, @customer, @returned) WHERE Id = @id";
command.Parameters.Add(new SqliteParameter("@id", id));
command.Parameters.Add(new SqliteParameter("@itemId", lend.ItemId));
command.Parameters.Add(new SqliteParameter("@returnDate", lend.ReturnDate));
command.Parameters.Add(new SqliteParameter("@customer", lend.Customer));
command.Parameters.Add(new SqliteParameter("@returned", lend.Returned));
var success = command.ExecuteNonQuery();
if (success == 1)
{
command.CommandText = @"SELECT last_insert_rowid()";
return (long)command.ExecuteScalar();
}
return -1;
}
}
public long AddLend (LendPost lend)
{
using (var command = _dbConnection.CreateCommand())
{
// funktioniert das so?
//muss ProduktId übergeben werden?
command.CommandText = @"INSERT INTO Lends (itemid, ReturnDate, Customer, Returned) VALUES (@ItemId, @ReturnDate, @Customer, false)";
command.Parameters.Add(new SqliteParameter("@ItemId", lend.ItemId));
command.Parameters.Add(new SqliteParameter("@ReturnDate", lend.ReturnDate));
command.Parameters.Add(new SqliteParameter("@Customer", lend.Customer));
var success = command.ExecuteNonQuery();
if (success == 1)
{
command.CommandText = @"SELECT last_insert_rowid()";
return (long)command.ExecuteScalar();
}
return -1;
}
}
}
}

View file

@ -1,12 +1,10 @@
namespace BuecherwurmAPI.Models
namespace BuecherwurmAPI.Data
{
public static class Tables
{
public struct Table
{
public const string Lends = "Lends";
public const string Katalog = "Katalog";
public const string Items = "Items";
}
}
}

BIN
LongWormMemory.db Normal file

Binary file not shown.

View file

@ -1,44 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace BuecherwurmAPI.Models
{
public class Book : IProduct
{
[Key, Required]
public long ProductId { get; set; }
public string Title {get; set;}
public string Author {get; set;}
public string Country {get; set;}
public string Link {get; set;}
public string Language {get; set;}
public long Pages {get; set;}
public long Year {get; set;}
public CategoryEnum Category { get; set; }
public string ImageLink { get; set; }
public long LendTime {get; set;}
public LendTypeEnum LendType {get; set;}
}
public class BookPost : IProductPost
{
public string Title {get; set;}
public string Author {get; set;}
public string Country {get; set;}
public string Link {get; set;}
public string Language {get; set;}
public long Pages {get; set;}
public long Year {get; set;}
public CategoryEnum Category { get; set; }
public string ImageLink { get; set; }
public long LendTime {get; set;}
public LendTypeEnum LendType {get; set;}
public BookPost()
{
LendType = LendTypeEnum.Physical;
LendTime = 30;
Category = CategoryEnum.Book;
}
}
}

View file

@ -1,11 +0,0 @@
namespace BuecherwurmAPI.Models
{
public enum CategoryEnum
{
Book,
Magazine,
EBook,
EPaper
}
}

View file

@ -1,14 +0,0 @@
using System.Collections.Generic;
using BuecherwurmAPI.Models;
namespace BuecherwurmAPI.Models
{
public interface IBookRepo
{
IEnumerable<Book> GetAllBooks();
Book GetBookById(long id);
void DeleteBook(long id);
long AddBook (Book book);
long EditBook (long id, Book book);
}
}

View file

@ -1,13 +0,0 @@
using System.Collections.Generic;
using BuecherwurmAPI.Models;
namespace BuecherwurmAPI.Models
{
public interface IItemRepo
{
IEnumerable<Item> GetAllItems();
Item GetItemById(long itemId);
Item NewItem(ItemPost item);
void DeleteItem(long itemId);
}
}

View file

@ -1,26 +0,0 @@
namespace BuecherwurmAPI.Models
{
public interface IProductPost
{
CategoryEnum Category {get; set;}
long LendTime {get; set;}
string Title {get; set;}
LendTypeEnum LendType {get; set;}
}
public interface IProduct
{
long ProductId {get; set;}
CategoryEnum Category {get; set;}
long LendTime {get; set;}
string Title {get; set;}
LendTypeEnum LendType {get; set;}
}
}

View file

@ -1,16 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace BuecherwurmAPI.Models
{
public class Item
{
[Key, Required]
public long ItemId { get; set; }
[Required]
public long BookId { get; set; }
}
public class ItemPost
{
public int BookId { get; set; }
}
}

View file

@ -1,121 +0,0 @@
using System;
using System.Collections.Generic;
using BuecherwurmAPI.Models;
using Microsoft.Data.Sqlite;
using Microsoft.VisualBasic.CompilerServices;
namespace BuecherwurmAPI.Models
{
public interface IItem
{
}
internal class ItemModel : IItem
{
private SqliteConnection _dbConnection;
public ItemModel()
{
var connectionBuilder = new SqliteConnectionStringBuilder {DataSource = "LongWormMemory.db"};
_dbConnection = new SqliteConnection(connectionBuilder.ConnectionString);
_dbConnection.Open();
}
public bool IdExits(string table, long id)
{
using (var command = _dbConnection.CreateCommand())
{
command.Parameters.Add(new SqliteParameter("@Id", SqliteType.Integer)).Value = id;
// Certain parts of the query can't be filled with variables for security reasons.
switch (table)
{
case Tables.Table.Items:
command.CommandText = @"SELECT EXISTS(SELECT 0 FROM Items WHERE Id = @Id)";
break;
}
var dr = command.ExecuteReader();
long result = 0;
while (dr.Read())
{
result = (long) dr[0];
}
return result != 0;
}
}
public IEnumerable<Item> GetAllItems()
{
var items = new List<Item>();
// using automatically disposes the command after completion
using (var command = _dbConnection.CreateCommand())
{
command.CommandText = "SELECT * FROM Items";
var dataReader = command.ExecuteReader();
while (dataReader.Read())
{
items.Add(new Item
{
ItemId = (long) dataReader["ItemId"],
BookId = (long) dataReader["BookId"]
});
}
}
return items;
}
public Item GetItemById(long itemId)
{
using (var command = _dbConnection.CreateCommand())
{
command.Parameters.Add(new SqliteParameter("@itemId", itemId));
command.CommandText = "SELECT * FROM Items WHERE ItemId = @itemId";
var dataReader = command.ExecuteReader();
while (dataReader.Read())
{
var item = new Item
{
ItemId = (long) dataReader["ItemId"],
BookId = (long) dataReader["BookId"]
};
return item;
}
}
return null;
}
public Item NewItem(ItemPost itemPost)
{
using (var command = _dbConnection.CreateCommand())
{
//hier soll jetz der NewItem Command folgen. ein POST mit EingabeInfo {id} = "BookId"
command.CommandText = "INSERT INTO Items (BookId) VALUES (@bookId)";
command.CommandType = System.Data.CommandType.Text;
command.Parameters.Add(new SqliteParameter("@bookId", itemPost.BookId));
command.ExecuteNonQuery();
command.CommandText = "select last_insert_rowid()";
var LastRowId64 = (long)command.ExecuteScalar();
var item = new Item{
ItemId = LastRowId64,
BookId = itemPost.BookId
};
return item;
}
}
public void DeleteItem(long itemId)
{
using (var command = _dbConnection.CreateCommand())
{
command.CommandText = "DELETE FROM Items WHERE ItemId = @itemId";
command.Parameters.Add(new SqliteParameter("@itemId", itemId));
command.ExecuteNonQuery();
}
}
}
}

View file

@ -1,224 +0,0 @@
using System;
using System.Collections.Generic;
using BuecherwurmAPI.Models;
using Microsoft.Data.Sqlite;
using Microsoft.VisualBasic.CompilerServices;
namespace BuecherwurmAPI.Models
{
public interface ICatalogue
{
}
internal class KatalogModel : ICatalogue
{
private SqliteConnection _dbConnection;
public KatalogModel()
{
var connectionBuilder = new SqliteConnectionStringBuilder {DataSource = "LongWormMemory.db"};
_dbConnection = new SqliteConnection(connectionBuilder.ConnectionString);
_dbConnection.Open();
}
public IEnumerable<IProduct> GetAllProducts()
{
var books= new List<IProduct>();
using (var command = _dbConnection.CreateCommand())
{
command.CommandText = @"SELECT * FROM Products";
var dataReader = command.ExecuteReader();
while (dataReader.Read())
{
if (!dataReader["Author"].Equals(null))
{
books.Add(new Book
{
Title = (string) dataReader["Title"],
Author = (string) dataReader["Author"],
Country = (string) dataReader["Country"],
Link = (string) dataReader["Link"],
Language = (string) dataReader["Language"],
Pages = (long) dataReader["Pages"],
Year = (long) dataReader["Year"],
ProductId = (long) dataReader["ProductId"],
Category = (CategoryEnum) Enum.Parse(typeof(CategoryEnum), dataReader["Category"].ToString()),
ImageLink = (string) dataReader["ImageLink"],
LendTime = (long) dataReader["LendTime"],
LendType = (LendTypeEnum) Enum.Parse(typeof(LendTypeEnum), dataReader["LendType"].ToString())
});
}
else
{
books.Add(new Magazin
{
Title = (string) dataReader["Title"],
LendTime = (long) dataReader["LendTime"],
LendType = (LendTypeEnum) Enum.Parse(typeof(LendTypeEnum), dataReader["LendType"].ToString()),
Category = (CategoryEnum) Enum.Parse(typeof(CategoryEnum), dataReader["Category"].ToString()),
Run = (long) dataReader["Run"],
Audience = (string) dataReader["Audience"],
Topic = (string) dataReader["Topic"]
});
}
}
}
return books;
}
public IProduct GetProductById(long id)
{
using (var command = _dbConnection.CreateCommand())
{
command.CommandText = "SELECT * FROM \"Products\" WHERE ProductId = @id";
command.Parameters.Add(new SqliteParameter("@id", id));
var dataReader = command.ExecuteReader();
IProduct book;
dataReader.Read();
if (dataReader["Author"].Equals(null))
{
book = new Magazin
{
Title = (string)dataReader["Title"],
LendTime = (long)dataReader["LendTime"],
LendType = (LendTypeEnum) Enum.Parse(typeof(LendTypeEnum), dataReader["LendType"].ToString()),
Category = (CategoryEnum) Enum.Parse(typeof(CategoryEnum), dataReader["Category"].ToString()),
Run = (long)dataReader["Run"],
Audience = (string)dataReader["Audience"],
Topic = (string)dataReader["Topic"]
};
}
else
{
book = new Book
{
Title = (string)dataReader["Title"],
Author = (string)dataReader["Author"],
Country = (string)dataReader["Country"],
Link = (string)dataReader["Link"],
Language = (string)dataReader["Language"],
Pages = (long)dataReader["Pages"],
Year = (long)dataReader["Year"],
ProductId = (long)dataReader["ProductId"],
Category = (CategoryEnum) Enum.Parse(typeof(CategoryEnum), dataReader["Category"].ToString()),
ImageLink = (string) dataReader["ImageLink"],
LendTime = (long) dataReader["LendTime"],
LendType = (LendTypeEnum) Enum.Parse(typeof(LendTypeEnum), dataReader["LendType"].ToString())
};
}
return book;
}
}
public void DeleteProduct(long id)
{
using (var command = _dbConnection.CreateCommand())
{
command.Parameters.Add(new SqliteParameter("@id", id));
command.CommandText = @"DELETE FROM Products WHERE ProductId= @id";
var dataReader = command.ExecuteReader();
}
}
public long AddProduct (IProductPost book)
{
using (var command = _dbConnection.CreateCommand())
{
command.CommandText = @"INSERT INTO Products (ProductId, Title, Author, Country, Link, Language, Pages, Year, Category, ImageLink, LendTime, LendType, Run, Audience, Topic) VALUES (NULL, @Title, @Author, @Country, @Link, @Language, @Pages, @Year, @Category, @ImageLink, @LendTime, @LendType, @Run, @Audience, @Topic)";
command.Parameters.Add(new SqliteParameter("@Title", book.Title));
command.Parameters.Add(new SqliteParameter("@Category", book.Category));
command.Parameters.Add(new SqliteParameter("@LendTime", book.LendTime));
command.Parameters.Add(new SqliteParameter("@LendType", book.LendType));
if (book.GetType() == typeof(BookPost))
{
command.Parameters.Add(new SqliteParameter("@Author", ((BookPost)book).Author));
command.Parameters.Add(new SqliteParameter("@Country", ((BookPost)book).Country));
command.Parameters.Add(new SqliteParameter("@Link", ((BookPost)book).Link));
command.Parameters.Add(new SqliteParameter("@Language", ((BookPost)book).Language));
command.Parameters.Add(new SqliteParameter("@Pages", ((BookPost)book).Pages));
command.Parameters.Add(new SqliteParameter("@Year", ((BookPost)book).Year));
command.Parameters.Add(new SqliteParameter("@ImageLink", ((BookPost)book).ImageLink));
command.Parameters.Add(new SqliteParameter("@Run", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Audience", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Topic", DBNull.Value));
}
else
{
command.Parameters.Add(new SqliteParameter("@Author", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Country", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Link", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Language", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Pages", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Year", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@ImageLink", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Run", ((MagazinPost)book).Run));
command.Parameters.Add(new SqliteParameter("@Audience", ((MagazinPost)book).Audience));
command.Parameters.Add(new SqliteParameter("@Topic", ((MagazinPost)book).Topic));
}
var success = command.ExecuteNonQuery();
if (success == 1)
{
command.CommandText = @"SELECT last_insert_rowid()";
return (long)command.ExecuteScalar();
}
return -1;
}
}
public long EditProduct (long id, IProduct book)
{
using (var command = _dbConnection.CreateCommand())
{
// funktioniert das so?
command.Parameters.Add(new SqliteParameter("@id", id));
command.CommandText = @"UPDATE Products SET (Title, Author, Country, Link, Language, Pages, Year, Category, ImageLink, LendTime, LendType, Run, Audience, Topic) = (@Title, @Author, @Country, @Link, @Language, @Pages, @Year, @Category, @ImageLink, @LendTime, @LendType, @Run, @Audience, @Topic) WHERE ProductId = @id";
command.Parameters.Add(new SqliteParameter("@Title", book.Title));
command.Parameters.Add(new SqliteParameter("@Category", book.Category));
command.Parameters.Add(new SqliteParameter("@LendTime", book.LendTime));
command.Parameters.Add(new SqliteParameter("@LendType", book.LendType));
if (book.GetType() == typeof(Book))
{
command.Parameters.Add(new SqliteParameter("@Author", ((BookPost)book).Author));
command.Parameters.Add(new SqliteParameter("@Country", ((BookPost)book).Country));
command.Parameters.Add(new SqliteParameter("@Link", ((BookPost)book).Link));
command.Parameters.Add(new SqliteParameter("@Language", ((BookPost)book).Language));
command.Parameters.Add(new SqliteParameter("@Pages", ((BookPost)book).Pages));
command.Parameters.Add(new SqliteParameter("@Year", ((BookPost)book).Year));
command.Parameters.Add(new SqliteParameter("@ImageLink", ((BookPost)book).ImageLink));
command.Parameters.Add(new SqliteParameter("@Run", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Audience", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Topic", DBNull.Value));
}
else
{
command.Parameters.Add(new SqliteParameter("@Author", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Country", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Link", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Language", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Pages", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Year", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@ImageLink", DBNull.Value));
command.Parameters.Add(new SqliteParameter("@Run", ((MagazinPost)book).Run));
command.Parameters.Add(new SqliteParameter("@Audience", ((MagazinPost)book).Audience));
command.Parameters.Add(new SqliteParameter("@Topic", ((MagazinPost)book).Topic));
}
command.ExecuteNonQuery();
return id;
}
}
}
}

View file

@ -1,30 +1,13 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace BuecherwurmAPI.Models
{
public class Lend
{
[Key, Required]
public long Id { get; set; }
[Required]
public long ItemId { get; set;}
[Required]
public DateTime ReturnDate { get; set; }
[Required]
public string Customer { get; set; }
[Required]
public bool Returned { get; set; }
}
public class LendPost
{
public long ItemId {get; set;}
public DateTime ReturnDate {get; set;}
public string Customer {get; set;}
public bool Returned { get; set; }
}
}
}

View file

@ -1,8 +0,0 @@
namespace BuecherwurmAPI
{
public enum LendTypeEnum
{
Physical,
Virtual
}
}

View file

@ -1,36 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace BuecherwurmAPI.Models
{
public class Magazin : IProduct
{
public long ProductId {get; set;}
public CategoryEnum Category {get; set;}
public long LendTime {get; set;}
public string Title {get; set;}
public long Run {get; set;}
public string Audience {get; set;}
public string Topic {get; set;}
public LendTypeEnum LendType {get; set;}
}
public class MagazinPost : IProductPost
{
public CategoryEnum Category {get; set;}
public long LendTime {get; set;}
public string Title {get; set;}
public string Run {get; set;}
public string Audience {get; set;}
public string Topic {get; set;}
public LendTypeEnum LendType {get; set;}
public MagazinPost()
{
LendType = LendTypeEnum.Physical;
LendTime = 2;
Category = CategoryEnum.Magazine;
}
}
}

View file

@ -1,4 +1,5 @@
using AutoMapper;
using BuecherwurmAPI.DTOs;
using BuecherwurmAPI.Models;
namespace BuecherwurmAPI.Profiles
@ -7,7 +8,7 @@ namespace BuecherwurmAPI.Profiles
{
public LendProfile()
{
CreateMap<Lend, LendPost>();
CreateMap<Lend, LendReadDTO>();
}
}
}

View file

@ -1,89 +1,26 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Data.Sqlite;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace BuecherwurmAPI
{
public class Program
{
public static void Main(string[] args)
{
if (!File.Exists("LongWormMemory.db"))
{
CreateNewEmptyDB();
MakeImports();
}
CreateHostBuilder(args).Build().Run();
}
private static void MakeImports()
{
var booksJson = File.ReadAllText("books.json");
//var magazinesJson = File.ReadAllText("magazines.json");
var catalogue = new Models.KatalogModel();
var items = new Models.ItemModel();
var config = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var importedBooks = JsonSerializer.Deserialize<List<Models.BookPost>>(booksJson, config);
//var importedMags = JsonSerializer.Deserialize<List<Models.BookPost>>(magazinesJson);
List<Models.IProductPost> imports = new List<Models.IProductPost>();
imports.AddRange(importedBooks);
foreach (var item in importedBooks)
{
item.LendType = LendTypeEnum.Virtual;
item.Category = Models.CategoryEnum.EBook;
imports.Add(item);
}
//imports.AddRange(importedMags);
foreach (var item in imports)
{
var id = catalogue.AddProduct(item);
items.NewItem(new Models.ItemPost{ BookId = (int)id});
if (item.LendType != LendTypeEnum.Virtual)
{
items.NewItem(new Models.ItemPost{ BookId = (int)id});
}
}
}
private static void CreateNewEmptyDB()
{
//File.Create("LongWormMemory.db");
File.WriteAllText("LongWormMemory.db", "");
var connectionBuilder = new SqliteConnectionStringBuilder {DataSource = "LongWormMemory.db"};
var connection = new SqliteConnection(connectionBuilder.ConnectionString);
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = "CREATE TABLE Lends (Id INTEGER NOT NULL PRIMARY KEY, ItemId INTEGER NOT NULL, ReturnDate TEXT NOT NULL, Customer TEXT NOT NULL, Returned INTEGER NOT NULL)";
command.ExecuteNonQuery();
command.CommandText = "CREATE TABLE Items (ItemId INTEGER NOT NULL PRIMARY KEY, BookId INTEGER NOT NULL)";
command.ExecuteNonQuery();
command.CommandText = "CREATE TABLE Products (ProductId INTEGER PRIMARY KEY, Title TEXT, Author TEXT, Country TEXT, Link TEXT, Language TEXT, Pages INTEGER, Year INTEGER, Category INTEGER, ImageLink TEXT, LendTime INTEGER, LendType INTEGER, Run INTEGER, Audience TEXT, Topic TEXT)";
command.ExecuteNonQuery();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace BuecherwurmAPI
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using BuecherwurmAPI.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
@ -11,7 +12,6 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using BuecherwurmAPI.Models;
namespace BuecherwurmAPI
{
@ -32,9 +32,7 @@ namespace BuecherwurmAPI
// Adds a service that is created once per connection.
// It takes an interface and a specific implementation.
// That allows to swap the implementation easily.
services.AddScoped<ILend, LendModel>();
services.AddScoped<IItem, ItemModel>();
services.AddScoped<ICatalogue, KatalogModel>();
services.AddScoped<IRepository, Repository>();
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
}
@ -59,4 +57,4 @@ namespace BuecherwurmAPI
});
}
}
}
}

1002
books.json

File diff suppressed because it is too large Load diff

View file

@ -1,802 +0,0 @@
[
{
"Rang": 1,
"Titel": "ADAC Motorwelt",
"Auflage": "13.705.032",
"Gruppe": "Publikum",
"Sachgruppe": "Motorpresse",
"Verlag / Herausgeber": "ADAC"
},
{
"Rang": 2,
"Titel": "Apotheken-Umschau",
"Auflage": "9.616.642",
"Gruppe": "Kunden",
"Sachgruppe": "Apotheken/Medizin/Gesundheit",
"Verlag / Herausgeber": "Wort & Bild Verlag"
},
{
"Rang": 3,
"Titel": "Bleibgesund",
"Auflage": "6.423.491",
"Gruppe": "Kunden",
"Sachgruppe": "Medizin/Gesundheit",
"Verlag / Herausgeber": "wdv-Gruppe"
},
{
"Rang": 4,
"Titel": "bleibgesund 60",
"Auflage": "3.192.922",
"Gruppe": "Kunden",
"Sachgruppe": "Medizin/Gesundheit",
"Verlag / Herausgeber": "wdv-Gruppe"
},
{
"Rang": 5,
"Titel": "tv14",
"Auflage": "2.389.661",
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Bauer Media Group"
},
{
"Rang": 6,
"Titel": "metallzeitung",
"Auflage": "2.227.205",
"Gruppe": "Publikum",
"Sachgruppe": "Aktuelle Zeitschriften und Magazine",
"Verlag / Herausgeber": "IG Metall"
},
{
"Rang": 7,
"Titel": "ver.di PUBLIK",
"Auflage": "1.899.122",
"Gruppe": "Publikum",
"Sachgruppe": "Sonstige Zeitschriften National",
"Verlag / Herausgeber": "ver.di"
},
{
"Rang": 8,
"Titel": "TV Digital",
"Auflage": "1.771.022",
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Funke Mediengruppe"
},
{
"Rang": 9,
"Titel": "Ratgeber/Meine Apotheke",
"Auflage": "1.728.602",
"Gruppe": "Kunden",
"Sachgruppe": "Apotheken/Medizin/Gesundheit",
"Verlag / Herausgeber": "Gebr. Storck GmbH & Co. Verlags-oHG"
},
{
"Rang": 10,
"Titel": "Senioren Ratgeber",
"Auflage": "1.727.317",
"Gruppe": "Kunden",
"Sachgruppe": "Apotheken/Medizin/Gesundheit",
"Verlag / Herausgeber": "Wort & Bild Verlag"
},
{
"Rang": 11,
"Titel": "Mit Liebe - Das Genussmagazin",
"Auflage": "1.668.550",
"Gruppe": "Kunden",
"Sachgruppe": "Lebensmittel/Kochen/Haushalt",
"Verlag / Herausgeber": "EDEKA Verlagsgesellschaft mbH"
},
{
"Rang": 12,
"Titel": "Das Haus",
"Auflage": "1.598.049",
"Gruppe": "Publikum",
"Sachgruppe": "Wohn- und Gartenzeitschriften",
"Verlag / Herausgeber": "Hubert Burda Media"
},
{
"Rang": 13,
"Titel": "Mein Eigenheim, Wohnen & Leben",
"Auflage": "1.586.533",
"Gruppe": "Publikum",
"Sachgruppe": "Wohn- und Gartenzeitschriften",
"Verlag / Herausgeber": "J.Fink Verlag GmbH & Co. KG"
},
{
"Rang": 14,
"Titel": "VdK-Zeitung",
"Auflage": "1.559.980",
"Gruppe": "Publikum",
"Sachgruppe": "Aktuelle Zeitschriften und Magazine",
"Verlag / Herausgeber": "Sozialverband VdK Deutschland"
},
{
"Rang": 15,
"Titel": "medizini",
"Auflage": "1.491.475",
"Gruppe": "Kunden",
"Sachgruppe": "Apotheken/Medizin/Gesundheit",
"Verlag / Herausgeber": "Wort & Bild Verlag"
},
{
"Rang": 16,
"Titel": "Wohnglück",
"Auflage": "1.404.263",
"Gruppe": "Publikum",
"Sachgruppe": "Wohn- und Gartenzeitschriften",
"Verlag / Herausgeber": "BELLEVUE AND MORE GmbH"
},
{
"Rang": 17,
"Titel": "Diabetes Ratgeber",
"Auflage": "1.200.450",
"Gruppe": "Kunden",
"Sachgruppe": "Apotheken/Medizin/Gesundheit",
"Verlag / Herausgeber": "Wort & Bild Verlag"
},
{
"Rang": 18,
"Titel": "TV Direkt",
"Auflage": "1.185.933",
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Funke Mediengruppe"
},
{
"Rang": 19,
"Titel": "TV-Movie",
"Auflage": "1.166.838",
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Bauer Media Group"
},
{
"Rang": 20,
"Titel": "Hörzu",
"Auflage": "1.125.985",
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Funke Mediengruppe"
},
{
"Rang": 21,
"Titel": "vigo Gesundheit - Das Kundenmagazin",
"Auflage": "1.121.050",
"Gruppe": "Kunden",
"Sachgruppe": "Medizin/Gesundheit",
"Verlag / Herausgeber": "wdv-Gruppe"
},
{
"Rang": 22,
"Titel": "Johanniter",
"Auflage": "1.106.507",
"Gruppe": "Publikum",
"Sachgruppe": "Gesundheitsmagazine",
"Verlag / Herausgeber": "Die Johanniter"
},
{
"Rang": 23,
"Titel": "ASB Magazin",
"Auflage": "1.104.904",
"Gruppe": "Publikum",
"Sachgruppe": "Gesundheitsmagazine",
"Verlag / Herausgeber": "Arbeiter-Samariter-Bund Deutschland"
},
{
"Rang": 24,
"Titel": "Wohnen - Das Magazin für Bauen, Einrichten & Lebensart",
"Auflage": "1.056.140",
"Gruppe": "Publikum",
"Sachgruppe": "Wohn- und Gartenzeitschriften",
"Verlag / Herausgeber": "HMC Verlag Hamburg Media Company GmbH"
},
{
"Rang": 25,
"Titel": "Landlust Die schönsten Seiten des Landlebens",
"Auflage": "1.040.119",
"Gruppe": "Publikum",
"Sachgruppe": "Wohn- und Gartenzeitschriften",
"Verlag / Herausgeber": "Landwirtschaftsverlag Münster"
},
{
"Rang": 26,
"Titel": "on job",
"Auflage": "1.009.720",
"Gruppe": "Kunden",
"Sachgruppe": "Medizin/Gesundheit",
"Verlag / Herausgeber": "wdv-Gruppe"
},
{
"Rang": 27,
"Titel": "Neue Apotheken Illustrierte",
"Auflage": "1.007.370",
"Gruppe": "Kunden",
"Sachgruppe": "Apotheken/Medizin/Gesundheit",
"Verlag / Herausgeber": "Bundesvereinigung Deutscher Apothekerverbände"
},
{
"Rang": 28,
"Titel": "TV Spielfilm",
"Auflage": 934.291,
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Hubert Burda Media"
},
{
"Rang": 29,
"Titel": "Auf einen Blick",
"Auflage": 921.049,
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Bauer Media Group"
},
{
"Rang": 30,
"Titel": "Schrot & Korn Naturkostmagazin",
"Auflage": 888.063,
"Gruppe": "Kunden",
"Sachgruppe": "Lebensmittel",
"Verlag / Herausgeber": "Bio Verlag GmbH"
},
{
"Rang": 31,
"Titel": "Der Spiegel",
"Auflage": 843.085,
"Gruppe": "Publikum",
"Sachgruppe": "Aktuelle Zeitschriften und Magazine",
"Verlag / Herausgeber": "SPIEGEL-Verlag"
},
{
"Rang": 32,
"Titel": "Bild der Frau",
"Auflage": 832.226,
"Gruppe": "Publikum",
"Sachgruppe": "Wöchentliche Frauenzeitschriften",
"Verlag / Herausgeber": "Funke Mediengruppe"
},
{
"Rang": 33,
"Titel": "extra / tour",
"Auflage": 774.431,
"Gruppe": "Publikum",
"Sachgruppe": "Reisezeitschriften",
"Verlag / Herausgeber": "Deutsches Jugendherbergswerk"
},
{
"Rang": 34,
"Titel": "Freizeit Revue",
"Auflage": 764.162,
"Gruppe": "Publikum",
"Sachgruppe": "Wöchentliche Frauenzeitschriften",
"Verlag / Herausgeber": "Hubert Burda Media"
},
{
"Rang": 35,
"Titel": "Baby und Familie",
"Auflage": 749.425,
"Gruppe": "Kunden",
"Sachgruppe": "Apotheken/Medizin/Gesundheit",
"Verlag / Herausgeber": "Wort & Bild Verlag"
},
{
"Rang": 36,
"Titel": "KONPRESS",
"Auflage": 731.664,
"Gruppe": "Publikum",
"Sachgruppe": "Konfessionelle Zeitschriften",
"Verlag / Herausgeber": "KONPRESS-Medien eG"
},
{
"Rang": 37,
"Titel": "Stern",
"Auflage": 725.959,
"Gruppe": "Publikum",
"Sachgruppe": "Aktuelle Zeitschriften und Magazine",
"Verlag / Herausgeber": "Gruner + Jahr"
},
{
"Rang": 38,
"Titel": "JUNIOR Kinderzeitschriften",
"Auflage": 679.795,
"Gruppe": "Kunden",
"Sachgruppe": "Apotheken/Medizin/Gesundheit",
"Verlag / Herausgeber": ""
},
{
"Rang": 39,
"Titel": "on",
"Auflage": 654.628,
"Gruppe": "Kunden",
"Sachgruppe": "Medizin/Gesundheit",
"Verlag / Herausgeber": "wdv-Gruppe"
},
{
"Rang": 40,
"Titel": "TV Hören und Sehen",
"Auflage": 653.399,
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Bauer Media Group"
},
{
"Rang": 41,
"Titel": "MieterZeitung",
"Auflage": 643.231,
"Gruppe": "Kunden",
"Sachgruppe": "Sonstige",
"Verlag / Herausgeber": "Deutscher Mieterbund"
},
{
"Rang": 42,
"Titel": "Kompakt",
"Auflage": 639.69,
"Gruppe": "Publikum",
"Sachgruppe": "Sonstige Zeitschriften National",
"Verlag / Herausgeber": "IG Bergbau, Chemie, Energie"
},
{
"Rang": 43,
"Titel": "DAV Panorama",
"Auflage": 638.493,
"Gruppe": "Publikum",
"Sachgruppe": "Sportzeitschriften",
"Verlag / Herausgeber": "Deutscher Alpenverein"
},
{
"Rang": 44,
"Titel": "NurTV",
"Auflage": 618.623,
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Funke Mediengruppe"
},
{
"Rang": 45,
"Titel": "Neue Post",
"Auflage": 613.572,
"Gruppe": "Publikum",
"Sachgruppe": "Wöchentliche Frauenzeitschriften",
"Verlag / Herausgeber": "Bauer Media Group"
},
{
"Rang": 46,
"Titel": "ACE-Lenkrad",
"Auflage": 580.877,
"Gruppe": "Publikum",
"Sachgruppe": "Motorpresse",
"Verlag / Herausgeber": "Auto Club Europa"
},
{
"Rang": 47,
"Titel": "Der Vermögensberater",
"Auflage": 564.27,
"Gruppe": "Publikum",
"Sachgruppe": "Wirtschaftspresse",
"Verlag / Herausgeber": "Deutsche Vermögensberatung"
},
{
"Rang": 48,
"Titel": "tv pur",
"Auflage": 561.959,
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Bauer Media Group"
},
{
"Rang": 49,
"Titel": "DBB-Magazin",
"Auflage": 542.491,
"Gruppe": "Fach",
"Sachgruppe": "Recht und Verwaltung",
"Verlag / Herausgeber": "dbb beamtenbund und tarifunion"
},
{
"Rang": 50,
"Titel": "Fondsmagazin",
"Auflage": 538.389,
"Gruppe": "Kunden",
"Sachgruppe": "Finanzdienstleistungen",
"Verlag / Herausgeber": ""
},
{
"Rang": 51,
"Titel": "Brigitte",
"Auflage": 533.661,
"Gruppe": "Publikum",
"Sachgruppe": "14-tägliche Frauenzeitschriften",
"Verlag / Herausgeber": "Gruner + Jahr"
},
{
"Rang": 52,
"Titel": "rotkreuzmagazin für Mitglieder, Freunde und",
"Auflage": 531.254,
"Gruppe": "Publikum",
"Sachgruppe": "Gesundheitsmagazine",
"Verlag / Herausgeber": ""
},
{
"Rang": 53,
"Titel": "Bunte",
"Auflage": 519.57,
"Gruppe": "Publikum",
"Sachgruppe": "Aktuelle Zeitschriften und Magazine",
"Verlag / Herausgeber": "Hubert Burda Media"
},
{
"Rang": 54,
"Titel": "Focus",
"Auflage": 508.489,
"Gruppe": "Publikum",
"Sachgruppe": "Aktuelle Zeitschriften und Magazine",
"Verlag / Herausgeber": "Hubert Burda Media"
},
{
"Rang": 55,
"Titel": "HausArzt - PatientenMagazin",
"Auflage": 479.45,
"Gruppe": "Kunden",
"Sachgruppe": "Apotheken/Medizin/Gesundheit",
"Verlag / Herausgeber": "Wort & Bild Verlag"
},
{
"Rang": 56,
"Titel": "Frau und Mutter",
"Auflage": 474.649,
"Gruppe": "Publikum",
"Sachgruppe": "Monatliche Frauenzeitschriften",
"Verlag / Herausgeber": "Katholische Frauengemeinschaft Deutschlands"
},
{
"Rang": 57,
"Titel": "Auto Bild",
"Auflage": 461.539,
"Gruppe": "Publikum",
"Sachgruppe": "Motorpresse",
"Verlag / Herausgeber": "Axel Springer"
},
{
"Rang": 58,
"Titel": "mkv Apotheken-Kombi TV Gesund & Leben, LindaMagazin",
"Auflage": 458.807,
"Gruppe": "Kunden",
"Sachgruppe": "Apotheken/Medizin/Gesundheit",
"Verlag / Herausgeber": "mkv medienkontor Verlagsgesellschaft mbH & Co. KG"
},
{
"Rang": 59,
"Titel": "Funk Uhr",
"Auflage": 453.55,
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Axel Springer"
},
{
"Rang": 60,
"Titel": "eve Magazin",
"Auflage": 441.139,
"Gruppe": "Kunden",
"Sachgruppe": "Lebensmittel",
"Verlag / Herausgeber": "TERRITORY CTR GmbH"
},
{
"Rang": 61,
"Titel": "Das Neue Blatt",
"Auflage": 433.918,
"Gruppe": "Publikum",
"Sachgruppe": "Wöchentliche Frauenzeitschriften",
"Verlag / Herausgeber": "Bauer Media Group"
},
{
"Rang": 62,
"Titel": "Freizeitwoche",
"Auflage": 427.633,
"Gruppe": "Publikum",
"Sachgruppe": "Wöchentliche Frauenzeitschriften",
"Verlag / Herausgeber": "Bauer Media Group"
},
{
"Rang": 63,
"Titel": "vigo GESUNDHEIT 65",
"Auflage": 425.688,
"Gruppe": "Kunden",
"Sachgruppe": "Medizin/Gesundheit",
"Verlag / Herausgeber": ""
},
{
"Rang": 64,
"Titel": "SoVD Zeitung - Soziales im Blick",
"Auflage": 410.809,
"Gruppe": "Fach",
"Sachgruppe": "Sonstige",
"Verlag / Herausgeber": ""
},
{
"Rang": 65,
"Titel": "Tina",
"Auflage": 403.493,
"Gruppe": "Publikum",
"Sachgruppe": "Wöchentliche Frauenzeitschriften",
"Verlag / Herausgeber": "Bauer Media Group"
},
{
"Rang": 66,
"Titel": "Reader´s Digest Das Beste",
"Auflage": 401.698,
"Gruppe": "Publikum",
"Sachgruppe": "Aktuelle Zeitschriften und Magazine",
"Verlag / Herausgeber": "Readers Digest Association"
},
{
"Rang": 67,
"Titel": "Vorwärts",
"Auflage": 394.892,
"Gruppe": "Publikum",
"Sachgruppe": "Sonstige Zeitschriften National",
"Verlag / Herausgeber": "Sozialdemokratische Partei Deutschlands"
},
{
"Rang": 68,
"Titel": "Meine Familie & ich",
"Auflage": 390.339,
"Gruppe": "Publikum",
"Sachgruppe": "Esszeitschriften",
"Verlag / Herausgeber": ""
},
{
"Rang": 69,
"Titel": "Fernsehwoche",
"Auflage": 388.28,
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Bauer Media Group"
},
{
"Rang": 70,
"Titel": "Die Aktuelle",
"Auflage": 369.428,
"Gruppe": "Publikum",
"Sachgruppe": "Wöchentliche Frauenzeitschriften",
"Verlag / Herausgeber": "FUNKE Women Group GmbH"
},
{
"Rang": 71,
"Titel": "Freundin",
"Auflage": 366.039,
"Gruppe": "Publikum",
"Sachgruppe": "14-tägliche Frauenzeitschriften",
"Verlag / Herausgeber": "Hubert Burda Media"
},
{
"Rang": 72,
"Titel": "Sport Bild",
"Auflage": 357.91,
"Gruppe": "Publikum",
"Sachgruppe": "Sportzeitschriften",
"Verlag / Herausgeber": "Axel Springer"
},
{
"Rang": 73,
"Titel": "Familienheim und Garten",
"Auflage": 357.712,
"Gruppe": "Fach",
"Sachgruppe": "Freizeit und Hobby",
"Verlag / Herausgeber": ""
},
{
"Rang": 74,
"Titel": "InStyle",
"Auflage": 357.418,
"Gruppe": "Publikum",
"Sachgruppe": "Monatliche Frauenzeitschriften",
"Verlag / Herausgeber": "Hubert Burda Media"
},
{
"Rang": 75,
"Titel": "Freizeit Spass",
"Auflage": 356.487,
"Gruppe": "Publikum",
"Sachgruppe": "Wöchentliche Frauenzeitschriften",
"Verlag / Herausgeber": "Hubert Burda Media"
},
{
"Rang": 76,
"Titel": "auto motor und sport",
"Auflage": 352.622,
"Gruppe": "Publikum",
"Sachgruppe": "Motorpresse",
"Verlag / Herausgeber": "Motor Presse Stuttgart"
},
{
"Rang": 77,
"Titel": "Deutsches Ärzteblatt",
"Auflage": 351.982,
"Gruppe": "Fach",
"Sachgruppe": "Medizin und Gesundheitswesen",
"Verlag / Herausgeber": "Deutscher Ärzte-Verlag"
},
{
"Rang": 78,
"Titel": "Laviva",
"Auflage": 335.934,
"Gruppe": "Publikum",
"Sachgruppe": "Monatliche Frauenzeitschriften",
"Verlag / Herausgeber": "Axel Springer Vertriebsservice GmbH"
},
{
"Rang": 79,
"Titel": "mein schönes Land",
"Auflage": 335.33,
"Gruppe": "Publikum",
"Sachgruppe": "Wohn- und Gartenzeitschriften",
"Verlag / Herausgeber": ""
},
{
"Rang": 80,
"Titel": "Computer Bild",
"Auflage": 334.72,
"Gruppe": "Publikum",
"Sachgruppe": "IT-/Telekommunikationszeitschriften",
"Verlag / Herausgeber": "Axel Springer"
},
{
"Rang": 81,
"Titel": "TV für mich",
"Auflage": 334.4,
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Gong Verlag"
},
{
"Rang": 82,
"Titel": "Lufthansa Magazin Exclusive",
"Auflage": 317.446,
"Gruppe": "Kunden",
"Sachgruppe": "Reisen/Verkehrsgesellschaften",
"Verlag / Herausgeber": ""
},
{
"Rang": 83,
"Titel": "Gala",
"Auflage": 315.745,
"Gruppe": "Publikum",
"Sachgruppe": "Aktuelle Zeitschriften und Magazine",
"Verlag / Herausgeber": "Gruner + Jahr"
},
{
"Rang": 84,
"Titel": "Glamour",
"Auflage": 314.832,
"Gruppe": "Publikum",
"Sachgruppe": "Monatliche Frauenzeitschriften",
"Verlag / Herausgeber": "Condé Nast Verlag"
},
{
"Rang": 85,
"Titel": "SUPERillu",
"Auflage": 314.807,
"Gruppe": "Publikum",
"Sachgruppe": "Aktuelle Zeitschriften und Magazine",
"Verlag / Herausgeber": "Hubert Burda Media"
},
{
"Rang": 86,
"Titel": "Gartenfreund/Siedlung und Eigenheim",
"Auflage": 314.601,
"Gruppe": "Publikum",
"Sachgruppe": "Wohn- und Gartenzeitschriften",
"Verlag / Herausgeber": ""
},
{
"Rang": 87,
"Titel": "Naturschutz heute",
"Auflage": 313.871,
"Gruppe": "Publikum",
"Sachgruppe": "Naturzeitschriften",
"Verlag / Herausgeber": "NABU Media-Agentur"
},
{
"Rang": 88,
"Titel": "Für Sie",
"Auflage": 307.31,
"Gruppe": "Publikum",
"Sachgruppe": "14-tägliche Frauenzeitschriften",
"Verlag / Herausgeber": "Jahreszeiten Verlag"
},
{
"Rang": 89,
"Titel": "Deutsches Ärzteblatt Kombi Praxis/Klinik",
"Auflage": 297.952,
"Gruppe": "Fach",
"Sachgruppe": "Medizin und Gesundheitswesen",
"Verlag / Herausgeber": ""
},
{
"Rang": 90,
"Titel": "Mein schöner Garten",
"Auflage": 297.636,
"Gruppe": "Publikum",
"Sachgruppe": "Wohn- und Gartenzeitschriften",
"Verlag / Herausgeber": "Hubert Burda Media"
},
{
"Rang": 91,
"Titel": "TV Today",
"Auflage": 287.221,
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": "Hubert Burda Media"
},
{
"Rang": 92,
"Titel": "on uni",
"Auflage": 279.705,
"Gruppe": "Kunden",
"Sachgruppe": "Medizin/Gesundheit",
"Verlag / Herausgeber": "wdv-Gruppe"
},
{
"Rang": 93,
"Titel": "Cosmopolitan",
"Auflage": 276.314,
"Gruppe": "Publikum",
"Sachgruppe": "Monatliche Frauenzeitschriften",
"Verlag / Herausgeber": "Bauer Media Group"
},
{
"Rang": 94,
"Titel": "Land IDEE",
"Auflage": 272.838,
"Gruppe": "Publikum",
"Sachgruppe": "Wohn- und Gartenzeitschriften",
"Verlag / Herausgeber": "Funke Mediengruppe"
},
{
"Rang": 95,
"Titel": "Frau im Trend",
"Auflage": 272.295,
"Gruppe": "Publikum",
"Sachgruppe": "Wöchentliche Frauenzeitschriften",
"Verlag / Herausgeber": "Hubert Burda Media"
},
{
"Rang": 96,
"Titel": "c't magazin für computertechnik",
"Auflage": 270.517,
"Gruppe": "Publikum",
"Sachgruppe": "IT-/Telekommunikationszeitschriften",
"Verlag / Herausgeber": "Heise Zeitschriften Verlag"
},
{
"Rang": 97,
"Titel": "kinder!",
"Auflage": 269.841,
"Gruppe": "Publikum",
"Sachgruppe": "Elternzeitschriften",
"Verlag / Herausgeber": "Junior-Verlag GmbH & Co. KG (Hamburg)"
},
{
"Rang": 98,
"Titel": "TV piccolino plus + (TV piccolino+TV Genie+My TV)",
"Auflage": 266.345,
"Gruppe": "Publikum",
"Sachgruppe": "Programmzeitschriften",
"Verlag / Herausgeber": ""
},
{
"Rang": 99,
"Titel": "Erziehung und Wissenschaft",
"Auflage": 263.359,
"Gruppe": "Fach",
"Sachgruppe": "Erziehung und Bildung",
"Verlag / Herausgeber": "STAMM Verlag GmbH"
},
{
"Rang": 100,
"Titel": "ACV Profil",
"Auflage": 257.7,
"Gruppe": "Publikum",
"Sachgruppe": "Motorpresse",
"Verlag / Herausgeber": ""
}
]